CMake: Recommended way for Config-File package, which depends on Find-Module package

I just read about the CMake Config-File Package "Concept" which sounds very promising. I really like that if I create the Config-File package myself, I can specify other packages that it depends on. My question is, how can I create a Config-File package that "floats" and depends on the Find-Module package (like boost)?

More details: Suppose I want to create a package named HyDi. cmake documentation explains very well how I can create the corresponding HydiConfig.cmake and HydiTargets.cmake files automatically. A very simple CMakeLists.txt version that does this:

project(HyDi)

find_package(Boost COMPONENTS program_options)
add_library(HyDi foo.cpp foo.hpp)
target_include_directories(HyDi PUBLIC INTERFACE ${Boost_INCLUDE_DIRS})
target_link_libraries(HyDi ${Boost_LIBRARIES})
target_compile_options(HyDi INTERFACE PUBLIC "-std=c++11")


install(TARGETS HyDi EXPORT HyDiTarget
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)

install(FILES foo.hpp DESTINATION include)

configure_file(cmake/HyDiConfig.cmake
  "${CMAKE_CURRENT_BINARY_DIR}/HyDi/HyDiConfig.cmake"
  COPYONLY
)

set(ConfigPackageLocation lib/cmake/HyDi)
install(EXPORT HyDiTarget FILE HyDiTargets.cmake 
    NAMESPACE Upstream:: DESTINATION ${ConfigPackageLocation} )
install(FILES cmake/HyDiConfig.cmake DESTINATION ${ConfigPackageLocation})

      

Corresponding HydiConfig.cmake:

include(CMakeFindDependencyMacro)
find_dependency(Boost COMPONENTS program_options)

include("${CMAKE_CURRENT_LIST_DIR}/HyDiTargets.cmake")

      

However, if I install this library, the HyDiTargets.cmake file contains the include path to the Boost Libraries hardcoded files and therefore does not move.

Please note that the cmake documentation gives an example of how to not include the boost libraries, which are essentially my version. But, unfortunately, they do not explain how to do it better.

I understand that I could create boost using cmake and then import boost as a Config-file package so that my HydiTargets.cmake is relocatable. But this approach does not work with any other library that provides the Findxxx.cmake file.

+3


source to share


1 answer


In fact, CMake is doing it right when it enters a "hardcoded" path for extending libraries (and you are doing it wrong). Because after your library is compiled and installed, it needs to "link" with a specific version of the acceleration (when it was at the time the library was compiled) - that is, its header files and static / dynamic libraries.

Consider a scenario: After successfully installing your library, someone installs a new version of the boost library (or any other third-party library, depending on you) in parallel (yes, boost and some other libraries can coexist in the same installation prefix) so that everyone looked like a real world example, suppose the ABI is incompatible with the previous version. Now, if this "lucky" developer wants to use your (already compiled and installed) library (using the exported targets and provided HyDiConfig.cmake

), he will have problems:

  • your library is already linked with a "previous" version of boost (remember that the ABI is incompatible with the newer one);
  • so when you somehow replace those "hardcoded" paths and find a newer version (as you are trying to do in HyDiConfig.cmake

    ), your lucky client will be mad at you for this mess!


It's not only boost support ... the same policy for all third-party libraries: they must remain the same as at compile time (or at least ABI compliant if we're talking about dynamic linking at runtime, but that's that's another story).

Also, your user probably isn't even using boost in their application (but has more than one version) - why should you find smth? You already know (thanks to CMake and hardcoded paths) which version your library is "required" for! So finding something new in this case is completely wrong! "Too late ... Your library is already compiled, linked and installed!

Another case: he wants to use some other (newer) version of boost ... Depending on the order find_package(boost)

, the find_package(yourLib)

results may differ ... but he will still be angry with you!

-2


source







All Articles