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

[bug] GNUInstallDirs seem to be overridden by CMakeToolchain-generated files #17802

Open
glennaycock opened this issue Feb 18, 2025 · 4 comments
Assignees

Comments

@glennaycock
Copy link

glennaycock commented Feb 18, 2025

Describe the bug

We are experiencing a CMake installer issue while migrating our project to Conan 2.x on Linux. The existing CMake project works as expected with 1.x recipes and dependencies using generated conan_paths.cmake.

Using CMake 3.31.4 with Conan 2.12.2

However, on RHEL/Alma 8, the introduction of CMakeDeps and CMakeToolchain in 2.x results in the GNUInstallDirs variables being overridden with incorrect values in conan_toolchain.cmake:

set(CMAKE_INSTALL_BINDIR "bin")
set(CMAKE_INSTALL_SBINDIR "bin")
set(CMAKE_INSTALL_LIBEXECDIR "bin")
set(CMAKE_INSTALL_LIBDIR "lib")
set(CMAKE_INSTALL_INCLUDEDIR "include")
set(CMAKE_INSTALL_OLDINCLUDEDIR "include")

CMAKE_INSTALL_LIBDIR gets set to 'lib' instead of 'lib64' and CMAKE_INSTALL_SBINDIR gets set to 'bin' instead of 'sbin'.

This is documented in CMakeToolchain under output_dirs.

We tried the tools.cmake.cmaketoolchain:extra_variables workaround suggested in #16829, but the result seems to be the same. Also, I would rather not arbitrarily replace the values generated by GNUInstallDirs because then we also have to incorporate that change into the developer environment, possibly for multiple platforms.

Is it possible to use ONLY the defaults generated by GNUInstallDirs? How to prevent this override?

Referencing existing issues:
#14733
#16829

How to reproduce it

No response

@glennaycock
Copy link
Author

We were able to override by setting the toolchain variables to the desired values, but I would still rather not override GNUInstallDirs.

@memsharded memsharded self-assigned this Feb 19, 2025
@memsharded
Copy link
Member

Hi @glennaycock

Thanks for your feedback.

We tried the tools.cmake.cmaketoolchain:extra_variables workaround suggested in #16829, but the result seems to be the same. Also, I would rather not arbitrarily replace the values generated by GNUInstallDirs because then we also have to incorporate that change into the developer environment, possibly for multiple platforms.

Is it possible to use ONLY the defaults generated by GNUInstallDirs? How to prevent this override?

This was very necessary, because the problem with GNUInstallDirs defines different directories even for different distros.
So consider the standard Conan recipe with:

def package(self):
     cmake = CMake(self)
     cmake.install()

def layout(self):
     self.cpp.package.libdirs = ["lib"]  # this is the default
    ...

Then, that recipe will be broken because in some systems the libdir will not be "lib" but "lib64". This was creating a multitude of unexpected issues in many Conan recipes, both public in ConanCenter, but also affecting proprietary recipes.

And the worst thing is that the logic to know that is not that straightforward, it would require something like

def layout(self):
     if (we are in one of those distros (list of all distros?) that create lib64):
          self.cpp.package.libdirs = ["lib64"]
     else:
          self.cpp.package.libdirs = ["lib"]  # this is the default
    ...

Is it possible to use ONLY the defaults generated by GNUInstallDirs? How to prevent this override?

Yes, if you define the self.cpp.package.libdirs = ["lib64"], then lib64 will be the value used for CMAKE_INSTALL_LIBDIR. But as commented above, the condition to apply is not that evident.

You could disable the OutputDirsBlock completely in CMakeToolchain, see https://docs.conan.io/2/reference/tools/cmake/cmaketoolchain.html#customizing-the-content-blocks, with something like tc.blocks.remove("output_dirs"). But then, be aware that if you disable it, still the correct layout() or package_info() definition of libdirs is necessary.

What is exactly your use case? You want to keep the lib64 folder because you are working in a consumer-only recipe and want to cmake --install into the system? It is not very clear what you mean with:

Also, I would rather not arbitrarily replace the values generated by GNUInstallDirs because then we also have to incorporate that change into the developer environment, possibly for multiple platforms.

Generally, for Conan packages this is not a concern, Conan automatically manages these things, that is one of the purposes of Conan, it abstract away the location of the dependencies.

@glennaycock
Copy link
Author

Thanks for the detailed response!

Our use case is an internal, consumer-only recipe, which we only use to download and configure the dependencies for our build. We use cmake --install for our (traditional) packaging and deployment.

@memsharded
Copy link
Member

Our use case is an internal, consumer-only recipe, which we only use to download and configure the dependencies for our build. We use cmake --install for our (traditional) packaging and deployment.

Then, for a consumer-only recipe, I think that the tc.blocks.remove("output_dirs") in the generate() method would be what you are looking for, and that will avoid the toolchain definition of the install dirs.

Thanks to you for the feedback!

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

No branches or pull requests

2 participants