4

I'm updating a (very old) find-module of a library. So the situation is an existing shared library which uses CMake itself. Users might already have this installed somewhere, in package repos or whatever.

Now they want to use this. The good way would be

find_package(Foo REQUIRED)
target_link_libraries(MyProject Foo::Foo)

So thats the goal.

The question is: How would a good find_package-Config or -Module look like which allows this 2-liner to work? It should meet these 2 requirements:

  • Allow a CMake version to use the library older than the one used to build it
  • Enforce e.g C++11 mode. In a Find-Module one can set the C++11 requirement based on the version (cxx_std_11 (CMake 3.8+), cxx_alias_templates (CMake 3.1+), check_cxx_source_compiles with C++11 code and a warning for older CMakes)

There are 2 ways of doing that:

  1. Update the find-module to define an imported library Foo::Foo and set it up correctly (using properties) and be nice to also set FOO_INCLUDE_DIR and FOO_LIBRARIES for old CMake w/o targets.
    This is pretty easy: Just use find_path and find_library, set up the imported target and be done. Works forwards and backwards compatible so even the old versions would be found.

Usage:
The user copies (the most recent) FindFoo.cmake to its project into e.g. cmake/Modules and points CMAKE_MODULE_PATH to it, or copy FindFoo.cmake to some CMake default path.

  1. Listening to Daniel Pfeiffer and Modern CMake which says If you are the library author, don't make a Find<mypackage>.cmake script! So we export and install targets.
    This is a bit messy. Following changes are required:

    • Add EXPORTS FooTargets and INCLUDES DESTINATION include to install(TARGETS (see Pfeiffer #24) which basically just defines an export. (I don't really see, why I would want to create an extra name for something that already has a name. Why can't the below command not simply refer to a target?)
    • Add install(EXPORT FooTargets NAMESPACE Foo:: DESTINATION lib/cmake/Foo) which would create a FooTargets.cmake in <CMAKE_INSTALL_PREFIX>/lib/cmake/Foo that defines a target Foo::Foo with (hopefully) all its dependencies
    • Add "something" creating FooConfigVersion.cmake possibly by using write_basic_package_version_file that, to my understanding, hard-codes the version to that file
    • Create a FooConfig.cmake that may use find_dependency to search for libraries that Foo depends on and includes FooTargets.cmake
    • Install FooConfig.cmake and FooConfigVersion.cmake to lib/cmake/Foo
    • modify target_include_directories to use separate BUILD_INTERFACE and INSTALL_INTERFACE paths

Usage:
find_package automatically finds the FooConfig.cmake and FooConfigVersion.cmake when Foo is searched for.

So the Config-Module should be preferred but problems I see are:

  • The process looks more complicated
  • It cannot be used to enable users to find older versions of the library (that did not use this approach)
  • It excludes all (library-)users with older CMake (2.8.11 is probably the minimum required here)
  • It requires a newer CMake version to build the library itself
  • The C++11 requirement seems to be very hard to encode

So can we solve the requirements with a CMake-Config? An answer should provide a solution or at least a well grounded "impossible". It should also address the problems outlined at the end.

Final Note: I guess this makes a nice wiki-entry if it doesn't exist.

Flamefire
  • 5,313
  • 3
  • 35
  • 70
  • Well-formulated question and answers for it can be easily treated as "wiki-entry". Currently, I see the only question in your post about CMake version-independent usage requirement in export approach. But this question is near at the end of the post; the rest of the post is quite a long "introduction". Could you reorganize the post, so the question will be near the **beginning**? Otherwise, it is too hard to find a real question. Also, current title is very generic; it is better when a title reflects a problem, not a problem area. – Tsyvarev Mar 13 '18 at 18:31
  • Better now? If you find a better title please edit it. I specifically want this as a wiki-entry (or a base for one) as I think it covers everything from goal, usage instructions to problems and will hopefully even have solutions for them. – Flamefire Mar 13 '18 at 18:47
  • Yes, the question post becomes better now, thanks. – Tsyvarev Mar 13 '18 at 19:50
  • To be honest, I'm having trouble reading the question still: Its internal order is unclear, it has forward- references, it uses ambiguous pronouns occasionally, etc. – einpoklum May 14 '18 at 09:41
  • I structured it a bit better. It's not easy but I think this is due to the question being not easy to answer. – Flamefire May 14 '18 at 11:18

0 Answers0