|
|
# 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(TARGETS <target> ...
|
|
|
FILE somefile.cmake
|
|
|
[PREFIX someprefix-]
|
|
|
[APPEND]
|
|
|
)
|
|
|
|
|
|
Export files generated for the build tree always have the full paths in
|
|
|
the LOCATION properties of the IMPORT targets it creates. The contents
|
|
|
are written immediately to the specified file, if APPEND is used then it
|
|
|
will be appended if the file already exists. This way it can be mixed
|
|
|
with FILE(WRITE ...) and EXPORT_LIBRARY_DEPENDENCIES() commands (...
|
|
|
which probably doesn't make a lot of sense).
|
|
|
|
|
|
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 exporting a simple project from the build tree
|
|
|
and install tree:
|
|
|
|
|
|
EXPORT( # anonymous export must be fully specified here
|
|
|
TARGETS mylibA mylibB mygen
|
|
|
FILE myproj-build.cmake
|
|
|
PREFIX myproj-1.2-
|
|
|
)
|
|
|
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
|
|
|
SET(EXPORT_FILE myproj-build.cmake)
|
|
|
SET(EXPORT_PREFIX myproj-1.2- )
|
|
|
|
|
|
INSTALL(
|
|
|
EXPORT myproj-install
|
|
|
DESTINATION lib/myproj-1.2
|
|
|
FILE myproj-install.cmake
|
|
|
PREFIX ${EXPORT_PREFIX})
|
|
|
)
|
|
|
|
|
|
# lib/CMakeLists.txt
|
|
|
EXPORT( TARGETS mylibA mylibB
|
|
|
FILE ${EXPORTS_FILE}
|
|
|
PREFIX ${EXPORTS_PREFIX}
|
|
|
)
|
|
|
INSTALL(TARGETS mylibA mylibB
|
|
|
EXPORT myproj-install
|
|
|
RUNTIME DESTINATION bin
|
|
|
ARCHIVE DESTINATION lib
|
|
|
LIBRARY DESTINATION lib
|
|
|
)
|
|
|
|
|
|
# exe/CMakeLists.txt
|
|
|
EXPORT(TARGETS mygen
|
|
|
FILE ${EXPORTS_FILE}
|
|
|
PREFIX ${EXPORTS_PREFIX}
|
|
|
)
|
|
|
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)
|
|
|
|
|
|
> Alex, just writing down thoughts: In the install() commands above the
|
|
|
> COMPONENT feature is unused.
|
|
|
>
|
|
|
> INSTALL(TARGETS mygen
|
|
|
> EXPORT myproj-install
|
|
|
> DESTINATION bin
|
|
|
> COMPONENT Runtime
|
|
|
> )
|
|
|
>
|
|
|
> I think both COMPONENT and EXPORT are used to create groups of
|
|
|
> installed targets. Maybe the EXPORT keyword is not required but
|
|
|
> instead INSTALL(EXPORT ... ) could use the COMPONENTS ?
|
|
|
>
|
|
|
> I think the typical use case for COMPONENT is to split packages into
|
|
|
> Runtime and Development. The Development component will include
|
|
|
> headers, static libraries, import libraries and cmake files. It may
|
|
|
> contain eventual code generators and tools, but they might also be in
|
|
|
> the Runtime component.
|
|
|
>
|
|
|
> One problem is that the different parts of a shared library will
|
|
|
> typically be in different components. Maybe this could be ignored and
|
|
|
> the library could be exported if any of its parts (ARCHIVE, RUNTIME,
|
|
|
> LIBRARY) is in the given COMPONENT ? Let's say the ARCHIVE part of a
|
|
|
> library is in the Development component, and I export the Development
|
|
|
> component, then this library will also be exported.
|
|
|
>
|
|
|
> But then this library will also be exported if the Runtime component
|
|
|
> is exported, since its RUNTIME part should belong to the Runtime
|
|
|
> component. OTOH, exporting a Runtime component doesn't make a lot of
|
|
|
> sense, because if you import something you are developing, so it must
|
|
|
> be development related stuff.
|
|
|
>
|
|
|
> Then again, a code generator executable should belong to the
|
|
|
> Development component, but its DESTINATION will be specified in the
|
|
|
> RUNTIME part, while the destination of the dll part of a library will
|
|
|
> also be in the RUNTIME part but it should belong to the Runtime
|
|
|
> component. This may be slightly confusing if one INSTALL(TARGETS ...)
|
|
|
> command is used for libraries, executables and "development"
|
|
|
> executables.
|
|
|
>
|
|
|
> So if such code generators belong to the Development component, and
|
|
|
> this component is exported, this will mean that also all the library
|
|
|
> targets will end up in the exported file, which will be good for the
|
|
|
> general case. When cross compiling it would probably be better if only
|
|
|
> the executables would go in the exported file, because the libraries
|
|
|
> aren't of any use then.
|
|
|
>
|
|
|
> So a third component DevelopmentTools might be a good idea, which
|
|
|
> would contain just these executables. Then when creating a regular
|
|
|
> development package two components would have to be installed,
|
|
|
> Development and DevelopmentTools. I think this is currently not
|
|
|
> supported by the generated cmake_install.cmake scripts, don't know
|
|
|
> about cpack.
|
|
|
>
|
|
|
> This could then also be added to the EXPORT() command, so that there
|
|
|
> is not only EXPORT(TARGETS ...), but also EXPORT(COMPONENT ...)
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CMake:ExportInterface) in another wiki. |