Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • Community Community
  • Project information
    • Project information
    • Activity
    • Members
  • Analytics
    • Analytics
    • Value stream
  • Wiki
    • Wiki
  • Activity
Collapse sidebar
  • CMake
  • CommunityCommunity
  • Wiki
  • FAQ

FAQ · Changes

Page history
Update FAQ using modern syntax authored Mar 05, 2020 by Mike Taves's avatar Mike Taves
Hide whitespace changes
Inline Side-by-side
FAQ.md
View page @ c07a5dcd
......@@ -34,11 +34,11 @@
* [How can I generate a source file during the build?](#how-can-i-generate-a-source-file-during-the-build)
* [How can I add a dependency to a source file which is generated in a subdirectory?](#how-can-i-add-a-dependency-to-a-source-file-which-is-generated-in-a-subdirectory)
* [How can I generate a file used in more than one target in the same directory?](#how-can-i-generate-a-file-used-in-more-than-one-target-in-the-same-directory)
* [I use EXEC_PROGRAM but the result is not set in subdirectories. Why?](#i-use-exec_program-but-the-result-is-not-set-in-subdirectories-why)
* [I use exec_program but the result is not set in subdirectories. Why?](#i-use-exec_program-but-the-result-is-not-set-in-subdirectories-why)
* [How can I get or set environment variables?](#how-can-i-get-or-set-environment-variables)
* [Why do I have unwanted semicolons ; in my compiler flags?](#why-do-i-have-unwanted-semicolons-in-my-compiler-flags)
* [How can I get quoting and escapes to work properly?](#how-can-i-get-quoting-and-escapes-to-work-properly)
* [Isn't the "Expression" in the "ELSE (Expression)" confusing?](#isnt-the-expression-in-the-else-expression-confusing)
* [Isn't the "Expression" in the "else(Expression)" confusing?](#isnt-the-expression-in-the-else-expression-confusing)
* [Which regular expressions are supported by CMake?](#which-regular-expressions-are-supported-by-cmake)
* [How to convert a semicolon separated list to a whitespace separated string?](#how-to-convert-a-semicolon-separated-list-to-a-whitespace-separated-string)
* [How can I build multiple modes without switching ?](#how-can-i-build-multiple-modes-without-switching-)
......@@ -71,7 +71,7 @@
- [Platform-specific questions](#platform-specific-questions)
* [How do I build universal binaries on Mac OS X?](#how-do-i-build-universal-binaries-on-mac-os-x)
* [How can I apply resources on Mac OS X automatically?](#how-can-i-apply-resources-on-mac-os-x-automatically)
* [Why does FIND_LIBRARY not find .DLL libraries under WIN32?](#why-does-find_library-not-find-dll-libraries-under-win32)
* [Why does find_library not find .DLL libraries under WIN32?](#why-does-find_library-not-find-dll-libraries-under-win32)
* [Why am I getting a linker error to _mainCRTStartup under WIN32?](#why-am-i-getting-a-linker-error-to-_maincrtstartup-under-win32)
* [Why do I get this error: nafxcwd.lib(appcore.obj) : error LNK2001: unresolved external symbol ___argv](#why-do-i-get-this-error-nafxcwdlibappcoreobj-error-lnk2001-unresolved-external-symbol-___argv)
* [How to use MFC with CMake](#how-to-use-mfc-with-cmake)
......@@ -147,14 +147,13 @@ released which documents CMake 2.6.
The following features have been added since printing the book:
- New INSTALL command (cmake --help-command INSTALL)
- New LIST command (cmake --help-command LIST)
- Updated FIND_PATH, FIND_PROGRAM, and FIND_FILE commands to be
more powerful (cmake --help-command FIND_PATH)
- RPATH and Mac OS X install_name support (cmake --help-command
SET_TARGET_PROPERTIES)
- New `install` command (`cmake --help-command install`)
- New `list` command (`cmake --help-command list`)
- Updated `find_path`, `find_program`, and `find_file` commands to be
more powerful (`cmake --help-command find_path`)
- RPATH and Mac OS X install_name support (`cmake --help-command set_target_properties`)
- CPack Beta (not finished or documented)
- EXECUTE_PROCESS was added and replaces EXEC_PROGRAM
- `execute_process` was added and replaces `exec_program`
- Other changes have been bug fixes and internal CMake restructuring
### Where can I find searchable CMake Mailing Archives?
......@@ -176,25 +175,29 @@ There exist at least these ones:
### Is there an option to produce more 'verbose' compiling?
On Makefile generators, you can set the Makefile variable VERBOSE to 1.
On Makefile generators, you can set the Makefile variable `VERBOSE` to 1.
For example on UNIX:
```shell
make VERBOSE=1
```
make VERBOSE=1
You can also set CMAKE_VERBOSE_MAKEFILE to ON.
On Windows (nmake) you can override CMAKE_VERBOSE_MAKEFILE by using
You can also set `CMAKE_VERBOSE_MAKEFILE` to ON.
nmake /S
On Windows (nmake) you can override `CMAKE_VERBOSE_MAKEFILE` by using
```
nmake /S
```
On Unix make you can mostly override verbose mode by using
make VERBOSE=""
```shell
make VERBOSE=""
```
If you are on Windows using Borland or NMake Makefiles, you will see
lines like:
cl @c:\DOCUME~1\ANDY~1.KIT\LOCALS~1\Temp\nma03504
```
cl @c:\DOCUME~1\ANDY~1.KIT\LOCALS~1\Temp\nma03504
```
The reason for this is that Borland and Microsoft Visual Studio make
programs have limitation on the length of command strings. They overcome
......@@ -202,12 +205,11 @@ this limitation by writing arguments to the file and then pass file to
the program.
If you actually want to see what the command looks like, set
CMAKE_START_TEMP_FILE and CMAKE_END_TEMP_FILE to "" -- be warned,
`CMAKE_START_TEMP_FILE` and `CMAKE_END_TEMP_FILE` to `""` -- be warned,
however, you cannot set these as variables on the CMake command line
with -D. Instead, see the very bottom of the file
"Modules/Platform/Windows.cmake" and uncomment the lines that set these
variables to the empty
string.
with `-D`. Instead, see the very bottom of the file
`Modules/Platform/Windows.cmake` and uncomment the lines that set these
variables to the empty string.
### Is there a way to skip checking of dependent libraries when compiling?
......@@ -215,22 +217,23 @@ string.
When using the Makefile generator under \*nix you can append "/fast" to
your target name. For example:
make target_name/fast
```shell
make target_name/fast
```
Under Windows use a backslash instead:
make target_name\fast
```
make target_name\fast
```
Be aware that this can cause link errors if the targets that were
skipped are not actually built. Use it only if you know what you're
doing\!
doing!
**Using Visual Studio \>= 7.1**
If you have Visual Studio .NET 7.1 or greater you can use the native
option to right click on a project and choose to build just that
project.
option to right click on a project and choose to build just that project.
**Using Visual Studio \<= 7.0**
......@@ -240,8 +243,7 @@ however you can take advantage of CTRL+F7 to manually compile a source
file for the affected target and then relink the target by right
clicking on it and choosing Link. You'll have to ensure that all
dependent libraries are made up-to-date however or suffer through
Visual's slow
check.
Visual's slow check.
### I set a cmake variable in my environment, but it didn't change anything. Why?
......@@ -261,34 +263,35 @@ For C and C++, set the `CC` and `CXX` environment variables. This method
is not guaranteed to work for all generators. (Specifically, if you are
trying to set Xcode's `GCC_VERSION`, this method confuses Xcode.)
For
example:
CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source
For example:
```shell
CC=gcc-4.2 CXX=/usr/bin/g++-4.2 cmake -G "Your Generator" path/to/your/source
```
#### Method 2: use cmake -D
Set the appropriate `CMAKE_FOO_COMPILER` variable(s) to a valid compiler
name or full path on the command-line using `cmake -D`.
For
example:
cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source
For example:
```shell
cmake -G "Your Generator" -D CMAKE_C_COMPILER=gcc-4.2 -D CMAKE_CXX_COMPILER=g++-4.2 path/to/your/source
```
#### Method 3 (avoid): use set()
Set the appropriate `CMAKE_FOO_COMPILER` variable(s) to a valid compiler
name or full path in a list file using `set()`. This must be done
*before* any language is set (ie before any `project()` or
*before* any language is set(ie before any `project()` or
`enable_language()` command).
For example:
```cmake
set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")
set(CMAKE_C_COMPILER "gcc-4.2")
set(CMAKE_CXX_COMPILER "/usr/bin/g++-4.2")
project("YourProjectName")
project("YourProjectName")
```
### I change CMAKE_C_COMPILER in the GUI but it changes back on the next configure step. Why?
......@@ -304,12 +307,13 @@ some existing path. If that is possible, it will do it. If not, it will
not do anything.
For example:
/usr/loc<TAB>
```
/usr/loc<TAB>
```
will expand to
/usr/local/
```
/usr/local/
```
## Out-of-source build trees
......@@ -322,18 +326,22 @@ a completely separate directory, so that your source tree is unchanged.
In the first example, an in-place build is performed, i.e., the binaries
are placed in the same directory as the source code.
cd Hello
ccmake .
make
```shell
cd Hello
ccmake .
make
```
In the second example, an out-of-place build is performed, i.e., the
source code, libraries, and executables are produced in a directory
separate from the source code directory(ies).
mkdir HelloBuild
cd HelloBuild
ccmake ../Hello
make
```shell
mkdir HelloBuild
cd HelloBuild
ccmake ../Hello
make
```
Out-of-source builds are recommended, as you can build multiple variants
in separate directories, e.g., HelloBuildDebug, HelloBuildRelease.
......@@ -348,11 +356,11 @@ CMakeCache.txt.
This means that there is a CMakeCache.txt file in the source tree,
possibly as part of an existing in-source build. If CMake is given the
path to a directory with a CMakeCache.txt file, it assumes the directory
is a build tree. Therefore if one runs "cmake ../mysrc" to build
is a build tree. Therefore if one runs `cmake ../mysrc` to build
out-of-source but there is a mysrc/CMakeCache.txt file then cmake will
treat mysrc as the build tree.
This is a side-effect of the feature that allows "cmake ." to be used to
This is a side-effect of the feature that allows `cmake .` to be used to
regenerate a build tree. The behavior will not be changed because mixing
in-source and out-of-source builds is not safe anyway (configured
headers may be found in the wrong place).
......@@ -386,17 +394,17 @@ the old one.
### CMake does not generate a "make distclean" target. Why?
Some build trees created with GNU autotools have a "make distclean"
Some build trees created with GNU autotools have a `make distclean`
target that cleans the build and also removes Makefiles and other parts
of the generated build system. CMake does not generate a "make
distclean" target because CMakeLists.txt files can run scripts and
of the generated build system. CMake does not generate a `make distclean`
target because CMakeLists.txt files can run scripts and
arbitrary commands; CMake has no way of tracking exactly which files are
generated as part of running CMake. Providing a distclean target would
give users the false impression that it would work as expected. (CMake
does generate a "make clean" target to remove files generated by the
does generate a `make clean` target to remove files generated by the
compiler and linker.)
A "make distclean" target is only necessary if the user performs an
A `make distclean` target is only necessary if the user performs an
in-source build. CMake supports in-source builds, but we strongly
encourage users to adopt the notion of an out-of-source build. Using a
build tree that is separate from the source tree will prevent CMake from
......@@ -405,9 +413,9 @@ the source tree, there is no need for a distclean target. One can start
a fresh build by deleting the build tree or creating a separate build
tree.
(If a CMakeLists.txt uses ADD_CUSTOM_COMMAND to generate source files
(If a CMakeLists.txt uses `add_custom_command` to generate source files
in the source tree, not the build tree, then in CMake 2.2 or higher
"make clean" will remove them. See next question.)
`make clean` will remove them. See next question.)
### Running "make clean" does not remove custom command outputs. Why?
......@@ -415,12 +423,12 @@ In CMake 2.2 and higher custom command outputs should be removed by make
clean. Make sure you are using at least this version. Prior to CMake 2.2
custom command outputs were not automatically added to the list of files
to clean. In CMake 2.0 the developer can specify a list of files to be
deleted. This can be done using SET_DIRECTORY_PROPERTIES setting
property ADDITIONAL_MAKE_CLEAN_FILES to the list of files.
deleted. This can be done using `set_directory_properties` setting
property `ADDITIONAL_MAKE_CLEAN_FILES` to the list of files.
We however strongly recommend using an "out-of-source" build which never
writes any files to the source tree. Using a separate source and build
tree greatly reduces the need for "make clean" and "make distclean"
tree greatly reduces the need for `make clean` and `make distclean`
targets to clean away files that differ between builds.
## Writing CMakeLists.txt
......@@ -430,9 +438,9 @@ targets to clean away files that differ between builds.
As of CMake 2.6 we employ a "Policy" mechanism to provide backwards
compatibility. The basic requirement for projects is to include one line
at the top of the highest CMakeLists.txt file:
cmake_minimum_required(VERSION 2.6) # or other version
```cmake
cmake_minimum_required(VERSION 2.6) # or other version
```
This tells versions of CMake older than that specified that they are too
old to build the project. They will report this information to the user.
It also tells versions of CMake newer than that specified that the
......@@ -447,10 +455,9 @@ enables additional compatibility. For futher documentation, see
### How do I get the current source or binary directory?
The variable CMAKE_CURRENT_SOURCE_DIR contains the absolute path to
your current source directory, while CMAKE_CURRENT_BINARY_DIR points
to the equivalent binary
directory.
The variable `CMAKE_CURRENT_SOURCE_DIR` contains the absolute path to
your current source directory, while `CMAKE_CURRENT_BINARY_DIR` points
to the equivalent binary directory.
### Why are my CMake variables not updated in the GUI after a SET command?
......@@ -459,91 +466,94 @@ used to initialize the values seen by the code in CMakeLists.txt files.
Changes made by the code are used during the configure step and seen by
the generators but are not stored back into the cache. For example:
SET(BUILD_SHARED_LIBS ON)
```cmake
set(BUILD_SHARED_LIBS ON)
```
will turn on building of shared libraries for the directory containing
the command and all subdirectories, but the change will not appear in
the GUI.
You can use the CACHE and FORCE options on the SET command to change
You can use the CACHE and FORCE options on the `set` command to change
variables in a way that will be reflected in the GUI. Run
cmake --help-command SET
to see full instructions for the
command.
```shell
cmake --help-command set
```
to see full instructions for the command.
### How can I change the default build mode and see it reflected in the GUI?
Adapt the following commands in your CMakeLists.txt (this example sets
the Release With Debug Information mode):
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
```cmake
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
endif()
```
### How do I generate an executable, then use the executable to generate a file?
Create the generator executable by just adding a target:
ADD_EXECUTABLE(generate generate.c)
```cmake
add_executable(generate generate.c)
```
The rest of the process is simpler in CMake 2.6 and above than in
previous versions.
Use `ADD_CUSTOM_COMMAND` to specify a custom build rule for the file.
Use `add_custom_command` to specify a custom build rule for the file.
(In this example we assume `generate` accepts the input and output files
as arguments.)
ADD_CUSTOM_COMMAND(
OUTPUT someoutput.txt
COMMAND generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt
)
```cmake
add_custom_command(
OUTPUT someoutput.txt
COMMAND generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
DEPENDS generate ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt
)
```
This tells CMake how to build the file but does not actually add a rule
to the build system. Another target must require it. One may create a
custom target explicitly for this rule:
ADD_CUSTOM_TARGET(driver ALL DEPENDS someoutput.txt)
```cmake
add_custom_target(driver ALL DEPENDS someoutput.txt)
```
or the file may be added as part of some other target:
```cmake
add_executable(product product.c someoutput.txt)
```
ADD_EXECUTABLE(product product.c someoutput.txt)
<font color=#555555> In CMake 2.4 and below the `generate` target may
In CMake 2.4 and below the `generate` target may
not be specified directly in the `COMMAND` option of
`add_custom_command` (but it can still be used in the `DEPENDS` option
as of CMake 2.4). Instead use GET_TARGET_PROPERTY to obtain the
as of CMake 2.4). Instead use `get_target_property` to obtain the
location of the generated executable. Additionally, the output must
always be specified by full path.
GET_TARGET_PROPERTY(GENERATE_EXE generate LOCATION)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
COMMAND ${GENERATE_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
DEPENDS generate
)
</font>
```cmake
get_target_property(GENERATE_EXE generate LOCATION)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
COMMAND ${GENERATE_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/someinput.txt ${CMAKE_CURRENT_BINARY_DIR}/someoutput.txt
DEPENDS generate
)
```
### How can I generate a source file during the build?
The ADD_CUSTOM_COMMAND command lets you generate a source file that
The `add_custom_command` command lets you generate a source file that
you can then include in another target. For example:
```cmake
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c
)
add_executable(foo foo.c)
```
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c
)
ADD_EXECUTABLE(foo foo.c)
This will create an executable by copying bar.c to foo.c and then
compiling foo.c to produce foo. CMake allows you to put generated source
This will create an executable by copying "bar.c" to "foo.c" and then
compiling "foo.c" to produce "foo". CMake allows you to put generated source
files in the current source or binary directory, so we were careful to
output foo.c to the current binary directory. When we add foo.c to foo,
CMake will look in either directory for it. Even if foo.c does not yet
......@@ -551,7 +561,7 @@ exist, CMake is smart enough to notice that a custom command creates it.
(For the file named as the OUTPUT, CMake has its GENERATED source file
property set to true.)
You can also use ADD_CUSTOM_COMMAND when the [generator command is
You can also use `add_custom_command` when the [generator command is
another executable in the same
project](FAQ#how-do-i-generate-an-executable-then-use-the-executable-to-generate-a-file "wikilink").
......@@ -562,75 +572,78 @@ example, suppose you had a program that read input.txt and generated
three files output1.cpp, output2.h, and output3.cpp, and that those
three files needed to be compiled into an executable program. The cmake
list file for that would look like this:
PROJECT(FOO)
# make sure cmake addes the binary directory for the project to the include path
INCLUDE_DIRECTORIES(${FOO_BINARY_DIR})
# add the executable that will do the generation
ADD_EXECUTABLE(my_generator my_generator.cxx)
GET_TARGET_PROPERTY(MY_GENERATOR_EXE my_generator LOCATION)
# add the custom command that will generate all three files
ADD_CUSTOM_COMMAND(
OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp
COMMAND ${MY_GENERATOR_EXE} ${FOO_BINARY_DIR} ${FOO_SOURCE_DIR}/input.txt
DEPENDS my_generator
MAIN_DEPENDENCY ${FOO_SOURCE_DIR}/input.txt
)
# now create an executable using the generated files
ADD_EXECUTABLE(generated
${FOO_BINARY_DIR}/output1.cpp
${FOO_BINARY_DIR}/output2.h
${FOO_BINARY_DIR}/output3.cpp)
```cmake
project(FOO)
# make sure cmake addes the binary directory for the project to the include path
include_directories(${FOO_BINARY_DIR})
# add the executable that will do the generation
add_executable(my_generator my_generator.cxx)
get_target_property(MY_GENERATOR_EXE my_generator LOCATION)
# add the custom command that will generate all three files
add_custom_command(
OUTPUT ${FOO_BINARY_DIR}/output1.cpp ${FOO_BINARY_DIR}/output2.h ${FOO_BINARY_DIR}/output3.cpp
COMMAND ${MY_GENERATOR_EXE} ${FOO_BINARY_DIR} ${FOO_SOURCE_DIR}/input.txt
DEPENDS my_generator
MAIN_DEPENDENCY ${FOO_SOURCE_DIR}/input.txt
)
# now create an executable using the generated files
add_executable(generated
${FOO_BINARY_DIR}/output1.cpp
${FOO_BINARY_DIR}/output2.h
${FOO_BINARY_DIR}/output3.cpp)
```
CMake 2.4 allows you to generate a header file. Because generated
headers often cause unnecessary rebuilds, you should try to avoid them;
consider using the CONFIGURE_FILE command to prepare the header at
consider using the `configure_file` command to prepare the header at
CMake time. If you must generate a header file, use code like this:
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.h ${CMAKE_CURRENT_BINARY_DIR}/foo.h
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.h
)
ADD_EXECUTABLE(foo foo.c ${CMAKE_CURRENT_BINARY_DIR}/foo.h)
```cmake
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.h
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.h ${CMAKE_CURRENT_BINARY_DIR}/foo.h
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.h
)
add_executable(foo foo.c ${CMAKE_CURRENT_BINARY_DIR}/foo.h)
```
This is like the first example above, except that it generates a header
instead of a C file. The header might not exist when the build system
scans foo.c's dependencies, so there is no way for CMake to know that
this target requires foo.h unless we can tell it that foo.h may exist in
scans dependencies for "foo.c", so there is no way for CMake to know that
this target requires "foo.h" unless we can tell it that "foo.h" may exist in
the future. We give CMake this knowledge by listing the generated header
file in the set of source files for the target. (This requires CMake
2.4. Previous versions of CMake required use of the OBJECT_DEPENDS
source file
property.)
2.4. Previous versions of CMake required use of the `OBJECT_DEPENDS`
source file property.)
### How can I add a dependency to a source file which is generated in a subdirectory?
Rules created with `ADD_CUSTOM_COMMAND` as
Rules created with `add_custom_command` as
[above](FAQ#how-can-i-generate-a-source-file-during-the-build "wikilink")
have scope only in the directory in which they are specified. If the
generated file is needed in another directory, a target-level dependency
needs to be added. Create a target in the subdirectory with the custom
rule in order to drive it:
# subdir/CMakeLists.txt
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c
)
ADD_CUSTOM_TARGET(generate_foo DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.c)
```cmake
# subdir/CMakeLists.txt
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/foo.c
COMMAND ${CMAKE_COMMAND} copy ${CMAKE_CURRENT_SOURCE_DIR}/bar.c ${CMAKE_CURRENT_BINARY_DIR}/foo.c
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bar.c
)
add_custom_target(generate_foo DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/foo.c)
```
Now other targets can depend on the target from the subdirectory:
# CMakeLists.txt
ADD_SUBDIRECTORY(subdir)
# Create the executable.
ADD_EXECUTABLE(generated ${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c)
# Tell CMake the source won't be available until build time.
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c PROPERTIES GENERATED 1)
# Make sure the source is generated before the executable builds.
ADD_DEPENDENCIES(generated generate_foo)
```cmake
# CMakeLists.txt
add_subdirectory(subdir)
# Create the executable.
add_executable(generated ${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c)
# Tell CMake the source won't be available until build time.
set_source_file_properties(${CMAKE_CURRENT_BINARY_DIR}/subdir/foo.c PROPERTIES GENERATED 1)
# Make sure the source is generated before the executable builds.
add_dependencies(generated generate_foo)
```
### How can I generate a file used in more than one target in the same directory?
......@@ -640,62 +653,67 @@ There is no other place to put it. If a single custom command output is
listed in more than one target and the targets have no dependency
relationship they will race to run the custom command during a parallel
build and possibly clobber each other. For example:
add_custom_command(OUTPUT Foo.c COMMAND ... DEPENDS ...)
add_library(FooStatic STATIC Foo.c)
add_library(FooShared SHARED Foo.c)
```cmake
add_custom_command(OUTPUT Foo.c COMMAND ... DEPENDS ...)
add_library(FooStatic STATIC Foo.c)
add_library(FooShared SHARED Foo.c)
```
There are at least two solutions to this problem. First, one may use
add_dependencies to serialize the targets involved:
add_dependencies(FooShared FooStatic)
```cmake
add_dependencies(FooShared FooStatic)
```
Second, one may add a custom target dedicated to generating files for
the other targets:
add_custom_target(Foo DEPENDS Foo.c)
add_dependencies(FooStatic Foo)
add_dependencies(FooShared Foo)
```cmake
add_custom_target(Foo DEPENDS Foo.c)
add_dependencies(FooStatic Foo)
add_dependencies(FooShared Foo)
```
The latter solution ensures that generated files are up to date before
any of the independent targets build so none of them will run the custom
command and there will be no
race.
command and there will be no race.
### I use EXEC_PROGRAM but the result is not set in subdirectories. Why?
### I use exec_program but the result is not set in subdirectories. Why?
An unfortunate holdover from ancient CMake versions is that certain
commands are "inherited" into subdirectories and others are not.
EXEC_PROGRAM is not inherited. What this means is that when the
`exec_program` is not inherited. What this means is that when the
listfile code from a parent directory executes in a subdirectory the
EXEC_PROGRAM command is left out. Therefore the code executes
`exec_program` command is left out. Therefore the code executes
differently. This problem was fixed in CMake 2.2, but for older versions
you will have to cache the result:
EXEC_PROGRAM(my-program OUTPUT_VARIABLE MY_OUTPUT)
SET(MY_OUTPUT "${MY_OUTPUT}" CACHE INTERNAL "")
```cmake
exec_program(my-program OUTPUT_VARIABLE MY_OUTPUT)
set(MY_OUTPUT "${MY_OUTPUT}" CACHE INTERNAL "")
```
This will store the result in a global location so it will be available
in the subdirectory. Be sure to choose a descriptive name for MY_OUTPUT
in the subdirectory. Be sure to choose a descriptive name for `MY_OUTPUT`
to avoid conflict in the global setting.
### How can I get or set environment variables?
CMake names environment variables using an ENV prefix and surrounding
the names in curly braces. Here is an example:
MESSAGE("$ENV{PATH}")
```cmake
message("$ENV{PATH}")
```
Reading variables will work in any version of CMake. Writing to them
works in CMake 2.2 and higher using the following syntax:
SET(ENV{HELLO} "World")
```cmake
set(ENV{HELLO} "World")
```
Note that there is currently no way to tell apart an empty environment
variable value from a variable that is not set at all.
One should avoid using environment variables for controlling the flow of
CMake code (such as in IF commands). The build system generated by CMake
CMake code (such as in `if` commands). The build system generated by CMake
may re-run CMake automatically when CMakeLists.txt files change. The
environment in which this is executed is controlled by the build system
and may not match that in which CMake was originally run. If you want to
......@@ -704,7 +722,7 @@ variables set with the -D option. The settings will be saved in
CMakeCache.txt so that they don't have to be repeated every time CMake
is run on the same build tree.
Also, environment variables SET in the CMakeLists.txt *only* take effect
Also, environment variables `set` in the CMakeLists.txt *only* take effect
for cmake itself (*configure-time*), so you cannot use this method to
set an environment variable that a custom command might need
(*build-time*). Barring environment variable support by various CMake
......@@ -716,7 +734,7 @@ the commands to be executed.
CMake has a list data type. A list is stored as a string of
semicolon-separated list elements. Whitespace separated arguments to a
SET statement are interpreted as list elements. For instance,
`set` statement are interpreted as list elements. For instance,
```cmake
set(var a b c d e)
......@@ -736,51 +754,52 @@ See the [cmake-language(7)](https://cmake.org/cmake/help/latest/manual/cmake-lan
### How can I get quoting and escapes to work properly?
If you want to escape a character in CMake, you use "\\", like in C
If you want to escape a character in CMake, you use `\`, like in C
code. For example, if you wanted to have a quote embedded in a string
you would do this: "\\"". However, each level of CMake that processes
you would do this: `\"`. However, each level of CMake that processes
your code will need one level of escaping to work. So, if you configure
a file that is read by cmake or cpack and you want to do the same thing,
you would do "\\\\\\"". You would still need to escape the " for the
you would do `\\\"`. You would still need to escape the `"` for the
first cmake that processes the string. However, this time, you would
want to also escape a '\\' as well. This would leave the next level of
processing with "\\"". Also, for custom commands that may get passed to
want to also escape a `\` as well. This would leave the next level of
processing with `\"`. Also, for custom commands that may get passed to
a shell, it maybe required to do escaping for that shell.
### Isn't the "Expression" in the "ELSE (Expression)" confusing?
### Isn't the "Expression" in the "else(Expression)" confusing?
Traditional CMakeLists.txt files prior to 2.6.0, require the following
syntax. In the IF syntax, the ELSE section requires the same
(Expression) as the IF section. This sometimes can make the script kind
syntax. In the `if` syntax, the `else` section requires the same
(Expression) as the `if` section. This sometimes can make the script kind
of hard to follow, take the short example below:
IF(WIN32)
...do something...
ELSE(WIN32)
...do something else...
ENDIF(WIN32)
You might think that the ELSE section, here containing "...do something
```cmake
if(WIN32)
...do something...
else(WIN32)
...do something else...
endif(WIN32)
```
You might think that the `else` section, here containing "...do something
else...", is for the WIN32 portion of the script. That is not so\! It is
actually handling the NOT WIN32 section.
As of CMake 2.6.0 the ELSE() and ENDIF() constructs can be empty. The
same is true for closing constructs on ENDMACRO(), ENDFUNCTION(), and
ENDFOREACH(). If you require 2.4.x compatibility, CMake 2.4.3 or greater
recognizes the CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS option (which is
As of CMake 2.6.0 the `else()` and `endif()` constructs can be empty. The
same is true for closing constructs on `endmacro()`, `endfunction()`, and
`endforeach()`. If you require 2.4.x compatibility, CMake 2.4.3 or greater
recognizes the `CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS` option (which is
superfluous in 2.6.0)
```
cmake_minimum_required(VERSION 2.4.3)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
if(WIN32)
...do something...
elseif(APPLE)
...do something else...
else()
...do something else...
endif()
```cmake
cmake_minimum_required(VERSION 2.4.3)
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
if(WIN32)
...do something...
elseif(APPLE)
...do something else...
else()
...do something else...
endif()
```
### Which regular expressions are supported by CMake?
......@@ -789,78 +808,80 @@ superfluous in 2.6.0)
source at
[Source/kwsys/RegularExpression.hxx.in](http://www.cmake.org/cgi-bin/viewcvs.cgi/Source/kwsys/RegularExpression.hxx.in?root=CMake&view=markup))
When using MATCHES or MATCHALL in an IF command, or using any of the
STRING(REGEX ...) commands, CMake expects regular expressions, not globs
When using `MATCHES` or `MATCHALL` in an `if` command, or using any of the
`string(REGEX ...)` commands, CMake expects regular expressions, not globs
(wild cards). CMake uses the same regular expression engine above all
platforms. Here are the meanings of the metacharacters:
^ Matches at beginning of a line
$ Matches at end of a line
. Matches any single character
[ ] Matches any character(s) inside the brackets
[^ ] Matches any character(s) not inside the brackets
- Matches any character in range on either side of a dash
| Matches a pattern on either side of the |
* Matches preceding pattern zero or more times
+ Matches preceding pattern one or more times
? Matches preceding pattern zero or once only
() Saves a matched expression and uses it in a later match
Example: "\[-\]\[L\](\[^ ;\])+" matches all strings beginning with -L
- `^` Matches at beginning of a line
- `$` Matches at end of a line
- `.` Matches any single character
- `[`...`]` Matches any character(s) inside the brackets
- `[^`...`]` Matches any character(s) not inside the brackets
- `-` Matches any character in range on either side of a dash
- `|` Matches a pattern on either side of the `|`
- `*` Matches preceding pattern zero or more times
- `+` Matches preceding pattern one or more times
- `?` Matches preceding pattern zero or once only
- `(`...`)` Saves a matched expression and uses it in a later match
Example: `\[-\]\[L\](\[^ ;\])+` matches all strings beginning with `-L`
and ending with a space or a semicolon, the usual linkdirs under Linux.
Here is how to catch a part of a string. The variable test is filled
with some content, and then we want to catch the "me":
SET(test "hello world ! catch: me if you can")
STRING(REGEX REPLACE ".*catch: ([^ ]+).*" "\\1" result "${test}" )
MESSAGE(STATUS "result= ${result}")
```cmake
set(test "hello world ! catch: me if you can")
string(REGEX REPLACE ".*catch: ([^ ]+).*" "\\1" result "${test}" )
message(STATUS "result= ${result}")
```
This is slightly tricky. The part inside the brackets is available in
\\\\1 . CMake will copy the variable test to the variable result, but
`\\1` . CMake will copy the variable test to the variable result, but
then it will replace everything that the regular expression matches with
\\\\1. This means the first regular expression has to match the whole
`\\1`. This means the first regular expression has to match the whole
string and the part we want to catch has to be put in parens.
-- result= me
For those of you who know Perl, the equivalent Perl code could be:
$test = "hello world ! catch: me if you can";
$result = $test;
$result =~ s/.*catch: ([^ ]+).*/$1/;
print "-- result= $result\n";
```perl
$test = "hello world ! catch: me if you can";
$result = $test;
$result =~ s/.*catch: ([^ ]+).*/$1/;
print "-- result= $result\n";
```
There are other ways to do this in Perl, but this is how we do it in
CMake because \\\\1 does not become a variable like $1 does in perl, so
there is no SET(result ${\\\\1}) in CMake.
CMake because `\1` does not become a variable like `$1` does in Perl, so
there is no `set(result ${\1})` in CMake.
Not sure whether CMake regex implementation supports modifiers for case
insensitive matching, thus if this is needed it's perhaps best to do
matches on a result of string(TOLOWER
...).
matches on a result of `string(TOLOWER ...)`.
### How to convert a semicolon separated list to a whitespace separated string?
set(foo
abc.c
abc.b
abc.a
)
foreach(arg ${foo})
set(bar "${bar} ${arg}")
endforeach(arg ${foo})
message("foo: ${foo}")
message("bar: ${bar}")
```cmake
set(foo
abc.c
abc.b
abc.a
)
foreach(arg ${foo})
set(bar "${bar} ${arg}")
endforeach(arg ${foo})
message("foo: ${foo}")
message("bar: ${bar}")
```
### How can I build multiple modes without switching ?
To build multiple modes (e.g. Debug and Release) in one shot without
constantly running cmake -DCMAKE_BUILD_TYPE=Debug and cmake
-DCMAKE_BUILD_TYPE=Release in source tree create a directory for
builds eg.:
constantly running `cmake -DCMAKE_BUILD_TYPE=Debug` and
`cmake -DCMAKE_BUILD_TYPE=Release` in source tree create a directory for
builds, e.g.:
Project-directory/
/Build
......@@ -875,14 +896,13 @@ modes as you want, e.g.:
In each of these directories issue a command (assuming that you have
CMakeLists.txt directly in Project-directory)
cmake -DCMAKE_BUILD_TYPE=type_of_build ../../
```shell
cmake -DCMAKE_BUILD_TYPE=type_of_build ../../
```
to create a cmake cache configured for requested build type.
Now you can make each build just by entering appropriate directory and
executing a make
command.
executing a make command.
### How can I specify my own configurations (for generators that allow it) ?
......@@ -890,62 +910,67 @@ For generators that allow it (like Visual Studio), CMake generates four
configurations by default: Debug, Release, MinSizeRel and
RelWithDebInfo. Many people just need Debug and Release, or need other
configurations. To modify this, you need to change the variable
CMAKE_CONFIGURATION_TYPES in the cache:
`CMAKE_CONFIGURATION_TYPES` in the cache:
if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Debug Release DebugMX31 ReleaseMX31)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to what we need"
FORCE)
endif()
```cmake
if(CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Debug Release DebugMX31 ReleaseMX31)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Reset the configurations to what we need"
FORCE)
endif()
```
Note that the first line checks whether the generator supports multiple
configurations.
If you just want to add your own configurations while keeping the
default ones, you can use list operations:
if(CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES SuperDuper)
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Add the configurations that we need"
FORCE)
endif()
```cmake
if(CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES SuperDuper)
list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
"Add the configurations that we need"
FORCE)
endif()
```
### How can I extend the build modes with a custom made one ?
The following code snippet (taken from a CMakeLists.txt) adds a
Maintainer mode:
SET( CMAKE_CXX_FLAGS_MAINTAINER "-Wall -Wabi" CACHE STRING
"Flags used by the C++ compiler during maintainer builds."
FORCE )
SET( CMAKE_C_FLAGS_MAINTAINER "-Wall -pedantic" CACHE STRING
"Flags used by the C compiler during maintainer builds."
FORCE )
SET( CMAKE_EXE_LINKER_FLAGS_MAINTAINER
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
"Flags used for linking binaries during maintainer builds."
FORCE )
SET( CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
"Flags used by the shared libraries linker during maintainer builds."
FORCE )
MARK_AS_ADVANCED(
CMAKE_CXX_FLAGS_MAINTAINER
CMAKE_C_FLAGS_MAINTAINER
CMAKE_EXE_LINKER_FLAGS_MAINTAINER
CMAKE_SHARED_LINKER_FLAGS_MAINTAINER )
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs
SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Maintainer."
FORCE )
"Maintainer" mode:
```cmake
set(CMAKE_CXX_FLAGS_MAINTAINER "-Wall -Wabi" CACHE STRING
"Flags used by the C++ compiler during maintainer builds."
FORCE)
set(CMAKE_C_FLAGS_MAINTAINER "-Wall -pedantic" CACHE STRING
"Flags used by the C compiler during maintainer builds."
FORCE)
set(CMAKE_EXE_LINKER_FLAGS_MAINTAINER
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
"Flags used for linking binaries during maintainer builds."
FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_MAINTAINER
"-Wl,--warn-unresolved-symbols,--warn-once" CACHE STRING
"Flags used by the shared libraries linker during maintainer builds."
FORCE)
mark_as_advanced(
CMAKE_CXX_FLAGS_MAINTAINER
CMAKE_C_FLAGS_MAINTAINER
CMAKE_EXE_LINKER_FLAGS_MAINTAINER
CMAKE_SHARED_LINKER_FLAGS_MAINTAINER)
# Update the documentation string of CMAKE_BUILD_TYPE for GUIs
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Maintainer."
FORCE)
```
Notes: The flags used in this example are specific to GCC. Change them
as needed for your project. Additionally the SET(CMAKE_BUILD_TYPE)
command will override a CMAKE_BUILD_TYPE previously set in the
CMakeLists.txt. A simple "SET(CMAKE_BUILD_TYPE)" does silently
as needed for your project. Additionally the `set(CMAKE_BUILD_TYPE)`
command will override a `CMAKE_BUILD_TYPE` previously set in the
CMakeLists.txt. A simple `set(CMAKE_BUILD_TYPE)` does silently
overwrite, the change is only visible in the GUI if "CACHE" is set when
overriding.
......@@ -953,21 +978,23 @@ overriding.
The code in question is of the form
set(var "a;b;;c;d") # list 'a', 'b', '', 'c', 'd'
foreach(v ${var})
# v=a, v=b, v=c, v=d, one at a time
endforeach()
and the loop variable 'v' never attains the empty-string value ''. This
```cmake
set(var "a;b;;c;d") # list 'a', 'b', '', 'c', 'd'
foreach(v ${var})
# v=a, v=b, v=c, v=d, one at a time
endforeach()
```
and the loop variable `v` never attains the empty-string value `''`. This
is because the `${var}` syntax is an unquoted argument so the CMake
language expands the list and removes the empty value. The foreach
command does not even see the empty value. One can verify this because
the code
foreach(v a b "" c d)
...
endforeach()
```cmake
foreach(v a b "" c d)
...
endforeach()
```
will see the empty value.
### Does CMake support precompiled headers?
......@@ -993,12 +1020,13 @@ repository.
### Why does find_library look in system directories before its PATHS option?
The code in question is often of the form
```cmake
find_library(FOO_LIBRARY NAMES foo PATHS /opt/foo/lib)
```
find_library(FOO_LIBRARY NAMES foo PATHS /opt/foo/lib)
CMake will find "`/usr/lib/libfoo.so`" instead of
"`/opt/foo/lib/libfoo.so`" if both exist. The reason is that
/opt/foo/lib is a <i>hard-coded guess</i> of the location. The
CMake will find `/usr/lib/libfoo.so` instead of
`/opt/foo/lib/libfoo.so` if both exist. The reason is that
`/opt/foo/lib` is a *hard-coded guess* of the location. The
documentation of
[`find_library`](http://www.cmake.org/cmake/help/cmake2.6docs.html#command:find_library)
specifies the search order. User, project, and system configuration
......@@ -1006,15 +1034,16 @@ variables are always more local than hard-coded guesses and should
override them, so the PATHS option is used last.
Some find-modules compute probable locations based on other information
<i>available from the system</i> such as a project-specific environment
*available from the system* such as a project-specific environment
variable. The HINTS option (CMake 2.6 and higher) takes precedence over
system directories specifically for this case:
```cmake
file(TO_CMAKE_PATH "$ENV{FOO_LIB_DIR}" FOO_LIB_DIR)
find_library(FOO_LIBRARY NAMES foo HINTS ${FOO_LIB_DIR})
```
file(TO_CMAKE_PATH "$ENV{FOO_LIB_DIR}" FOO_LIB_DIR)
find_library(FOO_LIBRARY NAMES foo HINTS ${FOO_LIB_DIR})
CMake will find "`$ENV{FOO_LIB_DIR}/libfoo.so`" before
"`/usr/lib/libfoo.so`".
CMake will find `$ENV{FOO_LIB_DIR}/libfoo.so` before
`/usr/lib/libfoo.so`.
## Finding and using external packages
......@@ -1022,54 +1051,56 @@ CMake will find "`$ENV{FOO_LIB_DIR}/libfoo.so`" before
CMake version 2 includes a module that supports the generation of SWIG
wrapper libraries. The SWIG package defines the following macros:
SWIG_ADD_MODULE and SWIG_LINK_LIBRARIES.
`swig_add_module` and `swig_link_libraries`.
# This example shows how to use python
# Currently these languages have been tested:
# perl tcl ruby php4 pike
```cmake
# This example shows how to use python
# Currently these languages have been tested:
# perl tcl ruby php4 pike
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "")
set(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(example python
example.i example.cxx)
SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})
set_source_file_properties(example.i PROPERTIES CPLUSPLUS ON)
set_source_file_properties(example.i PROPERTIES SWIG_FLAGS "-includeall")
swig_add_module(example python
example.i example.cxx)
swig_link_libraries(example ${PYTHON_LIBRARIES})
# This example shows how to use tcl
PROJECT(TCL_WRAP)
SET ( MODULE_NAME project )
SET ( INTERFACE_FILES project.i)
SET ( SRC_FILES Vertex.h Vertex.cxx Shapes.h Shapes.cxx )
# This example shows how to use tcl
project(TCL_WRAP)
set(MODULE_NAME project)
set(INTERFACE_FILES project.i)
set(SRC_FILES Vertex.h Vertex.cxx Shapes.h Shapes.cxx)
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# Look for TCL
INCLUDE_DIRECTORIES(${TCL_INCLUDE_PATH})
# Look for TCL
include_directories(${TCL_INCLUDE_PATH})
FIND_LIBRARY(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80
PATHS /usr/lib /usr/local/lib)
IF (TCL_LIBRARY)
TARGET_ADD_LIBRARY (${MODULE_NAME} TCL_LIBRARY)
ENDIF (TCL_LIBRARY)
find_library(TCL_LIBRARY NAMES tcl tcl84 tcl83 tcl82 tcl80
PATHS /usr/lib /usr/local/lib)
if(TCL_LIBRARY)
target_add_library(${MODULE_NAME} TCL_LIBRARY)
endif()
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
SET(CMAKE_SWIG_FLAGS "-c++")
set(CMAKE_SWIG_FLAGS "-c++")
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(${INTERFACE_FILES} PROPERTIES CMAKE_SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(${MODULE_NAME} tcl ${INTERFACE_FILES} ${SRC_FILES})
SWIG_LINK_LIBRARIES(${MODULE_NAME} ${TCL_LIBRARIES})
set_source_file_properties(${INTERFACE_FILES} PROPERTIES CPLUSPLUS ON)
set_source_file_properties(${INTERFACE_FILES} PROPERTIES CMAKE_SWIG_FLAGS "-includeall")
swig_add_module(${MODULE_NAME} tcl ${INTERFACE_FILES} ${SRC_FILES})
swig_link_libraries(${MODULE_NAME} ${TCL_LIBRARIES})
```
If you get errors indicating that C and C++ include files cannot be
found, like,
......@@ -1088,92 +1119,93 @@ found, like,
try setting the `-includeall` property on fewer source files:
# Try doing this on fewer files
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES SWIG_FLAGS "-includeall")
```cmake
# Try doing this on fewer files
set_source_file_properties(example.i PROPERTIES SWIG_FLAGS "-includeall")
```
In particular, you may need `-includeall` only on the top-level `.i`
files.
### How do I use CMake to build LaTeX documents?
Use the following approach. Note that you have to set LATEX_COMPILE to
LaTeX executable, DVIPDF_COMPILE to dvi to pdf converter. Also, the
Use the following approach. Note that you have to set `LATEX_COMPILE` to
LaTeX executable, `DVIPDF_COMPILE` to dvi to pdf converter. Also, the
LaTeX source is TDocument.tex and the result is called TDocument.pdf.
Note that this uses commands in CMake version 1.8 or later.
PROJECT(Document)
IF(LATEX_COMPILE)
ADD_CUSTOM_COMMAND(
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi
DEPENDS ${Document_BINARY_DIR}/TDocument.tex
COMMAND ${LATEX_COMPILE}
ARGS ${Document_SOURCE_DIR}/TDocument.tex
)
ENDIF(LATEX_COMPILE)
IF(DVIPDF_COMPILE)
ADD_CUSTOM_COMMAND(
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi
COMMAND ${DVIPDF_COMPILE}
ARGS ${Document_SOURCE_DIR}/TDocument.dvi
)
ENDIF(DVIPDF_COMPILE)
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf
)
The following uses commands in CMake version 2.0 and later
PROJECT(Document)
#
# Find LaTeX
#
FIND_PACKAGE(LATEX)
IF(LATEX_COMPILER)
ADD_CUSTOM_COMMAND(
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi
COMMAND ${LATEX_COMPILER}
ARGS ${Document_SOURCE_DIR}/TDocument.tex
DEPENDS ${Document_SOURCE_DIR}/TDocument.tex
COMMENT "Tex2dvi"
)
```
IF(DVIPS_CONVERTER)
ADD_CUSTOM_COMMAND(
OUTPUT ${Document_BINARY_DIR}/TDocument.ps
COMMAND ${DVIPS_CONVERTER}
ARGS ${Document_BINARY_DIR}/TDocument.dvi
-o ${Document_BINARY_DIR}/TDocument.ps
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi
COMMENT "dvi2ps"
)
IF(PS2PDF_CONVERTER)
ADD_CUSTOM_COMMAND(
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf
COMMAND ${PS2PDF_CONVERTER}
ARGS ${Document_BINARY_DIR}/TDocument.ps
DEPENDS ${Document_BINARY_DIR}/TDocument.ps
COMMENT "ps2pdf"
```cmake
project(Document)
if(LATEX_COMPILE)
add_custom_command(
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi
DEPENDS ${Document_BINARY_DIR}/TDocument.tex
COMMAND ${LATEX_COMPILE}
ARGS ${Document_SOURCE_DIR}/TDocument.tex
)
```
endif()
if(DVIPDF_COMPILE)
add_custom_command(
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi
COMMAND ${DVIPDF_COMPILE}
ARGS ${Document_SOURCE_DIR}/TDocument.dvi
)
endif()
add_custom_target(LaTeXDocument ALL echo
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf
)
```
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf
)
ENDIF(PS2PDF_CONVERTER)
ENDIF(DVIPS_CONVERTER)
ENDIF(LATEX_COMPILER)
The following uses commands in CMake version 2.0 and later
```cmake
project(Document)
#
# Find LaTeX
#
find_package(LATEX)
if(LATEX_COMPILER)
add_custom_command(
OUTPUT ${Document_BINARY_DIR}/TDocument.dvi
COMMAND ${LATEX_COMPILER}
ARGS ${Document_SOURCE_DIR}/TDocument.tex
DEPENDS ${Document_SOURCE_DIR}/TDocument.tex
COMMENT "Tex2dvi"
)
if(DVIPS_CONVERTER)
add_custom_command(
OUTPUT ${Document_BINARY_DIR}/TDocument.ps
COMMAND ${DVIPS_CONVERTER}
ARGS ${Document_BINARY_DIR}/TDocument.dvi
-o ${Document_BINARY_DIR}/TDocument.ps
DEPENDS ${Document_BINARY_DIR}/TDocument.dvi
COMMENT "dvi2ps"
)
if(PS2PDF_CONVERTER)
add_custom_command(
OUTPUT ${Document_BINARY_DIR}/TDocument.pdf
COMMAND ${PS2PDF_CONVERTER}
ARGS ${Document_BINARY_DIR}/TDocument.ps
DEPENDS ${Document_BINARY_DIR}/TDocument.ps
COMMENT "ps2pdf"
)
add_custom_target(LaTeXDocument ALL echo
DEPENDS ${Document_BINARY_DIR}/TDocument.pdf
)
endif() # PS2PDF_CONVERTER
endif() # DVIPS_CONVERTER
endif() # LATEX_COMPILER
```
### How do I get LaTeX references to be correct?
When your latex document contains references (e.g. \\ref{...} command)
When your latex document contains references (e.g. `\ref{...}` command)
you get to run two passes of latex. In the most general case, i.e. when
additionally your document uses a bibtex bibliography, you shall need
three passes of latex (and one pass of bibtex):
......@@ -1188,54 +1220,56 @@ and latex generated auxilary files (.aux, .log, .dvi, .bbl...) to create
an "artificial" set of CMake dependencies. The side-effect of those
dependencies should hopefully be the above described sequence of calls
to latex and bibtex
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/UsersManual.tex
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (first pass)"
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux
COMMAND ${BIBTEX_COMPILER}
ARGS -terse ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Bibtex"
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (second pass)"
)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (third pass)"
)
# Eventually trigger the whole process
ADD_CUSTOM_TARGET(LaTeXDocument ALL echo
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log
)
```cmake
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/UsersManual.tex
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (first pass)"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.aux
COMMAND ${BIBTEX_COMPILER}
ARGS -terse ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Bibtex"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (second pass)"
)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.bbl
${CMAKE_CURRENT_BINARY_DIR}/UsersManual.dvi
COMMAND ${LATEX_COMPILER}
ARGS -interaction=batchmode ${CMAKE_CURRENT_BINARY_DIR}/UsersManual
COMMENT "Latex (third pass)"
)
# Eventually trigger the whole process
add_custom_target(LaTeXDocument ALL echo
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/UsersManual.log
)
```
### How can I set TEXINPUTS for a LaTeX compilation?
First note that most often you can avoid using TEXINPUTS by copying all
the necessary files (.tex source file and included graphic files e.g.
.eps files) from your PROJECT_SOURCE_DIR hirarchy to your
PROJECT_BINARY_DIR subdir \[refer to CONFIGURE_FILE with the COPYONLY
.eps files) from your `PROJECT_SOURCE_DIR` hirarchy to your
`PROJECT_BINARY_DIR` subdir \[refer to `configure_file` with the COPYONLY
flag set for copying files\]. Since by default latex uses the current
working directory as value for TEXINPUTS you should be all set. As
expected, this trick is quick AND dirty since your concerned
PROJECT_BINARY_DIR subdir now contains files that are NOT generated by
`PROJECT_BINARY_DIR` subdir now contains files that are NOT generated by
CMake (in the sense that those files are not the result of a system
command but were merely duplicated)...
......@@ -1243,52 +1277,51 @@ If you consider it is cleaner or easier to define a TEXINPUTS
environment variable \[the latex command probably misses a -I flag\] you
can find an example in the InsightDocuments cvs archive (refer to the
section "cvs access" near the bottom of Kitware's ITK download page) or
use google with keywords "ITK_TEXINPUTS CONFIGURE_FILE". Look at
use google with keywords `ITK_TEXINPUTS CONFIGURE_FILE`. Look at
InsightDocuments/CourseWare/Training/Vis2003/Latex/CMakeLists.txt and
search for e.g. "LaTeXWrapper.sh.in".
Roughly the mechanism goes:
- SET ITK_TEXINPUTS with the desired TEXINPUTS
- CONFIGURE_FILE
- `set(ITK_TEXINPUTS ...)` with the desired TEXINPUTS
- `configure_file`
"InsightDocuments/CourseWare/Training/Vis2003/LaTeXWrapper.sh.in"
which generates an sh shell script setting the shell variable
TEXINPUTS prior to running the latex command
- use ADD_CUSTOM_COMMAND to invoke this shell script
- use `add_custom_command` to invoke this shell script
This very example is Win32 portable (except that LaTeXWrapper.bat.in
generates a .bat shell
script)
generates a .bat shell script)
## Library questions
### Can I build both shared and static libraries with one ADD_LIBRARY command?
No. Each library you build must have a unique target name, i.e. the
"libname" field of the ADD_LIBRARY command. That way, CMake can track
`libname` field of the `add_library` command. That way, CMake can track
dependencies separately for each library. Libraries can have the same
OUTPUT_NAME, see the SET_TARGET_PROPERTIES command, but this is not
the
default.
`OUTPUT_NAME`, see the `set_target_properties` command, but this is not
the default.
### Does that mean I have to build all my library objects twice, once for shared and once for static?\! I don't like that\!
In practice, most libraries have different defines and compiler flags
for the shared vs. static cases. So you would have to build all your
library objects twice anyways. However, if you happen to have
***exactly*** the same defines and compiler flags for the shared vs.
*exactly* the same defines and compiler flags for the shared vs.
static cases...
...if you're using Linux and a GCC-style linker, you could do the
following. Note that for this to work correctly on linux, the zzSTATIC
source files should have been compiled with "-fPIC" to ensure they will
work in a shared library.
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)
ADD_LIBRARY(zzSTATIC STATIC -fPIC)
ADD_LIBRARY(zzDYNAMIC SHARED)
TARGET_LINK_LIBRARIES(zzDYNAMIC -Wl,-whole-archive zzSTATIC -Wl,-no-whole-archive)
ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)
```cmake
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_COMPILER_IS_GNUCC)
add_library(zzSTATIC STATIC -fPIC)
add_library(zzDYNAMIC SHARED)
target_link_libraries(zzDYNAMIC -Wl,-whole-archive zzSTATIC -Wl,-no-whole-archive)
endif()
```
...if you want a cross-platform approach that works on all compilers,
not just GCC or Linux, you could extract the locations of previously
......@@ -1301,28 +1334,31 @@ code.
### How do I make my shared and static libraries have the same root name, but different suffixes?
Set the OUTPUT_NAME of your shared and static libraries to the same
Set the `OUTPUT_NAME` of your shared and static libraries to the same
thing.
ADD_LIBRARY(foo SHARED ${foo_sources})
ADD_LIBRARY(foo-static STATIC ${foo_sources})
# The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it.
# The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it.
SET_TARGET_PROPERTIES(foo-static PROPERTIES OUTPUT_NAME "foo")
# Now the library target "foo-static" will be named "foo.lib" with MS tools.
# This conflicts with the "foo.lib" import library corresponding to "foo.dll",
# so we add a "lib" prefix (which is default on other platforms anyway):
SET_TARGET_PROPERTIES(foo-static PROPERTIES PREFIX "lib")
```cmake
add_library(foo SHARED ${foo_sources})
add_library(foo-static STATIC ${foo_sources})
# The library target "foo" already has a default OUTPUT_NAME of "foo", so we don't need to change it.
# The library target "foo-static" has a default OUTPUT_NAME of "foo-static", so change it.
set_target_properties(foo-static PROPERTIES OUTPUT_NAME "foo")
# Now the library target "foo-static" will be named "foo.lib" with MS tools.
# This conflicts with the "foo.lib" import library corresponding to "foo.dll",
# so we add a "lib" prefix (which is default on other platforms anyway):
set_target_properties(foo-static PROPERTIES PREFIX "lib")
```
One more detail is needed with CMake 2.6.x and lower (but not CMake 2.8
or higher). If you are building your shared and static libraries in the
same directory, you will also need the following to keep your shared and
static libraries from clobbering each other during the
build.
static libraries from clobbering each other during the build.
# Help CMake 2.6.x and lower (not necessary for 2.8 and above, but doesn't hurt):
SET_TARGET_PROPERTIES(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(foo-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
```cmake
# Help CMake 2.6.x and lower (not necessary for 2.8 and above, but doesn't hurt):
set_target_properties(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1)
set_target_properties(foo-static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
```
### How do I rename a library after it has already been built?
......@@ -1331,24 +1367,25 @@ CMakeLists.txt says it's supposed to be.
Perhaps you want to copy the library to a different name. But, are you
sure that's what you want to do? You could just change the name in your
ADD_LIBRARY command or change its OUTPUT_NAME property using
SET_TARGET_PROPERTY(). If you really really want to copy the library
`add_library` command or change its OUTPUT_NAME property using
`set_target_property()`. If you really really want to copy the library
to a different name, try:
GET_TARGET_PROPERTY(LIB_NAME Foo LOCATION)
GET_TARGET_PROPERTY(Bar_prefix Foo PREFIX)
GET_TARGET_PROPERTY(Bar_suffix Foo SUFFIX)
SET(NEW_LIB_NAME ${Bar_prefix}Bar${Bar_suffix})
ADD_CUSTOM_COMMAND(
TARGET Foo
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${LIB_NAME} ${NEW_LIB_NAME}
)
```cmake
get_target_property(LIB_NAME Foo LOCATION)
get_target_property(Bar_prefix Foo PREFIX)
get_target_property(Bar_suffix Foo SUFFIX)
set(NEW_LIB_NAME ${Bar_prefix}Bar${Bar_suffix})
add_custom_command(
TARGET Foo
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${LIB_NAME} ${NEW_LIB_NAME}
)
```
On Windows you may also want to copy the .dll import lib, using the same
approach as above, but with IMPORT_PREFIX and IMPORT_SUFFIX. *Problem:
LOCATION only refers to 1 file, the .dll. What is a simple way to get
approach as above, but with `IMPORT_PREFIX` and `IMPORT_SUFFIX`. *Problem:
`LOCATION` only refers to 1 file, the .dll. What is a simple way to get
the location of the import lib? Could provide a complicated way, but
that's annoying.*
......@@ -1378,8 +1415,9 @@ default behavior provided by CMake with the simple
`PRIVATE`, and `INTERFACE` options to target_link_libraries to specify
whether linking should be used for just the implementation and/or made
part of the interface (transitive dependencies):
target_link_libraries(myLibrary PRIVATE myImplDependency)
```cmake
target_link_libraries(myLibrary PRIVATE myImplDependency)
```
CMake 2.8.7 and above provide `LINK_PUBLIC` and `LINK_PRIVATE` options
for the same purpose (these were superseded by PUBLIC/PRIVATE/INTERFACE
......@@ -1390,11 +1428,11 @@ in 3.0 for consistency with options other commands like
CMake does not preprocess source files while scanning dependencies. Code
like
#if 0
# include "bla.h"
#endif
```
#if 0
# include "bla.h"
#endif
```
will result in a dependency on "bla.h". This sometimes leads to source
files recompiling unnecessarily but will not break the build.
......@@ -1412,11 +1450,11 @@ For example, if the Makefile generator is used, then all of the
following are example usages of DESTDIR (perhaps assuming the bash shell
for the last 2):
(1) make install DESTDIR="/some/absolute/path"
(2) make DESTDIR="/some/absolute/path" install
(3) DESTDIR="/some/absolute/path" make install
(4) export DESTDIR="/some/absolute/path
make install
1. `make install DESTDIR="/some/absolute/path"`
2. `make DESTDIR="/some/absolute/path" install`
3. `DESTDIR="/some/absolute/path" make install`
4. `export DESTDIR="/some/absolute/path`<br/>
`make install`
### Can I do "make uninstall" with CMake?
......@@ -1429,55 +1467,57 @@ you from providing one. You need to delete the files listed in
install_manifest.txt file. Here is how to do it. First create file
cmake_uninstall.cmake.in in the top-level directory of the project:
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")