Preprocessor definitions may now be added to builds with much finer
granularity than in previous versions of CMake. There is a new property
called COMPILE_DEFINITIONS 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:
When the add_definitions command is called with flags like "-DX" the
definitions are extracted and added to the current directory's
COMPILE_DEFINITIONS property. When a new subdirectory is created with
add_subdirectory 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 set_property command will actually
set the property and replace any existing value. The command
provides the APPEND 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 "-DD -DDV=4" when building src1.c.
Definitions may also be added on a per-configuration basis using the
COMPILE_DEFINITIONS_ property. For example, the code
This worked most of the time, but some platforms (such as OS X) do not
support the -Bstatic 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
add_executable(myexe myexe.c)target_link_libraries(myexe /path/to/libA.so B)
where "B" is meant to link "/path/to/libB.so". This code is
incorrect because it asks CMake to link to B but does not provide the
proper linker search path for it. It used to work by accident because
the -L/path/to 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)
In order to support projects that have this bug, we've added a
compatibility feature that adds the "-L/path/to" 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
/usr/lib or /lib. These directories are considered implicit linker
search paths because linkers automatically search these locations even
without a flag like -L/usr/lib. Consider the code
Unfortunately find_library may not know about all the
architecture-specific system search paths used by the linker. In fact
when it finds /usr/lib/libm.so 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 /usr/lib/libm.so 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:
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 -l options: not all platforms
have an option like -Bstatic. Fortunately the platforms that do not
provide such flags also tend to not have architecture-specific implicit
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 -l option if a flag like -Bstatic 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
This page was initially populated by conversion from its original location in another wiki.