[CMake] ProjectConfig.cmake, export() and multiple libraries

Michael Hertling mhertling at online.de
Wed Oct 12 08:39:54 EDT 2011


On 10/12/2011 11:31 AM, Jérémie Delaitre wrote:
> Hi all,
> 
> I have a project which provides a set of shared libraries, some libraries
> being dependent on other ones:
> 
> For example:
> libcore
> libmodule1 -> libcore
> libmodule2 -> libcore
> libmoduleA -> libmodule1
> 
> As this is a CMake based project, I've read on the internet that I should
> provide a ProjectConfig.cmake file to allow other CMake based projects to
> use the libraries. So I tried to do that after reading the tutorial on the
> CMake's wiki and I have a working ProjectConfig.cmake for an installed tree
> which contains all the targets (I did not succeed to have it working for an
> in build tree though).
> 
> The problem is that I want each of my libraries to be "self-supported" (for
> example, I'd like to use find_package() in module1 to find core). I want to
> be able to have different version for each library which depends on specific
> versions of the other libraries. If I am correct, that means I need to
> generate one ProjectConfig.cmake and one ProjectConfigVersion.cmake for each
> library.
> 
> This way, I should be able to create a project which does find_package(core
> 1.3) and find_package(module2 0.3) if it needs only the module2. But the
> Module2Config.cmake tries do redeclare the "core" imported target which is
> already created by the CoreConfig.cmake. Indeed I already have this problem
> directly in the Module2's CMakeLists.txt as I tried to find_package(core
> 1.3) here in order to define the include directories and to link to the
> core.
> 
> If I try to not export "core" when generating Module2Config.cmake, I get an
> error telling me that "module2" depends on "core" so it must be exported.
> 
> So, to sum it up, I'd like each "module" to find its dependencies as if it
> was third party libraries (installed tree and in build tree must be
> supported). Then, everything should be ok to create a project which uses
> only a few of the modules.
> 
> Any hints?

Imported targets require to be protected against being redefined
within the same scope, i.e. the following line from the tutorial

include("${FOOBAR_CMAKE_DIR}/FooBarLibraryDepends.cmake")

must not be executed unconditionally. See the discussion spawned
at the end of [1] for more information and a possible solution.

BTW, with your current approach, the lines

FIND_PACKAGE(core 1.3)
FIND_PACKAGE(module2 0.3)

in another project might pose a problem: After the first line, core's
export file has been processed, the imported target "core" is defined
and points to the 1.3 core library. Now, if Module2Config.cmake issues
FIND_PACKAGE(core 1.2), e.g., and a valid CoreConfig.cmake for 1.2 is
found but differs from the 1.3 version, the export file for core 1.2
won't le loaded because of the above-mentioned include guard, or if
the include guard is version-sensitive, you will redefine the core
imported target, and CMake bails out. Therefore, if the libraries'
versions are important to you, you should add them to the targets'
names, or make the latters differ from version to version by other
means. So, module2 will use the core1.2 imported target whereas the
overall project refers to core1.3. Anyway, using multiple versions
of a library within the same binary requires particular carefulness.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg35873.html


More information about the CMake mailing list