Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmake: use multiple outputs for GNUInstallDirs #52859

Merged
merged 1 commit into from Jul 25, 2019

Conversation

jtojnar
Copy link
Contributor

@jtojnar jtojnar commented Dec 25, 2018

Motivation for this change

CMake contains a module for more granular installation directories. Let’s set the paths so that projects using the module (e.g. #52856) can be more easily split into multiple outputs.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@jtojnar jtojnar changed the base branch from master to staging December 25, 2018 19:42
CMake contains a module for more granular installation directories:

https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html

Let’s set the paths so that projects using the module can be more
easily split into multiple outputs.
@orivej
Copy link
Contributor

orivej commented Dec 25, 2018

Thank you! This looks good, except that LIBEXECDIR seems to belong to the bin output.

This will generate even more warnings like the following for projects that do not use GNUInstallDirs:

CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_INSTALL_INCLUDEDIR
    CMAKE_INSTALL_LIBDIR

This can be avoided by writing a file with

SET(CMAKE_INSTALL_MANDIR "/path/to/lib" CACHE PATH "")

and running cmake with -C that/file.

@jtojnar
Copy link
Contributor Author

jtojnar commented Dec 25, 2018

I followed the directories in

--libdir=${!outputLib}/lib --libexecdir=${!outputLib}/libexec \
. Should we change it there?

As for the warning, I think it might be useful to retain it. If we want to do something about it, I would prefer patching CMake to show a single warning, something like “Manually-specified variables CMAKE_INSTALL_* flags are commonly registered by GNUInstallDirs module but the project does not include it.” and try to push it upstream.

@orivej
Copy link
Contributor

orivej commented Dec 25, 2018

Should we change it there?

I guess so, since libexec is for binaries which are likely to depend on libraries, while libraries may not depend on the binaries; but @vcunat has moved libexec from bin to lib in 3ec413c seemingly intentionally.

As for the warning, I think it might be useful to retain it.

Why? So far it has been only distracting. With more variables we will turn blind to it.

@jtojnar
Copy link
Contributor Author

jtojnar commented Dec 25, 2018

I guess so, since libexec is for binaries which are likely to depend on libraries, while libraries may not depend on the binaries

I think udisks is an example of a library that depends on a daemon from libexec. libinput is another one that comes to mind, though there it might make sense to split it to yet another output (service, or daemon like dbus has).

Why? So far it has been only distracting. With more variables we will turn blind to it.

It can serve as a reminder to pester upstream about it.

@orivej
Copy link
Contributor

orivej commented Dec 26, 2018

OK, perhaps libexec should be left with lib.

It can serve as a reminder to pester upstream about it.

These warnings can hardly serve that purpose: before this discussion I had no idea that CMAKE_INSTALL_LIBDIR might indicate an omission upstream rather than, say, the fact that a package does not install libraries.

@orivej
Copy link
Contributor

orivej commented Dec 26, 2018

I have looked at google-gflags to check whether it would be appropriate to ask upstream to use GNUInstallDirs (maybe a bit, but I won't ask) and noticed that it generates more warnings:

CMake Warning:
  Manually-specified variables were not used by the project:

    CMAKE_C_COMPILER
    CMAKE_INSTALL_INCLUDEDIR
    CMAKE_INSTALL_LIBDIR
    CMAKE_POLICY_DEFAULT_CMP0025

The first is because it is a C++-only project.

@orivej
Copy link
Contributor

orivej commented Dec 26, 2018

Such warnings make it difficult to notice cmake flags in specific .nix files that need updating (and that should rather be treated as errors).

Copy link
Member

@matthewbauer matthewbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! It looks like CMake is getting quite a lot of flags though. Would it make sense to put these in pkgs/build-support/setup-hooks/multiple-outputs.sh instead? It's a little bit confusing where the right place to include these kinds of things is & okay to leave here for now.

@jtojnar
Copy link
Contributor Author

jtojnar commented Dec 27, 2018

I mainly chose to put it here as meson does the same in its own setup hook. Also, with more and more build systems, multiple-outputs would explode.

@matthewbauer
Copy link
Member

matthewbauer commented Dec 27, 2018

Yeah that makes sense. Perhaps we should make these conditional on $outputs != "out"?

@orivej
Copy link
Contributor

orivej commented Dec 28, 2018

Perhaps we should make these conditional on $outputs != "out"?

That's an interesting idea! For the purpose of preventing breakage of packages that expect these variables to contain relative paths, it might be even better to individually compare them to $out to avoid setting them even in some multiple output derivations:

if [ "${!outputBin}" != "$out" ]; then
    …-DCMAKE_INSTALL_BINDIR=…
    …-DCMAKE_INSTALL_SBINDIR=…
fi
if [ "${!outputInclude} != $out" ]; …

For the purpose of preventing useless CMake warnings, it is better to save them to a CMake cache file rather than to pass them on the command line.

@worldofpeace worldofpeace merged commit 883a1df into NixOS:staging Jul 25, 2019
@jtojnar jtojnar deleted the cmake-gid branch July 30, 2019 16:13
@jtojnar jtojnar mentioned this pull request Aug 5, 2019
@veprbl
Copy link
Member

veprbl commented Jan 3, 2020

Breakage in zoneminder: #76855

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/could-weve-implemented-multi-output-packages-better/6597/2

@jtojnar
Copy link
Contributor Author

jtojnar commented Jun 24, 2020

If you find this pull request and think this broke your package, please fix the project upstream as described in https://github.com/jtojnar/cmake-snips#assuming-cmake_install_dir-is-relative-path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants