CMake:ExportInterface

From KitwarePublic
Jump to navigationJump to search

Export Interface for CMake Projects

This page documents a prototype design Alex and Brad created for exporting project information from a CMake project for use by outside projects.

The EXPORT command is used to export information from a project build tree:

EXPORT([export-name]
  [FILE somefile.cmake]
  [PREFIX someprefix-]
  [TARGETS <target>...]
  )

Export files generated for the build tree always have the full paths in the LOCATION properties of the IMPORT targets it creates.

The EXPORT mode of the INSTALL command is used to export information from an install tree:

INSTALL(
  EXPORT <export-name>
  DESTINATION lib/myproj-1.2
  FILE <file-for-install>.cmake
  [PREFIX someprefix-]
  )
INSTALL(
  TARGETS ...
  EXPORT <export-name> # attach these installed targest to the named export
  ...)

Export files generated for the install tree have LOCATION properties that may be relative to the installation prefix. The INSTALL(EXPORT ...) command creates code at the top of the export script that computes the install prefix. If the export script is installed relative to the installation prefix it computes the prefix relative to its own location. If the export script is installed to an absolute path the installation prefix is hard-coded into the file.

The INSTALL(TARGETS ... EXPORT ...) command creates code in the export script to specify the IMPORT target. If the destination is relative to the installation prefix the LOCATION property is specified relative to the install prefix set by the INSTALL(EXPORT ...) command. If the destination is to an absolute path that path is hard-coded into the LOCATION property.

Here is an example for exporing a simple project from the build tree and install tree:

EXPORT( # anonymous export must be fully specified here
  FILE myproj-build.cmake
  PREFIX myproj-1.2-
  TARGETS mylibA mylibB mygen
  )
INSTALL(
  TARGETS mylibA mylibB mygen
  EXPORT  myproj-install
  RUNTIME DESTINATION bin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  )
INSTALL(
  EXPORT myproj-install
  DESTINATION lib/myproj-1.2
  FILE myproj-install.cmake
  PREFIX myproj-1.2-
  )

A more complicated project may be organized this way:

# CMakeLists.txt
EXPORT(myproj-build # named export allows more rules later
  FILE myproj-build.cmake
  PREFIX myproj-1.2-
  )
INSTALL(
  EXPORT myproj-install
  DESTINATION lib/myproj-1.2
  FILE myproj-install.cmake
  PREFIX myproj-1.2-
  )

# lib/CMakeLists.txt
EXPORT(myproj-build
  TARGETS mylibA mylibB
  )
INSTALL(TARGETS mylibA mylibB
  EXPORT myproj-install
  RUNTIME DESTINATION bin
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  )

# exe/CMakeLists.txt
EXPORT(myproj-build
  TARGETS mygen
  )
INSTALL(TARGETS mygen
  EXPORT myproj-install
  DESTINATION bin
  )

The generated export .cmake file for the build tree will have content such as

add_library(myproj-1.2-mylibA IMPORT)
set_target_properties(mylibA PROPERTIES
  LOCATION /path/to/libmylibA.a)

add_library(myproj-1.2-mylibB IMPORT)
set_target_properties(mylibB PROPERTIES
  LOCATION /path/to/libmylibB.a
  INTERFACE_LIBRARIES myproj-1.2-mylibA
  )

add_executable(myproj-1.2-mygen IMPORT)
set_target_properties(mylibB PROPERTIES
  LOCATION /path/to/mygen)

The generated export .cmake file for the install tree will have content such as

# PREFIX/lib/myproj-1.2/exports.cmake
get_filename_component(myproj-1.2-_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(myproj-1.2-_PREFIX "${myproj-1.2-_PREFIX}" PATH)
get_filename_component(myproj-1.2-_PREFIX "${myproj-1.2-_PREFIX}" PATH)
add_library(myproj-1.2-mylibA IMPORT)
set_target_properties(mylibA PROPERTIES
  LOCATION ${myproj-1.2-_PREFIX}/lib/libmylibA.a)

add_library(myproj-1.2-mylibB IMPORT)
set_target_properties(mylibB PROPERTIES
  LOCATION ${myproj-1.2-_PREFIX}/lib/libmylibB.a
  INTERFACE_LIBRARIES myproj-1.2-mylibA
  )

add_executable(myproj-1.2-mygen IMPORT)
set_target_properties(mylibB PROPERTIES
  LOCATION ${myproj-1.2-_PREFIX}/bin/mygen)