[CMake] Installing and Exporting for multiple configurations

Matthew Woehlke matthew.woehlke at kitware.com
Thu Apr 4 11:28:57 EDT 2013


On 2013-04-03 22:06, Saad Khattak wrote:
> Hi,
>
> I am trying my best to understand CMake's install and export commands so
> that separate projects are able to find libraries easily.
>
> I am having a tremendously hard time understand what CMake is doing. After
> 'add_library()' where the library is called 'myLib' I called the following:
>
> install(TARGETS myLib
>      DESTINATION ${PROJECT_BINARY_DIR}/lib/
>      EXPORT repoA-targets
>      )

You're installing to your build directory. Don't do that. You should 
install to the install prefix, which is most easily done by not 
specifying a full path to DESTINATION (the prefix is automatically 
prepended to relative paths).

Also, you should install to 'lib${LIB_SUFFIX}', not 'lib'. This will 
allow you (and distros packaging your software) to set LIB_SUFFIX to 
separate arch-specific components of 32- and 64-bit builds. E.g. on 
Linux, lib_suffix is usually ''/'64' or '32'/'', and on Windows might be 
''/'/amd64'.

> That is only part of the problem. Now in RepoB, I want to import the
> libraries. CMake documentation here:
> http://www.cmake.org/Wiki/CMake/Tutorials/Exporting_and_Importing_Targets
>
> states that I can do something like this:
> include(${PATH_OF_REPO_A_BUILD}/repoA-targets.cmake)

You can, but I wouldn't recommend it. Instead, you should create a 
'repoAConfig.cmake' that is installed by repoA, which does this for you. 
Then use repoA with 'find_package(repoA)'.

Usually I generate (with @ONLY) a FooConfig.cmake and 
FooConfig-install.cmake with each containing an appropriate 
Foo_INCLUDE_DIRS. The first, intended for using your package from the 
build directory, will set its include directories to locations in your 
source and/or build. The second usually uses 
@CMAKE_INSTALL_PREFIX@/include, and is installed with the RENAME option 
to rename it 'back' to FooConfig.cmake.

Besides setting the INCLUDE_DIRS, it should include the line:

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

> target_link_libraries(repoBExecutable myLib)

...and then you can do this.

Some things to check if it is not working:

- Open repoATargets.cmake and verify that it is declaring an imported 
'myLib' target.
- if(NOT TARGET myLib)
     message(SEND_ERROR "myLib not a target?!")
   endif()

It may also be beneficial to look at an existing CMake project...

-- 
Matthew



More information about the CMake mailing list