|
|
(27 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| __TOC__
| | {{CMake/Template/Moved}} |
|
| |
|
| This page documents some of the changes and new features available in CMake 2.6. | | This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/notes/2.6 here]. |
| | |
| =Exporting and Importing Targets=
| |
| | |
| CMake 2.6 introduces support for exporting targets from one project and importing them into another.
| |
| The main feature allowing this functionality is the notion of an <code>IMPORTED</code> target.
| |
| Here we present imported targets and then show how CMake files may be generated by a project to export its targets for use by other projects.
| |
| | |
| ==Importing Targets==
| |
| | |
| Imported targtes are used to convert files outside the project on disk into logical targets inside a CMake project.
| |
| They are created using the <code>IMPORTED</code> option to <code>add_executable</code> and <code>add_library</code> commands.
| |
| No build files are generated for imported targets.
| |
| They are useful simply for convenient, flexible reference to outside executables and libraries.
| |
| | |
| Consider the following example which creates and uses an IMPORTED executable target:
| |
| | |
| add_executable(generator IMPORTED) # 1
| |
| set_property(TARGET generator PROPERTY IMPORTED_LOCATION "/path/to/some_generator") # 2
| |
|
| |
| set(GENERATED_SRC ${CMAKE_CURRENT_BINARY_DIR}/generated.c)
| |
| add_custom_command(
| |
| OUTPUT ${GENERATED_SRC}
| |
| COMMAND generator ${GENERATED_SRC} # 3
| |
| )
| |
|
| |
| add_executable(myexe src1.c src2.c ${GENERATED_SRC})
| |
| | |
| Line #1 creates a new CMake target called "<code>generator</code>".
| |
| Line #2 tells CMake the location of the file on disk to import.
| |
| Line #3 references the target in a custom command. The generated build system will contain a command line such as
| |
| | |
| /path/to/some_generator /project/binary/dir/generated.c
| |
| | |
| in the rule to generate the source file.
| |
| | |
| Libraries may also be used through imported targets:
| |
| | |
| add_library(foo IMPORTED)
| |
| set_property(TARGET foo PROPERTY IMPORTED_LOCATION /path/to/libfoo.a)
| |
| add_executable(myexe src1.c src2.c)
| |
| target_link_libraries(myexe foo)
| |
| | |
| The generated build system will contain a command line such as
| |
| | |
| ... -o myexe /path/to/libfoo.a ...
| |
| | |
| in the rule to link <code>myexe</code>.
| |
| On Windows a .dll and its .lib import library may be imported together:
| |
| | |
| add_library(bar IMPORTED)
| |
| set_property(TARGET bar PROPERTY IMPORTED_LOCATION c:/path/to/bar.dll)
| |
| set_property(TARGET bar PROPERTY IMPORTED_IMPLIB c:/path/to/bar.lib)
| |
| add_executable(myexe src1.c src2.c)
| |
| target_link_libraries(myexe bar)
| |
| | |
| The generated build system will contain a command line such as
| |
| | |
| ... -o myexe.exe c:/path/to/bar.lib ...
| |
| | |
| in the rule to link <code>myexe</code>.
| |
| A library with multiple configurations may be imported with a single target:
| |
| | |
| add_library(foo IMPORTED)
| |
| set_property(TARGET foo PROPERTY IMPORTED_LOCATION_RELEASE c:/path/to/foo.lib)
| |
| set_property(TARGET foo PROPERTY IMPORTED_LOCATION_DEBUG c:/path/to/foo_d.lib)
| |
| add_executable(myexe src1.c src2.c)
| |
| target_link_libraries(myexe foo)
| |
| | |
| The generated build system will link <code>myexe</code> to <code>foo.lib</code> when it is built in the release configuration and <code>foo_d.lib</code> when built in the debug configuration.
| |
| | |
| ==Exporting Targets==
| |
| | |
| Imported targets on their own are useful, but they still require the project that imports targets to know the locations of the target files on disk.
| |
| The real power of this feature is when the project providing the target files also provides a file to help import them.
| |
| | |
| ===Exporting from and Installation Tree===
| |
| | |
| The <code>install(TARGETS)</code> and <code>install(EXPORT)</code> commands work together to install a target and a file to help import it.
| |
| For example, the code
| |
| | |
| add_executable(generator generator.c)
| |
| install(TARGETS generator DESTINATION lib/myproj/generators EXPORT myproj-targets)
| |
| install(EXPORT myproj-targets DESTINATION lib/myproj)
| |
| | |
| installs the files
| |
| | |
| <prefix>/lib/myproj/generators/generator
| |
| <prefix>/lib/myproj/myproj-targets.cmake
| |
| | |
| The <code>myproj-targets.cmake</code> file contains code such as
| |
| | |
| add_executable(generator IMPORTED)
| |
| set_property(
| |
| TARGET generator
| |
| PROPERTY IMPORTED_LOCATION ${PREFIX}/lib/myproj/generators/generator
| |
| )
| |
| | |
| (in practice the <code>${PREFIX}</code> is computed relative to the file location automatically).
| |
| An outside project may now contain code such as
| |
| | |
| include(${PREFIX}/lib/myproj/myproj-targets.cmake) # 1
| |
| set(GENERATED_SRC ${CMAKE_CURRENT_BINARY_DIR}/generated.c)
| |
| add_custom_command(
| |
| OUTPUT ${GENERATED_SRC}
| |
| COMMAND generator ${GENERATED_SRC} # 2
| |
| )
| |
| add_executable(myexe src1.c src2.c ${GENERATED_SRC})
| |
| | |
| Line #1 loads the target import script. The script may import any number of targets. Their locations are computed relative to the script location so the install tree may be moved around.
| |
| The importing project need only find the import script (see the packaging section of this document for how this might be done).
| |
| Line #2 references the generator executable in a custom command. The resulting build system will run the executable from its installed location.
| |
| | |
| Libraries may also be exported and imported:
| |
| | |
| add_library(foo STATIC foo1.c)
| |
| install(TARGETS foo DESTINATION lib EXPORTS myproj-targets)
| |
| install(EXPORT myproj-targets DESTINATION lib/myproj)
| |
| | |
| This installs the library and an import file referencing it. Outside projects may simply write
| |
| | |
| include(${PREFIX}/lib/myproj/myproj-targets.cmake)
| |
| add_executable(myexe src1.c)
| |
| target_link_libraries(myexe foo)
| |
| | |
| and the executable will be linked to the library <code>foo</code> exported and installed by the original project.
| |
| | |
| Any number of target installations may be associated with the same export name.
| |
| The export names are considered global so any directory may contribute a target installation.
| |
| Only one call to the <code>install(EXPORT)</code> command is needed to install an import file that references all targets.
| |
| Both of the examples above may be combined into a single export, even if they are in different subdirectories of the project:
| |
| | |
| # A/CMakeLists.txt
| |
| add_executable(generator generator.c)
| |
| install(TARGETS generator DESTINATION lib/myproj/generators EXPORT myproj-targets)
| |
|
| |
| # B/CMakeLists.txt
| |
| add_library(foo STATIC foo1.c)
| |
| install(TARGETS foo DESTINATION lib EXPORTS myproj-targets)
| |
|
| |
| # Top CMakeLists.txt
| |
| add_subdirectory(A)
| |
| add_subdirectory(B)
| |
| install(EXPORT myproj-targets DESTINATION lib/myproj)
| |
| | |
| ===Exporting from a Build Tree===
| |
| | |
| Typically projects are built and installed before being used by an outside project.
| |
| However in some cases it is desirable to export targets directly from a build tree.
| |
| The targets may then be used by an outside project that references the build tree with no installation involved.
| |
| | |
| The <code>export</code> command is used to generate a file exporting targets from a project build tree.
| |
| For example, the code
| |
| | |
| add_executable(generator generator.c)
| |
| export(TARGETS generator FILE myproj-exports.cmake)
| |
| | |
| will create a file in the project build tree called <code>myproj-exports.cmake</code> that contains code such as
| |
| | |
| add_executable(generator IMPORTED)
| |
| set_property(TARGET generator PROPERTY IMPORTED_LOCATION "/path/to/build/tree/generator")
| |
| | |
| This file may be loaded by an outside project that is aware of the project build tree in order to use the executable to generate a source file.
| |
| | |
| An example application of this feature is for building a generator executable on a host platform when cross compiling.
| |
| The project containing the generator executable may be built on the host platform and then the project that is being cross-compiled for another platform may load it.
| |
| | |
| =Packages=
| |
| | |
| This section documents creation and use of packages that help projects locate each other.
| |
| These features are distinct from CPack which is meant for creating source and binary distributions and installers.
| |
| | |
| The <code>find_package</code> command has been enhanced with features to help find packages without the use of "find" modules (FindXXX.cmake files).
| |
| Projects that are aware of CMake may provide a "package configuration file" inside their installation trees.
| |
| Naming the file correctly and installing it in a suitable location will allow the <code>find_package</code> command to find it easily.
| |
| | |
| ==Package Configuration Files==
| |
| | |
| Consider a project "Foo" that installs the following files:
| |
| | |
| <prefix>/include/foo-1.2/foo.h
| |
| <prefix>/lib/foo-1.2/libfoo.a
| |
| | |
| It may also provide a CMake package configuration file
| |
| | |
| <prefix>/lib/foo-1.2/foo-config.cmake
| |
| | |
| with content such as
| |
| | |
| # ...
| |
| # (compute PREFIX relative to file location)
| |
| # ...
| |
| set(foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
| |
| set(foo_LIBRARY ${PREFIX}/lib/foo-1.2/libfoo.a)
| |
| | |
| If another project wishes to use Foo it need only to locate the <code>foo-config.cmake</code> file and load it to get all the information it needs about package content locations.
| |
| Since the package configuration file is provided by the package installation it already knows all the file locations.
| |
| | |
| The <code>find_package</code> command may be used to search for the configuration file:
| |
| | |
| find_package(Foo)
| |
| | |
| This command (assuming no <code>FindFoo.cmake</code> module exists) constructs a set of installation prefixes and searches under each prefix in several locations.
| |
| Given the name "Foo", it looks for a file called "<code>FooConfig.cmake</code>" or "<code>foo-config.cmake</code>".
| |
| The full set of locations is specified in the <code>find_package</code> command documentation, but one place it looks is
| |
| | |
| <prefix>/lib/Foo*/
| |
| | |
| where "<code>Foo*</code>" is a case-insensitive globbing expression.
| |
| In our example the globbing expression will match "<code><prefix>/lib/foo-1.2</code>" and the configuration file will be found.
| |
| | |
| Once found, a package configuration file is immediately loaded. It contains all the information the project needs to use the package.
| |
| | |
| ===Packaging and Exporting===
| |
| | |
| Package configuration files may also work in conjunction with the target exporting/importing feature discussed above.
| |
| For example, a project might write
| |
| | |
| add_library(mylib STATIC mylib.c mylib.h)
| |
| install(FILES mylib.h DESTINATION include/myproj)
| |
| install(TARGETS mylib DESTINATION lib/myproj EXPORT mylib-targets)
| |
| install(EXPORT mylib-targets DESTINATION lib/myproj)
| |
| install(FILES mylib-config.cmake DESTINATION lib/myproj)
| |
| | |
| where <code>mylib-config.cmake</code> contains something like
| |
| | |
| get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
| |
| include(${SELF_DIR}/mylib-targets.cmake)
| |
| get_filename_component(myproj_INCLUDE_DIRS "${SELF_DIR}/../../include/myproj" ABSOLUTE)
| |
| | |
| After the project is built and installed, an outside project may use it by writing
| |
| | |
| find_package(myproj REQUIRED)
| |
| include_directories(${myproj_INCLUDE_DIRS})
| |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe mylib)
| |
| | |
| ==Package Version Files==
| |
| | |
| =Preprocessor Definitions=
| |
| | |
| Preprocessor definitions may now be added to builds with much finer granularity than in previous versions of CMake. There is a new property called <code>COMPILE_DEFINITIONS</code> that is defined directories, targets, and source files. For example, the code
| |
| | |
| add_library(mylib src1.c src2.c)
| |
| add_executable(myexe main1.c)
| |
| | |
| set_property(
| |
| DIRECTORY
| |
| PROPERTY COMPILE_DEFINITIONS A AV=1
| |
| )
| |
| set_property(
| |
| TARGET mylib
| |
| PROPERTY COMPILE_DEFINITIONS B BV=2
| |
| )
| |
| set_property(
| |
| SOURCE src1.c
| |
| PROPERTY COMPILE_DEFINITIONS C CV=3
| |
| )
| |
| | |
| will build the source files with these definitions:
| |
| | |
| src1.c: -DA -DAV=1 -DB -DBV=2 -DC -DCV=3
| |
| src2.c: -DA -DAV=1 -DB -DBV=2
| |
| main2.c: -DA -DAV=1
| |
| | |
| When the <code>add_definitions</code> command is called with flags like "<code>-DX</code>" the definitions are extracted and added to the current directory's <code>COMPILE_DEFINITIONS</code> property. When a new subdirectory is created with <code>add_subdirectory</code> the current state of the directory-level property is used to initialize the same property in the subdirectory.
| |
| | |
| Note in the above example that the <code>set_property</code> command will actually '''set''' the property and replace any existing value. The command provides the <code>APPEND</code> option to help add more definitions without removing existing ones. For example, the code
| |
| | |
| set_property(
| |
| SOURCE src1.c
| |
| APPEND PROPERTY COMPILE_DEFINITIONS D DV=4
| |
| )
| |
| | |
| will add the definitions "<code>-DD -DDV=4</code>" when building <code>src1.c</code>.
| |
| | |
| Definitions may also be added on a per-configuration basis using the <code>COMPILE_DEFINITIONS_<CONFIG></code> property. For example, the code
| |
| | |
| set_property(
| |
| TARGET mylib
| |
| PROPERTY COMPILE_DEFINITIONS_DEBUG MYLIB_DEBUG_MODE
| |
| )
| |
| | |
| will build sources in mylib with <code>-DMYLIB_DEBUG_MODE</code> only when compiling in a <code>Debug</code> configuration.
| |
| | |
| =Link Line Generation=
| |
| | |
| CMake 2.6 implements a new approach to generating link lines for targets.
| |
| | |
| Consider these libraries:
| |
| | |
| /path/to/libfoo.a
| |
| /path/to/libfoo.so
| |
| | |
| Previously if someone wrote
| |
| | |
| target_link_libraries(myexe /path/to/libfoo.a)
| |
| | |
| CMake would generate this code to link it:
| |
| | |
| ... -L/path/to -Wl,-Bstatic -lfoo -Wl,-Bdynamic ...
| |
| | |
| This worked most of the time, but some platforms (such as OS X) do not
| |
| support the <code>-Bstatic</code> or equivalent flag. This made it impossible to
| |
| link to the static version of a library without creating a symlink in
| |
| another directory and using that one instead.
| |
| | |
| Now CMake will generate this code:
| |
| | |
| ... /path/to/libfoo.a ...
| |
| | |
| This guarantees that the correct library is chosen. However there are some side-effects.
| |
| | |
| ==Missing Linker Search Directories==
| |
| | |
| Projects used to be able to write this (wrong) code and it would work by accident:
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| where "<code>B</code>" is meant to link "<code>/path/to/libB.so</code>". This code is incorrect
| |
| because it asks CMake to link to <code>B</code> but does not provide the proper
| |
| linker search path for it. It used to work by accident because the
| |
| <code>-L/path/to</code> would get added as part of the implementation of linking to
| |
| A. The correct code would be
| |
| | |
| link_directories(/path/to)
| |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so B)
| |
| | |
| or even better
| |
| | |
| add_executable(myexe myexe.c)
| |
| target_link_libraries(myexe /path/to/libA.so /path/to/libB.so)
| |
| | |
| In order to support projects that have this bug, we've added a
| |
| compatibility feature that adds the "<code>-L/path/to</code>" paths for all libraries
| |
| linked with full paths even though the linker will not need those paths
| |
| to find the main libraries. The compatibility mode is enabled when a
| |
| link line contains a non-full-path library (like <code>B</code>) and either
| |
| <code>CMAKE_BACKWARDS_COMPATIBILITY</code> is set to 2.4 or lower or
| |
| <code>CMAKE_LINK_OLD_PATHS</code> is set to true.
| |
| | |
| If you are trying to build a project and run into this problem, a quick-fix is to run
| |
| | |
| cmake -DCMAKE_LINK_OLD_PATHS:BOOL=ON .
| |
| | |
| in the top of the build tree.
| |
| | |
| ==Linking to System Libraries==
| |
| | |
| System libraries on UNIX-like systems are typically provided in <code>/usr/lib</code> or <code>/lib</code>. These directories are considered implicit linker search paths because linkers automatically search these locations even without a flag like <code>-L/usr/lib</code>. Consider the code
| |
| | |
| find_library(M_LIB m)
| |
| target_link_libraries(myexe ${M_LIB})
| |
| | |
| Typically the <code>find_library</code> command would find the math library
| |
| | |
| /usr/lib/libm.so
| |
| | |
| In CMake 2.4 and lower this value would be assigned directly to <code>M_LIB</code>. Then the link line generation would split off the link directory <code>/usr/lib</code> and the library <code>libm.so</code> and produce the
| |
| | |
| ... -lm ...
| |
| | |
| Note that the <code>-L/usr/lib</code> option is left out because it is an implicit linker search path. The linker would see <code>-lm</code> and search for the math library. Typically the linker would find /usr/lib/libm.so too. However some platforms provide multiple versions of libraries correesponding to different architectures. For example, on an IRIX machine one might find the libraries
| |
| | |
| /usr/lib/libm.so (ELF o32)
| |
| /usr/lib32/libm.so (ELF n32)
| |
| /usr/lib64/libm.so (ELF 64)
| |
| | |
| On a Solaris machine one might find
| |
| | |
| /usr/lib/libm.so (sparcv8 architecture)
| |
| /usr/lib/sparcv9/libm.so (sparcv9 architecture)
| |
| | |
| When the linker sees <code>-lm</code> it in fact searches the system path corresponding to the current architecture. Internally it might use <code>-L/usr/lib/sparcv9</code> instead of <code>-L/usr/lib</code>.
| |
| | |
| In CMake 2.6 the code
| |
| | |
| target_link_libraries(myexe /usr/lib/libm.so)
| |
| | |
| would generate the link line
| |
| | |
| ... /usr/lib/libm.so ...
| |
| | |
| no matter what architecture is getting linked. This might cause the linker to complain if <code>/usr/lib/libm.so</code> does not match the architecture it wants. This is not a problem with the link line computation. CMake is linking <code>myexe</code> to the library to which it was told to link.
| |
| | |
| The problem is created because <code>find_library</code> may not know about all the architecture-specific system search paths used by the linker. In fact when it finds <code>/usr/lib/libm.so</code> it may be finding a library of incorrect architecture. The solution is for the command to recognize that when it finds a library in a system search path that it should ask the linker to find the correct version of the library at link time. Consider the original example:
| |
| | |
| find_library(M_LIB m)
| |
| target_link_libraries(myexe ${M_LIB})
| |
| | |
| In CMake 2.6 the <code>find_library</code> command will set <code>M_LIB</code> to contain just "<code>libm.so</code>" when it finds <code>/usr/lib/libm.so</code>. The link command will then be
| |
| | |
| target_link_libraries(myexe libm.so)
| |
| | |
| which will be converted to the link command line
| |
| | |
| ... -lm ...
| |
| | |
| and the linker will locate the correct version of the library. If <code>find_library</code> does not find the library in an implicit link directory it will report the full path as usual. The user might also edit the cache to set <code>M_LIB</code> to a full path. In both cases the full path given to target_link_libraries will be preserved on the final link line.
| |