Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Installing a CMake library: also ship find modules for the dependencies?

Tags:

cmake

My CMake library, MyLibrary, has a dependency for OtherLibrary, that I import with a non-standard FindOtherLibrary.cmake.

My library depends on OtherLibrary publicly:

target_link_libraries(MyLibrary PUBLIC OtherLibrary::OtherLibrary)

When I install MyLibrary (together with MyLibraryConfig.cmake), and users want to link against it, they therefore need to import OtherLibrary.

Is there a good practice regarding how to distribute FindOtherLibrary.cmake along MyLibrary?


Ideally, one could make things even easier for users of MyLibrary by importing OtherLibrary automatically from the installed config file MyLibraryConfig.cmake, if it contains something like

include(CMakeFindDependencyMacro)
find_dependency(OtherLibrary)

and knows where FindOtherLibrary.cmake is.

Is this at all possible?

like image 866
oLen Avatar asked Jul 05 '17 08:07

oLen


2 Answers

I ended up finding a solution to my question.

In principle, it does what @utopia suggested, but in an automated fashion: the end user of my library does not need to set up (or even know about) FindOtherLibrary.cmake. It will be imported automatically by MyLibraryConfig.cmake.

To do so, I install FindOtherLibrary.cmake along MyLibraryConfig.cmake:

install(FILES
          /path/to/MyLibraryConfig.cmake
        DESTINATION
          lib/cmake/MyLibrary
        )
install(FILES
          /path/to/FindOtherLibrary.cmake
        DESTINATION
          lib/cmake/MyLibrary/Modules
        )

And in MyLibraryConfig.cmake I set up how to import it:

include(CMakeFindDependencyMacro)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/Modules/")
find_dependency(OtherLibrary REQUIRED)

Note that I set the variable CMAKE_MODULE_PATH because it is not possible to specify the location of find modules in find_package or find_dependency (works only for config mode).

like image 107
oLen Avatar answered Sep 28 '22 10:09

oLen


"Transitive" behavior for module-mode find_package() is not supported.

In fact, I don't believe it is even possible since it requires modifying downstream CMake module path with information you would not have available to you. That's one of the reasons there is a config-mode find_package() (see here).

To be clear, a user of your library, which has a dependency on a FindModule library, has no choice but to know how to get a copy of the FindModule script and add it to their CMake module path. This is typically done through documentation. You as the author of a library that uses the FindModule cannot shortcut that process for the end user in any general way. So, there is no "good practice" for such a process.

Otherwise, good practice is to use FindModules only for non-CMake projects and use Config.cmake for CMake projects. If a dependent CMake library has no Config.cmake, you're out of luck (tell them they need it to support CMake in a Bug/Issue report).

like image 34
utopia Avatar answered Sep 28 '22 10:09

utopia