conan icon indicating copy to clipboard operation
conan copied to clipboard

[feature] Add support for DESTDIR for the cmake tool

Open derived-coder opened this issue 2 years ago • 7 comments

Please add support for the cmake tool to execute the install command with the DESTDIR as a prefix. Similar to this https://github.com/conan-io/conan/issues/11264 but this was for autotools and we need the same for CMake now.

derived-coder avatar Jul 20 '22 08:07 derived-coder

Hi @derived-coder

Sorry, it is not clear what you mean. CMakeToolchain already has a block to define all CMAKE_INSTALL_PREFIX and family. You need to do a full report, specifying a full working conanfile.py, the current behavior, the desired behavior, etc.

memsharded avatar Jul 20 '22 08:07 memsharded

I would like to do this:

 def package(self):
    cmake = self._configure_cmake()
    cmake.install(args=[f"DESTDIR={self.package_folder}"])

Your colleague @czoido has implemented this already for AutoToolsBuildEnvironment (https://github.com/conan-io/conan/pull/11284) now it needs to be implemented for the CMake tool as well.

derived-coder avatar Jul 20 '22 09:07 derived-coder

Hi @derived-coder, I don't know if this is the same case, in the Autotools build helper case (note it's not AutoToolsBuildEnvironment) It was needed to make some packages relocatable as we could not know the destination package folder at the configure step. As @memsharded said, it's not clear why this would be needed in CMake.

czoido avatar Jul 20 '22 11:07 czoido

Hi @czoido

I am not sure, this request was about relocatable packages. For me it was about controlling the hard coded paths in the binary.

So you want my motivation for this? Take the dbus package in CCI:

conan install dbus/1.12.20@ -g virtualenv -g virtualrunenv
source activate.sh && source activate_run.sh
dbus-daemon --session --print-address --fork

Will result in following error at runtime:

dbus[419]: Failed to start message bus: Failed to open "/home/conan/w/prod/BuildSingleReference/.conan/data/dbus/1.12.20/_/_/package/fb2ae32c85d50c7776ed05b57cc10f2bc374880b/share/dbus-1/session.conf": No such file or directory

This paths comes from your CI environment.

My goal is that I create my own packages (package_id calculated with own settings), where I can control the paths which are hard coded in the binary. So I will be setting CMAKE_INSTALL_PREFIX=/usr and cmake.install(args=[f"DESTDIR={self.package_folder}"]) This will get me an application where it will look for resources in /usr/share/dbus-1/session.conf

The AutoToolsBuildEnvironment allows me to do this, however the cmake tool now. It doesn't take any args.

Does this answer your question?

derived-coder avatar Jul 20 '22 11:07 derived-coder

there are at least several things here.

  1. allow DESTDIR to be configurable. I believe it's completely impossible right now, as CMake.install method doesn't accept any custom args. that would be a logical if all our build helpers (at least Autotools/CMake/Meson) support the same mechanism (DESTDIR) and have feature parity - it's a natural thing.
  2. changing every recipe to pass DESTDIR is something that doesn't scale. I beliieve it should accept configuration from the outside (e.g. via conf), so we can do something like:
[install]
prefix = /usr/local # or /opt
destdir = %package_folder% # here you can use some placeholders like source/build/package folder and so on
  1. we know changing prefix to /usr/local results in build tree like:
%package_folder%/usr/local/include
%package_folder%/usr/local/lib

instead of just

%package_folder%/include
%package_folder%/lib

therefore, our default includedirs/libdirs wouldn't work out of the box if you tweak prefix/destdir. this will require adjustments in CppInfo and layout models to make it work smoothly.

so, the reality is that many packages are not relocatable out of the box. we know it happens (e.g. dbus) and we know it requires patching in the code. this doesn't scale, and these patches are pretty complex (see https://github.com/conan-io/conan-center-index/blob/master/recipes/bison/all/patches/0004-3.5.3-relocatable.patch), they have to be maintained (=rebased for new releases), writing them requires knowledge of library internals, and it makes conan package behavior divering from vanilla library (something user might not expect).

if you're doing some embeddedd stuff, you probably can do: A. compile some libraries with conan create B. make RPMs with some generator (or deployer in V2) C. install RPMs on the real embedded device to some known location (depends on distro, might be /usr/local, /opt or whatever)

we know on stage A we pass prefix=%package_folder%, which results in libraries with hard-coded conan-specific paths (like /home/jenkins/.conan/...). these paths obviously never exist on the real device. so the solution is to apply custom prefix and custom destidir during the build. libraries will still have hard-coded paths, but these paths are at least guaranteed to be correct and exist on the real device. this way, dbus will find its config, and so on.

and if you have 1000 packages, you obviously don't want to patch 1000 recipes just to do:

- cmake.configure()
+ cmake.configure(args=["--prefix=/usr/local"])
...
- cmake.install()
+ cmake.install(args=["DESTDIR=%s" % self.package_folder])

this doesn't scale. and these is a high change you need to build recipes and RPMs for multiple distros, so you will end up with multiple sets of recipes (e.g. one doing prefix=/usr/local and one doing prefix=/opt). I think it's pretty logical that it requires some global configuration.

SSE4 avatar Jul 28 '22 07:07 SSE4

@SSE4 Thank you very much for this summary!

And you brought up another good comment:

therefore, our default includedirs/libdirs wouldn't work out of the box if you tweak prefix/destdir. this will require adjustments in CppInfo and layout models to make it work smoothly.

I overlooked this. All the package_info funcs, would need to be adjusted as well...

  1. With the actual task, do you say, it should not be implemented, because we have to use a global solution anyway?
  2. What would be the generic solution for the package_info problem?
  3. Is this global solution something only for conan 2.x?

derived-coder avatar Jul 28 '22 17:07 derived-coder

for 1, global solution depends on local one. DESTDIR has to be implemented for the CMake helper first. for 2, generic solution is possible. basically, it's to join prefix in CppInfo defaults for 3, no idea, I think it can be ported to 1.x, but it might not be desired, as current policy is to avoid adding new things there

SSE4 avatar Jul 28 '22 17:07 SSE4