|
|
(5 intermediate revisions by one other user 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=
| |
| | |
| Please see our tutorial on [[CMake/Tutorials/Exporting_and_Importing_Targets|Exporting and Importing Targets]].
| |
| | |
| =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.
| |
| | |
| '''Note:''' If your project does not already have a <code><prefix>/lib/Foo*/</code> directory you may prefer to put the package file in <code><prefix>/lib/cmake/Foo*/</code> to keep the <code>lib</code> directory clean. However, CMake 2.6.2 and lower do not search there. CMake 2.6.3 and above do.
| |
| | |
| 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 myproj-config.cmake DESTINATION lib/myproj)
| |
| | |
| where <code>myproj-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==
| |
| | |
| The <code>find_package</code> command offers a version request argument. One might write
| |
| | |
| find_package(Foo 1.2)
| |
| find_package(Bar 4.2 EXACT)
| |
| | |
| in order to get a version of package <code>Foo</code> that is compatible with version 1.2 and exactly package <code>Bar</code> version 4.2.
| |
| CMake does not attempt to define any convention for the compatibility or exactness of version numbers for a package.
| |
| It also does not try to map the version number to a directory or file name.
| |
| Instead packages must provide "version" files next to their package configuration files.
| |
| This allows maximum flexibility for project authors and package maintainers.
| |
| | |
| A package version file is placed next to the package configuration file.
| |
| Its name matches that of the configuration file but has either "<code>-version</code>" or "<code>Version</code>" appended to the name before the "<code>.cmake</code>" extension.
| |
| For example, the files
| |
| | |
| <prefix>/lib/foo-1.3/foo-config.cmake
| |
| <prefix>/lib/foo-1.3/foo-config-version.cmake
| |
| | |
| and
| |
| | |
| <prefix>/lib/bar-4.2/BarConfig.cmake
| |
| <prefix>/lib/bar-4.2/BarConfigVersion.cmake
| |
| | |
| are each pairs of package configuration files and corresponding version files.
| |
| When the <code>find_package</code> command finds a candidate package configuration file it looks next to it for a version file.
| |
| The version file is loaded to test whether the package version is an acceptable match for the version requested.
| |
| If the version file claims compatibility the configuration file is accepted. Otherwise it is ignored.
| |
| | |
| When the <code>find_package</code> command loads a version file it first sets the following variables:
| |
| | |
| {| border=1
| |
| ! CMake 2.6.2 and Above !! CMake 2.6.0 and 2.6.1
| |
| |-valign="top"
| |
| |<pre>
| |
| PACKAGE_FIND_NAME = the <package> name
| |
| PACKAGE_FIND_VERSION = full requested version string
| |
| PACKAGE_FIND_VERSION_MAJOR = major version if requested, else 0
| |
| PACKAGE_FIND_VERSION_MINOR = minor version if requested, else 0
| |
| PACKAGE_FIND_VERSION_PATCH = patch version if requested, else 0
| |
| PACKAGE_FIND_VERSION_TWEAK = tweak version if requested, else 0
| |
| PACKAGE_FIND_VERSION_COUNT = number of version components, 0 to 4
| |
| </pre>
| |
| ||<pre>
| |
| PACKAGE_FIND_NAME = the <package> name
| |
| PACKAGE_FIND_VERSION = full requested version string
| |
| PACKAGE_FIND_VERSION_MAJOR = requested major version, if any
| |
| PACKAGE_FIND_VERSION_MINOR = requested minor version, if any
| |
| PACKAGE_FIND_VERSION_PATCH = requested patch version, if any
| |
| </pre>
| |
| |}
| |
| | |
| The version file must use these variables to check whether it is compatible or an exact match for the requested version.
| |
| It sets the following variables with results:
| |
| | |
| PACKAGE_VERSION = full provided version string
| |
| PACKAGE_VERSION_EXACT = true if version is exact match
| |
| PACKAGE_VERSION_COMPATIBLE = true if version is compatible
| |
| PACKAGE_VERSION_UNSUITABLE = true if unsuitable as any version (CMake >= 2.6.3)
| |
| | |
| For example, <code>foo-config-version.cmake</code> might contain
| |
| | |
| set(PACKAGE_VERSION 1.3)
| |
| if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
| |
| set(PACKAGE_VERSION_COMPATIBLE 1) # compatible with any version 1.x
| |
| if("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 3)
| |
| set(PACKAGE_VERSION_EXACT 1) # exact match for version 1.3
| |
| endif("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 3)
| |
| endif("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
| |
| | |
| if it is compatible with all "<code>1.x</code>" versions of Foo and exactly matches version "<code>1.3</code>".
| |
| Note that the input variable names all start in "<code>PACKAGE_FIND_</code>" and the output variable names all start in "<code>PACKAGE_</code>".
| |
| The names are fixed and do not vary with the package name.
| |
| | |
| Version files are loaded in a nested scope so they are free to set any variables they wish as part of their computation.
| |
| The <code>find_package</code> command wipes out the scope when the version file has completed and it has checked the output variables.
| |
| When the version file claims to be an acceptable match for the requested version the <code>find_package</code> command sets the following variables for use by the project:
| |
| | |
| {| border=1
| |
| ! CMake 2.6.2 and Above !! CMake 2.6.0 and 2.6.1
| |
| |-valign="top"
| |
| |<pre>
| |
| <package>_VERSION = full provided version string
| |
| <package>_VERSION_MAJOR = major version if provided, else 0
| |
| <package>_VERSION_MINOR = minor version if provided, else 0
| |
| <package>_VERSION_PATCH = patch version if provided, else 0
| |
| <package>_VERSION_TWEAK = tweak version if provided, else 0
| |
| <package>_VERSION_COUNT = number of version components, 0 to 4
| |
| </pre>
| |
| ||<pre>
| |
| <package>_VERSION = package version (major[.minor[.patch]])
| |
| <package>_VERSION_MAJOR = major from major[.minor[.patch]], if any
| |
| <package>_VERSION_MINOR = minor from major[.minor[.patch]], if any
| |
| <package>_VERSION_PATCH = patch from major[.minor[.patch]], if any
| |
| </pre>
| |
| |}
| |
| | |
| The variables report the version of the package that was actually found.
| |
| The "<code><package></code>" part of their name matches the argument given to the <code>find_package</code> command.
| |
| | |
| =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 that affect compatibility with existing projects (documented in the next two subsections).
| |
| | |
| ==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. See policy CMP0003 for details.
| |
| | |
| ==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
| |
| | |
| Some platforms provide multiple versions of libraries corresponding 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)
| |
| | |
| Unfortunately <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. If the link computation were to produce the line
| |
| | |
| ... /usr/lib/libm.so ...
| |
| | |
| the linker might complain if <code>/usr/lib/libm.so</code> does not match the architecture it wants.
| |
| | |
| One solution to this problem is for the link computation to recognize that the library is in a system directory and ask the linker to search for the library. It could produce the link line
| |
| | |
| ... -lm ...
| |
| | |
| and the linker would search through its architecture-specific implicit link directories to find the correct library. Unfortunately this solution suffers from the original problem of distinguishing between static and shared versions:
| |
| | |
| /usr/lib/libm.a
| |
| /usr/lib/libm.so
| |
| | |
| In order to ask the linker to find the static system library of the correct architecture it must produce the link line
| |
| | |
| ... -Wl,-Bstatic -lm ... -Wl,-Bshared ...
| |
| | |
| This solution directly contradicts the original motivation to give the linker paths to libraries instead of <code>-l</code> options: not all platforms have an option like <code>-Bstatic</code>.
| |
| Fortunately the platforms that do not provide such flags also tend to not have architecture-specific implicit link directories.
| |
| | |
| The solution used by CMake is:
| |
| | |
| * Libraries not in implicit system locations are linked by passing the file path to the linker
| |
| * Libraries in implicit system locations are linked by
| |
| ** passing the <code>-l</code> option if a flag like <code>-Bstatic</code> is available
| |
| ** passing the file path to the linker otherwise
| |
| | |
| Users can override this behavior by using the IMPORTED targets feature:
| |
| | |
| add_library(math STATIC IMPORTED)
| |
| set_property(TARGET math PROPERTY IMPORTED_LOCATION /usr/lib/libm.a)
| |
| add_executable(foo foo.c)
| |
| target_link_libraries(foo math) # will link using full path
| |
| | |
| =CMake Policy Mechanism=
| |
| | |
| CMake 2.6 introduces a new mechanism for backwards compatibility support. See [[CMake Policies]] for more information.
| |