To help us debug your issue please explain:
Conan v1.0.1
The default settings for CMake projects is to use CMAKE_INSTALL_PREFIX=self.package_folder and no value for DESTDIR. For many projects, that results in absolute paths finding their way into installed files like exported (using the CMake term "exported" not Conan) CMake scripts. When another user then attempts to use that CMake script (such as find_package(foo REQUIRED)), it fails because it can't find /home/billybob/.conan/data/foo/1.0.0/user/channel/packages/asdfjkl/lib/foo.so. That /home/billybob should never have made its way into the package, but it did. Here's what I've done to work around the issue, and I think it should be the default:
def build(self):
cmake = CMake(self)
cmake.definitions['CMAKE_INSTALL_PREFIX'] = '/'
cmake.configure(source_dir='foobar')
cmake.build()
cmake.install(args=['--', 'DESTDIR=' + self.package_folder])
Interesting. How would you do the above to be generic for Windows too? Thanks!
Ugh... Windows...
Maybe a simple if-statement that uses the current approach for Windows and my suggestion for everything else? I don't know because I really don't know Windows at all.
Yes, exactly, big ugh :) :)
As stated in the cmake docs: https://cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_PREFIX.html, the DEST_DIR approach is only UNIX.
Keeping consistency among OSs is something we always have in mind, it is complicated, but it is very important. So changing the default behavior for one system and not the others is indeed a path to later big pain.
I would try to investigate what could be done to workaround what in my opinion is a weakness of the cmake-find approach: creating those scripts at build time make the packages not relocatable, and there is nothing that can be done in order to make them relocatable and transparent for the user at the same time. This is why conan generates the location information at package install time. Can't paths in find.cmake scripts be made relative to the current location of the script? Because the find.cmake scripts would be already in the package root, right?
Thanks for the feedback!
Hm... and my implementation is Makefile specific too. I'll dig into it more and come up with a concrete and reproducible example
Btw, has anyone mentioned that this idea of creating a universal C++ package manager is absurdly hard? Because it most definitely is. And you guys have, by far, done the best job of anyone that isn't enforcing a specific build system (gradle, buckaroo, etc).
Please note that absolute paths in generated cmake files are not the only thing keeping packages from being relocatable, there are RPATH issues too (see #1303 for more context).
I successfully managed to use relative RPATHs + imports ('CMAKE_INSTALL_RPATH' = '\\$ORIGIN'), but this requires careful handling.
Maybe CMake "exported" definitions need the same handling as the pkg-config *.pc files? Or just use that and switch from find_package to pkg_check_modules in the consuming CMakeLists.txt?
Okay, looks like using DESTDIR didn't even fix my problem. Here's the error I'm running into:
Executable A depends on Library B.
Library B depends on Library C.
Libraries B and C were built on Bob's computer.
Executable A is being built on David's computer.
In my case, Library C is Boost and Library B is FreeOpcUA. When I grep the CMake import script for FreeOpcUA, I see that it has a reference to Bob's home directory (/home/developer):
./lib/cmake/FreeOpcUa/FreeOpcUaConfig-release.cmake: IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE "pthread;dl;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_system.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_program_options.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_filesystem.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_thread.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_chrono.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_date_time.a;/home/developer/.conan/data/Boost/1.64.0/wsbu/stable/package/8958ea8fe46c6a287cfebd83c229c8fbd67e037e/lib/libboost_atomic.a"
Maybe this is just because Library B was built using the static version of Boost? Maybe if Library B had been built with dynamic Boost libraries this would be fixed? Off to go try that I guess.
My problem did not go away until both libraries B and C were built dynamically. I didn't realize that they were both static, but they were. I'm now thinking that the DESTDIR and CMAKE_INSTALL_PREFIX may not have had anything to do with it, because it never did change the outcome (even with the prefix set correctly, I was getting the same error until I switched to dynamic libraries).
Most helpful comment
Btw, has anyone mentioned that this idea of creating a universal C++ package manager is absurdly hard? Because it most definitely is. And you guys have, by far, done the best job of anyone that isn't enforcing a specific build system (gradle, buckaroo, etc).