8

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?

oLen
  • 5,177
  • 1
  • 32
  • 48
  • Do not understand your problem. `When I install 'MyLibrary' (together with 'MyLibraryConfig.cmake')` - in that case your config file **already** contains paths to your and other libraries and appropriate relation between them. So when user links with `MyLibrary` target, it automatically links with `OtherLibrary`. No `FindOtherLibrary.cmake` script is needed. – Tsyvarev Jul 05 '17 at 08:25
  • @Tsyvarev You're correct, as long as the paths for `OtherLibrary` are hard-coded. However, if `FindOtherLibrary.cmake` defines imported targets, which I prefer, users of `MyLibrary` also must be able to find `OtherLibrary` "on their own". – oLen Jul 05 '17 at 08:33
  • If you do not want hardcoded paths, you should provide `FindMyLibrary.cmake` script instead of `MyLibraryConfig.cmake`. For work with your library user needs to ship his(her) project with that script, ... and with every other script you describe in docs (and adjust *CMAKE_MODULE_PATH* accordingly). So you may provide `FindOtherLibrary.cmake` alongside with `FindMyLibrary.cmake`. – Tsyvarev Jul 05 '17 at 08:47
  • 1
    @Tsyvarev In this case I have a different opinion: it would defeat the whole point! In my eyes `MyLibraryConfig.cmake` is superior to `FindMyLibrary.cmake` since it is able to set all dependencies following how you compiled the shipped `MyLibrary`, while in `FindMyLIbrary.cmake` this would need to be specified manually. Ideally the developers of `OtherLibrary` would also provide `OtherLibraryConfig.cmake`, but this is not the case, and thus my SO question. – oLen Jul 05 '17 at 08:55

2 Answers2

4

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).

oLen
  • 5,177
  • 1
  • 32
  • 48
  • How did you add those lines (`find_dependency` etc) into the config file? Did you add it manually? Is there a way to add it from the CMakeLists? – user3667089 Dec 07 '17 at 00:50
  • 1
    I added it manually. To my knowledge there is no way to do it automatically. – oLen Dec 07 '17 at 08:08
1

"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).

utopia
  • 1,477
  • 8
  • 7