All notes
Cmak

A minimal template

The default configuration file is CMakeLists.txt.

Wcf note

The project struture is:

/
/src
/ut
/include/wcf

/CmakeLists.txt.

cmake_minimum_required (VERSION 2.6)
set(libName ###wcfLib###)
project (${libName})

# Set a consistent MACOSX_RPATH default across all CMake versions.
# When CMake 2.8.12 is required, change this default to 1.
# When CMake 3.0.0 is required, remove this block (see CMP0042).
if(NOT DEFINED CMAKE_MACOSX_RPATH)
set(CMAKE_MACOSX_RPATH 0)
endif()

add_definitions(-std=c++0x)
add_definitions(-fPIC)

# It is recommended to specify actual libs instead of wildcards!
# file(GLOB_RECURSE externLibs "${externDir}/slib/lib*.a" "${externDir}/lib/lib*.*")
file(GLOB_RECURSE externLibs "${externDir}/slib/libgtest*.a")
# list(REMOVE_ITEM externLibs ${externDir}/lib/lib${libName}.*)
message(STATUS ${externLibs})
include_directories(${CMAKE_SOURCE_DIR}/include/##wcf##)
include_directories(${externDir}/include)

add_subdirectory(src)
add_subdirectory(ut)

ut/CMakeLists.txt.

set(exeName runTest)
file(GLOB srcs "*.cpp")
add_executable(${exeName} ${srcs})
file(GLOB gtestLibs "${externDir}/slib/libgtest*.a")
# z crypto
target_link_libraries(${exeName} ${libName} ${externLibs} ${externLibs} ${gtestLibs} pthread)

src/CMakeLists.txt

file(GLOB srcs "*.cpp")
# file(GLOB_RECURSE srcs "*.cpp")

if(DEFINED IOS_PLATFORM)
add_library(${libName} STATIC ${srcs})
else()
add_library(${libName} SHARED ${srcs})
endif()

target_link_libraries(${libName} ${externLibs} ${externLibs})
set_target_properties(${libName} PROPERTIES version 1.0.0 soversion 1.0.0)

if(DEFINED IOS_PLATFORM)
else()
install(TARGETS ${libName} LIBRARY DESTINATION lib CONFIGURATIONS Release)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include)
endif()

Generate Xcode from cmake. macCompile.sh.

#!/bin/bash

# xcode=1, then generate Xcode.
xcode="0"
if [ -n "${1}" ]; then
	xcode="1"
fi

# Set extern in your .bashrc!
# extern="###/path/to/extern###"
# rm -rf ${extern}/lib/libWcf*.dylib ${extern}/slib/libWcf*.a

[ ! -d build/debug ] && mkdir -p build/debug
cd build/debug
# Have to remove this, so cmake will not complain about changing templates.
rm -f CMakeCache.txt
[ ${xcode} == "0" ] && cmake -DCMAKE_BUILD_TYPE=Debug -DexternDir=${extern} -DCMAKE_INSTALL_PREFIX=${extern} ../.. && make -j8
[ ${xcode} == "1" ] && cmake -DCMAKE_BUILD_TYPE=Debug -DexternDir=${extern} -DCMAKE_INSTALL_PREFIX=${extern} -G Xcode ../..
cd ../..

[ ! -d build/release ] && mkdir -p build/release
cd build/release
rm -f CMakeCache.txt
[ ${xcode} == "0" ] && cmake -DCMAKE_BUILD_TYPE=Release -DexternDir=${extern} -DCMAKE_INSTALL_PREFIX=${extern} ../.. && make -j8
[ ${xcode} == "1" ] && cmake -DCMAKE_BUILD_TYPE=Release -DexternDir=${extern} -DCMAKE_INSTALL_PREFIX=${extern} -G Xcode ../..
cd ../..

macDistribute.sh.

#!/bin/bash

echo "Must pass UT first before installing!"
cd build/release
make -j8
make install

macRunTest.sh.

#!/bin/bash

export DYLD_FALLBACK_LIBRARY_PATH=/pathto/extern/macos/lib
export PATH=/pathto/extern/macos/bin:$PATH

# The following may be wrong.
gdb build/debug/runTest

Other

References: cmake website.

# The name of our project is "HELLO". CMakeLists files in this project can
# refer to the root source directory of the project as ${HELLO_SOURCE_DIR} and
# to the root binary directory of the project as ${HELLO_BINARY_DIR}.
cmake_minimum_required (VERSION 2.6)
project (HELLO)

# Recurse into the "Hello" and "Demo" subdirectories. This does not actually
# cause another cmake executable to run. The same process will walk through
# the project's entire directory structure.
add_subdirectory (Hello)
add_subdirectory (Demo)

Now in the "./Hello" directory,

# Create a library called "Hello" which includes the source file "hello.cxx".
# The extension is already found. Any number of sources could be listed here.
add_library (Hello hello.cxx)

In the "./Demo" directory,

# Make sure the compiler can find include files from our Hello library.
include_directories (${HELLO_SOURCE_DIR}/Hello)

# Make sure the linker can find the Hello library once it is built.
link_directories (${HELLO_BINARY_DIR}/Hello)

# Add executable called "helloDemo" that is built from the source files
# "demo.cxx" and "demo_b.cxx". The extensions are automatically found.
add_executable (helloDemo demo.cxx demo_b.cxx)

# Link the executable to the Hello library.
target_link_libraries (helloDemo Hello)

CommandLine

CmakeOrg: 3.0 manual.

-D var:type=value
# Create a cmake cache entry.
When cmake is first run in an empty build tree, it creates a CMakeCache.txt file and populates it with customizable settings for the project.
This option may be used to specify a setting that takes priority over the project's default value. The option may be repeated for as many cache entries as desired.
Types include: BOOL, PATH.

-Wno-dev
Suppress developer warnings.
Suppress warnings that are meant for the author of the CMakeLists.txt files.

-Wdev
Enable developer warnings.
Enable warnings that are meant for the author of the CMakeLists.txt files.

Usual commands

enable_testing

Enable testing for current directory and below. See also the add_test command. Note that ctest expects to find a test file in the build directory root. Therefore, this command should be in the source directory root.

add_test

add_test(NAME <name> COMMAND <command> [<arg>...]
         [CONFIGURATIONS <config>...]
         [WORKING_DIRECTORY <dir>])
Example usage:
add_test(NAME mytest
         COMMAND testDriver --config $<CONFIGURATION>
                            --exe $<TARGET_FILE:myexe>)
This creates a test mytest whose command runs a testDriver tool passing the configuration name and the full path to the executable file produced by target myexe.

add_test(<name> <command> [<arg>...])
Add a test called <name> with the given command-line. Unlike the above NAME signature no transformation is performed on the command-line to support target names or generator expressions.

file

http://www.cmake.org/cmake/help/v3.0/command/file.html.

file(WRITE filename "message to write"... )
file(APPEND filename "message to write"... )
file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])
file(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512> filename variable)
file(STRINGS filename variable [LIMIT_COUNT num]
     [LIMIT_INPUT numBytes] [LIMIT_OUTPUT numBytes]
     [LENGTH_MINIMUM numBytes] [LENGTH_MAXIMUM numBytes]
     [NEWLINE_CONSUME] [REGEX regex]
     [NO_HEX_CONVERSION])
file(GLOB variable [RELATIVE path] [globbing expressions]...)
file(GLOB_RECURSE variable [RELATIVE path]
     [FOLLOW_SYMLINKS] [globbing expressions]...)
file(RENAME <oldname> <newname>)
file(REMOVE [file1 ...])
file(REMOVE_RECURSE [file1 ...])
file(MAKE_DIRECTORY [directory1 directory2 ...])
file(RELATIVE_PATH variable directory file)
file(TO_CMAKE_PATH path result)
file(TO_NATIVE_PATH path result)
file(DOWNLOAD url file [INACTIVITY_TIMEOUT timeout]
     [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS]
     [EXPECTED_HASH ALGO=value] [EXPECTED_MD5 sum]
     [TLS_VERIFY on|off] [TLS_CAINFO file])
file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]
     [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])
file(TIMESTAMP filename variable [<format string>] [UTC])
file(GENERATE OUTPUT output_file
     <INPUT input_file|CONTENT input_content>
     [CONDITION expression])
file(STRINGS myfile.txt myfile)
	stores a list in the variable "myfile" in which each item is a line from the input file.

Examples of globbing expressions include:
	*.cxx      - match all files with extension cxx
	*.vt?      - match all files with extension vta,...,vtz
	f[3-5].txt - match files f3.txt, f4.txt, f5.txt

Examples of recursive globbing include:
	/dir/*.py  - match all python files in /dir and subdirectories

http://stackoverflow.com/questions/3201154/cmake-automatically-add-all-files-in-a-folder-to-a-target.

file(GLOB helloworld_SRC "*.h" "*.cpp")

add_executable(helloworld ${helloworld_SRC})

if

if(expression)
  # then section.
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
elseif(expression2)
  # elseif section.
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
else(expression)
  # else section.
  COMMAND1(ARGS ...)
  COMMAND2(ARGS ...)
  ...
endif(expression)

Ref.

String

string(REGEX MATCH <regular_expression>
       <output variable> <input> [<input>...])
string(REGEX MATCHALL <regular_expression>
       <output variable> <input> [<input>...])
string(REGEX REPLACE <regular_expression>
       <replace_expression> <output variable>
       <input> [<input>...])
string(REPLACE <match_string>
       <replace_string> <output variable>
       <input> [<input>...])
string(CONCAT <output variable> [<input>...])
string(<MD5|SHA1|SHA224|SHA256|SHA384|SHA512>
       <output variable> <input>)
string(COMPARE EQUAL <string1> <string2> <output variable>)
string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
string(COMPARE LESS <string1> <string2> <output variable>)
string(COMPARE GREATER <string1> <string2> <output variable>)
string(ASCII <number> [<number> ...] <output variable>)
string(CONFIGURE <string1> <output variable>
       [@ONLY] [ESCAPE_QUOTES])
string(TOUPPER <string1> <output variable>)
string(TOLOWER <string1> <output variable>)
string(LENGTH <string> <output variable>)
string(SUBSTRING <string> <begin> <length> <output variable>)
string(STRIP <string> <output variable>)
string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
       [RANDOM_SEED <seed>] <output variable>)
string(FIND <string> <substring> <output variable> [REVERSE])
string(TIMESTAMP <output variable> [<format string>] [UTC])
string(MAKE_C_IDENTIFIER <input string> <output variable>)

list

Reference.

list(LENGTH <list> <output variable>)
list(GET <list> <element index> [<element index> ...]
     <output variable>)
list(APPEND <list> [<element> ...])
list(FIND <list> <value> <output variable>)
list(INSERT <list> <element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value> [<value> ...])
list(REMOVE_AT <list> <index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)

Install

install(TARGETS targets... [EXPORT <export-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
         [DESTINATION <dir>]
         [INCLUDES DESTINATION [<dir> ...]]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [OPTIONAL] [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...])
Ref.

install(TARGETS myExe mySharedLib myStaticLib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib/static)
install(TARGETS mySharedLib DESTINATION /some/full/path)

install(DIRECTORY icons scripts/ DESTINATION share/myproj
        PATTERN "CVS" EXCLUDE
        PATTERN "scripts/*"
        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
                    GROUP_EXECUTE GROUP_READ)

Version, soversion

Ref.

SET_TARGET_PROPERTIES(
   wt
 PROPERTIES
   VERSION 2.0.6
   SOVERSION 0.0.0
)
You will get this:
lrwxrwxrwx 1 root root      14 2007-09-24 09:56 /usr/lib/libwt.so -> 
libwt.so.0.0.0
lrwxrwxrwx 1 root root      14 2007-09-24 09:56 /usr/lib/libwt.so.0.0.0 -> 
libwt.so.2.0.6
-rw-r--r-- 1 root root 1935368 2007-09-22 13:02 /usr/lib/libwt.so.2.0.6

Ref.

libmylibname.so.6.1 - the real file, name used to separate the different versions
	Used by no one.
libmylibname.so.5 - used by whom? linker?
	Used by the dynamic linker (run time).
libmylibname.so - used by whom? linker?
	Used by the static linker (compile time).
Process is:
  1. static linker (ld) gets -lfoo
  2. ld finds libfoo.so
  3. ld extracts the DT_SONAME symbol from the library
  4. soname = "libfoo.so.N"
  5. ld writes to the executable: DT_NEEDED "libfoo.so.N"
  6. application is loaded
  7. dynamic linker (ldd) sees DT_NEEDED libfoo.so.N
  8. ldd tries to load libfoo.so.N

Find_library

A shorthand: find_library (VAR name1 [path1 path2 ...]).

The general signature:
find_library (
	 VAR
	 name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
	 [HINTS path1 [path2 ... ENV var]]
	 [PATHS path1 [path2 ... ENV var]]
	 [PATH_SUFFIXES suffix1 [suffix2 ...]]
	 [DOC "cache documentation string"]
	 [NO_DEFAULT_PATH]
	 [NO_CMAKE_ENVIRONMENT_PATH]
	 [NO_CMAKE_PATH]
	 [NO_SYSTEM_ENVIRONMENT_PATH]
	 [NO_CMAKE_SYSTEM_PATH]
	 [CMAKE_FIND_ROOT_PATH_BOTH |
	  ONLY_CMAKE_FIND_ROOT_PATH |
	  NO_CMAKE_FIND_ROOT_PATH]
	)

http://www.cmake.org/cmake/help/v3.0/command/find_library.html.

target_link_libraries

target_link_libraries(<target> [item1 [item2 [...]]]
	[[debug|optimized|general] <item>] ...)

# CMake allows the graph to contain cycles
add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)

In CMakeLists.txt, I just write the libs twice to solve this problem:

set (DCMTK_LIB_DIR "/home/image/proGreen/dcmtk/lib")
file (GLOB DCMTK_LIBRARIES "${DCMTK_LIB_DIR}/lib*.a")
# Write DCMTK_LIBRARIES twice here to solve cyclic dependency.
target_link_libraries (imgServ pthread mysqlcppconn ssl ${DCMTK_LIBRARIES} ${DCMTK_LIBRARIES})

http://www.cmake.org/cmake/help/v3.0/command/target_link_libraries.html.

find_package

Load settings for an external project. It has two overloads/signatures/modes: Module and Config. Reference.

Module

Module mode:

find_package(<package> [version] [EXACT] [QUIET] [MODULE]
	[REQUIRED] [[COMPONENTS] [components...]]
	[OPTIONAL_COMPONENTS components...]
	[NO_POLICY_SCOPE])
<package>_FOUND will be set to indicate the result. QUIET option disables messages if the package cannot be found. The MODULE option disables the Config signature. The REQUIRED option stops processing with an error message if the package cannot be found.

A package-specific list of required components may be listed after the COMPONENTS option (or after the REQUIRED option if present). The [version] argument requests a version with which the package found should be compatible (format is major[.minor[.patch[.tweak]]]). The EXACT option requests that the version be matched exactly.

CMake searches for a file called Find<package>.cmake in the CMAKE_MODULE_PATH followed by the CMake installation. If the file is found, it is read and processed by CMake. It is responsible for finding the package, checking the version, and producing any needed messages. Many find-modules provide limited or no support for versioning. If no module is found and the MODULE option is not given the command proceeds to Config mode.

CMAKE_MODULE_PATH: List of directories to search for CMake modules. Commands like include() and find_package() search for files in directories listed by this variable before checking the default modules that come with CMake.

set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_PATH} ${CMAKE_MODULE_PATH})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_PREFIX}")

Config

The CONFIG option may be used to skip Module mode explicitly and switch to Config mode. It is synonymous to using NO_MODULE.

Config mode attempts to locate a configuration file provided by the package to be found. A cache entry called <package>_DIR is created to hold the directory containing the file. By default the command searches for a package with the name <package>. If the NAMES option is given the names following it are used instead of <package>. The command searches for a file called <name>Config.cmake or <lower-case-name>-config.cmake for each name specified. A replacement set of possible configuration file names may be given using the CONFIGS option. The search procedure is specified below. Once found, the configuration file is read and processed by CMake. Since the file is provided by the package it already knows the location of package contents. The full path to the configuration file is stored in the cmake variable <package>_CONFIG.

FindModule.cmake

http://stackoverflow.com/questions/8711109/could-not-find-module-findopencv-cmake-error-in-configuration-process.

Find_package always needs FindModule.cmake file under CMAKE_MODULE_PATH. If cmake provides none, and the library website gives nothing cmake, you have to write one yourself. Usually, I would resort to the second way: PackageConfig.cmake.

PackageConfig.cmake

Many packages compiled by cmake provide PackageConfig.cmake file. For example, OpenCV has it under ".", "cmake/", "unix_install/". Use

find_package(OpenCV CONFIG REQUIRED)

Example: find glog

find_package (Glog REQUIRED)
include_directories (${GLOG_INCLUDE_DIR})

add_executable (foo main.cc)
target_link_libraries (foo glog)

# - Try to find Glog
#
# The following variables are optionally searched for defaults
#  GLOG_ROOT_DIR:            Base directory where all GLOG components are found
#
# The following are set after configuration is done:
#  GLOG_FOUND
#  GLOG_INCLUDE_DIRS
#  GLOG_LIBRARIES
#  GLOG_LIBRARYRARY_DIRS

include(FindPackageHandleStandardArgs)

set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")

if(WIN32)
    find_path(GLOG_INCLUDE_DIR glog/logging.h
        PATHS ${GLOG_ROOT_DIR}/src/windows)
else()
    find_path(GLOG_INCLUDE_DIR glog/logging.h
        PATHS ${GLOG_ROOT_DIR})
endif()

if(MSVC)
    find_library(GLOG_LIBRARY_RELEASE libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Release)

    find_library(GLOG_LIBRARY_DEBUG libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Debug)

    set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
else()
    find_library(GLOG_LIBRARY glog
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES
            lib
            lib64)
endif()

find_package_handle_standard_args(GLOG DEFAULT_MSG
    GLOG_INCLUDE_DIR GLOG_LIBRARY)

if(GLOG_FOUND)
    set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
    set(GLOG_LIBRARIES ${GLOG_LIBRARY})
endif()

configure_file

Copy a file to another location and modify its contents. Ref.

configure_file(<input> <output>
               [COPYONLY] [ESCAPE_QUOTES] [@ONLY]
               [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])

add_library

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

Ref.

add_definitions

add_definitions(-DFOO -DBAR ...)

add_compile_options(-std=c++0x) # CMake 2.8.12 or newer
add_definitions(-std=c++0x) # CMake 2.8.11 or older

CFlags

Reference. To make GCC support unique_ptr, add in CMakeLists.txt:

ADD_DEFINITIONS("-std=c++0x")

add_compile_options

add_compile_options(<option> ...)

Option

option(option_variable "help string describing option" [initial value])

Example:
option(BUILD_CODEC "Build the CODEC executables" ON)

CMakeDependentOption

CMAKE_DEPENDENT_OPTION(USE_FOO "Use Foo" ON "USE_BAR;NOT USE_ZOT" OFF)
  1. If USE_BAR is true and USE_ZOT is false, this provides an option called USE_FOO that defaults to ON. Otherwise, it sets USE_FOO to OFF.
  2. If the status of USE_BAR or USE_ZOT ever changes, any value for the USE_FOO option is saved so that when the option is re-enabled it retains its old value.

Message

http://www.cmake.org/cmake/help/v3.0/command/message.html.

message([<mode>] "message to display" ...)

(none)         = Important information
STATUS         = Incidental information
WARNING        = CMake Warning, continue processing
AUTHOR_WARNING = CMake Warning (dev), continue processing
SEND_ERROR     = CMake Error, continue processing, but skip generation
FATAL_ERROR    = CMake Error, stop processing and generation
DEPRECATION    = CMake Deprecation Error or Warning if variable
				CMAKE_ERROR_DEPRECATED or CMAKE_WARN_DEPRECATED
				is enabled, respectively, else no message.

message(STATUS "Hello World!")

link_directories

link_directories(directory1 directory2 ...)

Foreach

file (GLOB DCMTK_LIBRARIES "/home/image/proGreen/dcmtk/lib/lib*.a")
message("DCMTK libs: ")
foreach(lib ${DCMTK_LIBRARIES})
	message(STATUS ${lib})                                              
endforeach() 

Set

http://www.cmake.org/cmake/help/v3.0/command/set.html.

set(<variable> <value>
    [[CACHE <type> <docstring> [FORCE]] | PARENT_SCOPE])

The value of type:
FILEPATH = File chooser dialog.
PATH     = Directory chooser dialog.
STRING   = Arbitrary string.
BOOL     = Boolean ON/OFF checkbox.
INTERNAL = No GUI entry (used for persistent variables).

set(<variable> <value1> ... <valueN>)
	In this case <variable> is set to a semicolon separated list of values.

<variable> can be an environment variable such as:
	set( ENV{PATH} /home/martink )
in which case the environment variable will be set.

  1. Each directory added with add_subdirectory or each function declared with function creates a new scope. The new child scope inherits all variable definitions from its parent scope. Variable assignments in the new child sope with the set command will only be visible in the child scope unless the PARENT_SCOPE option is used.
  2. If value is not specified then the variable is removed instead of set. See also: the unset() command.
  3. If CACHE is present, then the variable is put in the cache instead, unless it is already in the cache. If CACHE is used, type and docstring are required.
  4. Normally, set(...CACHE...) creates cache variables, but does not modify them. If FORCE is specified, the value of the cache variable is set, even if the variable is already in the cache. This should normally be avoided, as it will remove any changes to the cache variable's value by the user.

Var types

In CMake there are two types of variables: normal variables and cache variables.

Both types can exist at the same time with the same name but different values.
When ${FOO} is evaluated, CMake first looks for a normal variable 'FOO' in scope and uses it if set. If and only if no normal variable exists then it falls back to the cache variable 'FOO'.
Finally, whenever a cache variable is added or modified by a command, CMake also removes the normal variable of the same name from the current scope so that an immediately following evaluation of it will expose the newly cached value.

# In this case variable is set to a semicolon separated list of values.
set(variable value1 ... valueN)

# variable can be an environment variable such as:
set( ENV{PATH} /home/martink )

# Get environment variable. NOTE: $ must be there.
set(wcfDir $ENV{wcf})

# sets the normal variable 'FOO', but it will hide any existing cache value 'FOO'.
set(FOO "x")
# checks for 'FOO' in the cache, ignoring any normal variable of the same name:
set(FOO "x" CACHE ...)

set_source_files_properties

set_source_files_properties(yourfile.c LANGUAGE CXX) would compile .c files with g++.

FAQ

Cmake clean

Is there a way to remove files like cmake_install.cmake and CMakeCache.txt, and the CMakeFiles folders, just as make clean?

Stackoverflow Ref. Since cmake could do off-source build, we could simply delete the off-build directory, say, "build", to remove everything automatically generated by cmake to start anew.

CMAKE_CXX_CFLAGS

The var is cached in CMakeCache.txt. So if you want to set the var, you'd better force rewrite it by:

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /foobar" FORCE)

Detect Compiler

Ref.

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  # using regular Clang or AppleClang
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  # using GCC
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
  # using Intel C++
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  # using Visual Studio C++
endif()

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
    "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
    set(warnings "-Wall -Wextra -Werror")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    set(warnings "/W4 /WX /EHsc")
endif()
if (NOT CONFIGURED_ONCE)
    set(CMAKE_CXX_FLAGS "${warnings}"
        CACHE STRING "Flags used by the compiler during all build types." FORCE)
    set(CMAKE_C_FLAGS   "${warnings}"
        CACHE STRING "Flags used by the compiler during all build types." FORCE)
endif()

set(CONFIGURED_ONCE TRUE CACHE INTERNAL
    "A flag showing that CMake has configured at least once.")

Mac os RPATH

# Set a consistent MACOSX_RPATH default across all CMake versions.
# When CMake 2.8.12 is required, change this default to 1.
# When CMake 3.0.0 is required, remove this block (see CMP0042).
if(NOT DEFINED CMAKE_MACOSX_RPATH)
set(CMAKE_MACOSX_RPATH 0)
endif()

Out-of-source build

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.

Note: Before performing an out-of-source build, ensure that all CMake generated in-source build information is removed from the source directory, e.g., CMakeFiles directory, CMakeCache.txt. Otherwise: "I run an out-of-source build but CMake generates in-source anyway. Why?" This means that there is a CMakeCache.txt file in the source tree, possibly as part of an existing in-source build.

Generate other build systems

cmake -G Xcode ..

Release and debug

The possible options are: Debug, Release, ReleaseWithDebInfo

cmake -DCMAKE_BUILD_TYPE=Debug

Choose compiler

CMAKE_CXX_COMPILER can only be set the first time cmake is run in a given build directory. On subsequent runs it is ignored. In order to change CMAKE_CXX_COMPILER you first need to delete the contents of the build directory and then run cmake again with that option.

Source: http://www.cmake.org/Wiki/CMake_Useful_Variables
I believe the reasoning for only using that variable on the first run is because changing it later would potentially invalidate everything already built including the configuration checks so cmake would have to start from scratch anyway.

Install prefix

mkdir -p release && cd release
# The type (PATH) is not strictly necessary, but would cause the Qt based cmake-gui to present the directory chooser dialog.
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr ..

Link: fatal error LNK1112: module machine type conflict with target machine type

StackOverflow: how to build x86 and/or x64 on windows.


mkdir build32 & pushd build32
cmake -G "Visual Studio 12 2013" ..
popd
mkdir build64 & pushd build64
cmake -G "Visual Studio 12 2013 Win64" ..
popd
cmake --build build32 --config Release
cmake --build build64 --config Release

LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt

StackOverflow.

Encounted after installing a new version of the .NET Framework - 4.5.

Solved it by installing Visual Studio 2010 SP1 which made the problem disappear.

Variables

Useful vars

CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS (deprecated)

Superfluous since 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_BUILD_TYPE

http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_BUILD_TYPE.html.

How to examine the build type?

if (CMAKE_BUILD_TYPE STREQUAL "Debug")

CMAKE_SOURCE_DIR

Reference. CMAKE_SOURCE_DIR: this is the directory, from which cmake was started, i.e. the top level source directory.

PROJECT_SOURCE_DIR

This is the source directory of the most recent project() command.

BUILD_SHARED_LIBS

Global flag to cause add_library to create shared libraries if on.
This variable is often added to projects as an OPTION so that each user of a project can decide.

Examples

set(var1 OFF)
set(var2 "var1")

if(${var2})
# appears to the if command as:
# if(var1)
# The result is OFF which is false.

if(var2)
# which is true because var2 is defined to "var1" which is not a false constant.

Those below are from "if command reference".

if((expression) AND (expression OR (expression)))

if(<constant>)
# True if the constant is 1, ON, YES, TRUE, Y, or a non-zero number. False if the constant is 0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, the empty string, or ends in the suffix -NOTFOUND. Named boolean constants are case-insensitive. If the argument is not one of these constants, it is treated as a variable.

if(<variable>)
# True if the variable is defined to a value that is not a false constant. False otherwise. (Note macro arguments are not variables.)

if(<variable|string> MATCHES regex)

if(<variable|string> LESS <variable|string>)
if(<variable|string> GREATER <variable|string>)
if(<variable|string> EQUAL <variable|string>)
# True if the given string or variable's value is a valid number and equal to that on the right.

if(<variable|string> STREQUAL <variable|string>)
# True if the given string or variable's value is lexicographically equal to the string or variable on the right.

if(DEFINED variable)
if(EXISTS path-to-file-or-directory)
if(IS_DIRECTORY path-to-directory)
if(IS_ABSOLUTE path)
if(COMMAND command-name)

FAQ

Specify/Overwrite GCC path

StackOverflow.

export CC=/usr/local/bin/gcc
export CXX=/usr/local/bin/g++
cmake /path/to/your/project

Project setting

Ref.

####################
CMakeLists.txt:

cmake_minimum_required (VERSION 2.8)
project (TEST)
add_subdirectory (src) 
add_subdirectory (test)
enable_testing ()
add_test (NAME MyTest COMMAND Test)

####################
src/CMakeLists.txt:

add_library (Sqr sqr.cpp sqr.h)
add_executable (demo main.cpp)
target_link_libraries (demo Sqr)

####################
test/CMakeLists.txt:

find_package (Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories (${TEST_SOURCE_DIR}/src
                     ${Boost_INCLUDE_DIRS}
                     )
add_definitions (-DBOOST_TEST_DYN_LINK)
add_executable (Test test.cpp)
target_link_libraries (Test
                       Sqr
                       ${Boost_FILESYSTEM_LIBRARY}
                       ${Boost_SYSTEM_LIBRARY}
                       ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
                       )

Properties

EXCLUDE_FROM_ALL

Exclude the target from the all target.