变量 预定义变量 1 2 3 4 5 6 7 8 9 10 PROJECT_SOURCE_DIR PROJECT_BINARY_DIR PROJECT_NAME CMAKE_CURRENT_SOURCE_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_LIST_DIR CMAKE_CURRENT_LIST_LINE CMAKE_MODULE_PATH EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH
环境变量 1 2 3 4 5 $ENV{Name} set (ENV{Name} value)
系统信息 1 2 3 4 5 6 7 8 9 CMAKE_MAJOR_VERSION CMAKE_MINOR_VERSION CMAKE_PATCH_VERSION CMAKE_SYSTEM CMAKE_SYSTEM_NAME CMAKE_SYSTEM_VERSION CMAKE_SYSTEM_PROCESSOR UNIX WIN32
主要开关选项 1 2 3 4 5 6 7 8 9 10 11 12 BUILD_SHARED_LIBS CMAKE_C_FLAGS CMAKE_CXX_FLAGS add_definitions (-DENABLE_DEBUG -DABC)
语法 set设置变量1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 set (SRC_LIST main.cpp test .cpp)add_executable (demo ${SRC_LIST} )set (SRC_LIST main.cpp)set (SRC_LIST ${SRC_LIST} test .cpp)add_executable (demo ${SRC_LIST} )set (SRC_LIST main.cpp)list (APPEND SRC_LIST test .cpp)list (REMOVE_ITEM SRC_LIST main.cpp)add_executable (demo ${SRC_LIST} )list (LENGTH <list > <out-var>) list (GET <list > <element index> [<index> ...] <out-var>) list (JOIN <list > <glue> <out-var>)list (SUBLIST <list > <begin> <length> <out-var>)list (FIND <list > <value> <out-var>)list (APPEND <list > [<element>...]) list (FILTER <list > {INCLUDE | EXCLUDE} REGEX <regex>)list (INSERT <list > <index> [<element>...])list (POP_BACK <list > [<out-var>...])list (POP_FRONT <list > [<out-var>...])list (PREPEND <list > [<element>...])list (REMOVE_ITEM <list > <value>...)list (REMOVE_AT <list > <index>...)list (REMOVE_DUPLICATES <list >) list (TRANSFORM <list > <ACTION> [...])list (REVERSE <list >)list (SORT <list > [...])
if条件控制1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 if (expression) if (not exp) if (var1 AND var2) if (var1 OR var2) if (COMMAND cmd) if (EXISTS dir)/if (EXISTS file ) if (file1 IS_NEWER_THAN file2) if (IS_DIRECTORY dir) if (DEFINED var) if (var MATCHES regex) if (string MATCHES regex) if (variable LESS number) if (string LESS number)if (variable GREATER number) if (string GREATER number)if (variable EQUAL number) if (string EQUAL number)if (variable STRLESS string )if (string STRLESS string )if (variable STRGREATER string )if (string STRGREATER string )if (variable STREQUAL string )if (string STREQUAL string )if (${CMAKE_BUILD_TYPE} MATCHES "debug" ) ... endif ()if (UNIX) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -g" ) else () add_definitions (-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_WIN32_WINNT=0 x601 -D_WINSOCK_DEPRECATED_NO_WARNINGS) endif ()
while循环语句1 2 3 while (condition) ... endwhile ()
foreach循环语句1 2 3 4 5 6 7 8 9 foreach (loop_var RANGE start stop [step]) ... endforeach (loop_var)foreach (i RANGE 1 9 2 ) message (${i} ) endforeach (i)
macro宏定义1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 MACRO (<name> [arg1 [arg2 [arg3 ...]]]) COMMAND1(ARGS ...) COMMAND2(ARGS ...) ... ENDMACRO (<name>)macro (do_test arg1 arg2 result) add_test (test_${arg1} _${arg2} Demo ${arg1} ${arg2} ) set_tests_properties (test_${arg1} _${arg2} PROPERTIES PASS_REGULAR_EXPRESSION ${result} ) endmacro (do_test) do_test (5 2 "is 25" ) do_test (10 5 "is 100000" ) do_test (2 10 "is 1024" )
function函数1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function (<name> [<arg1> ...]) <commands> endfunction ()function (_foo) foreach (arg IN LISTS ARGN) message (STATUS "this in function is ${arg}" ) endforeach () endfunction ()_foo(a b c)
命令 指定cmake的最小版本 1 cmake_minimum_required (VERSION3.4.1 )
设置项目名称
设置编译类型 1 2 3 4 5 6 7 add_executable (demo demo.cpp) add_library (common STATIC util.cpp) add_library (common SHARED util.cpp)
指定编译包含的源文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 add_library (demo demo.cpp test .cpp util.cpp)aux_source_directory (dir VAR)aux_source_directory (. SRC_LIST)add_library (demo ${SRC_LIST} )file (GLOB SRC_LIST "*.cpp" "protocol/*.cpp" )add_library (demo ${SRC_LIST} )file (GLOB SRC_LIST "*.cpp" )file (GLOB SRC_PROTOCOL_LIST "protocol/*.cpp" )add_library (demo ${SRC_LIST} ${SRC_PROTOCOL_LIST} )file (GLOB_RECURSE SRC_LIST "*.cpp" ) file (GLOB SRC_PROTOCOL RELATIVE "protocol" "*.cpp" ) add_library (demo ${SRC_LIST} ${SRC_PROTOCOL_LIST} )aux_source_directory (. SRC_LIST)aux_source_directory (protocol SRC_PROTOCOL_LIST)add_library (demo ${SRC_LIST} ${SRC_PROTOCOL_LIST} )
查找指定的库文件 1 2 3 4 5 6 7 8 9 10 11 find_library (VAR name path) find_library ( log-lib log )
设置包含的目录 1 2 3 4 5 6 7 8 9 10 11 12 include_directories ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} /include ) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}" )add_subdirectory (source_dir [binary_dir] [EXCLUDE_FROM_ALL])
设置链接库搜索目录 1 2 3 4 5 6 link_directories ( ${CMAKE_CURRENT_SOURCE_DIR} /libs ) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs" )
设置 target需要链接的库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 target_link_libraries ( demo ${log-lib} ) target_link_libraries (demo libface.a) target_link_libraries (demo libface.so) target_link_libraries (demo ${CMAKE_CURRENT_SOURCE_DIR} /libs/libface.a)target_link_libraries (demo ${CMAKE_CURRENT_SOURCE_DIR} /libs/libface.so)target_link_libraries (demo ${CMAKE_CURRENT_SOURCE_DIR} /libs/libface.a boost_system.a boost_thread pthread )
打印信息 1 2 3 4 5 6 message (${PROJECT_SOURCE_DIR} )message ("build with debug mode" )message (WARNING "this is warnning message" )message (FATAL_ERROR "this build has many error" )
包含其它cmake文件 1 2 3 4 5 include (./common.cmake) include (def) set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR} /cmake)
文件操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 configure_file (<input> <output> [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS | FILE_PERMISSIONS <permissions>...] [COPYONLY] [ESCAPE_QUOTES] [@ONLY] [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ]) file (READ <filename> <out-var> [...])file (STRINGS <filename> <out-var> [...])file (<HASH> <filename> <out-var>)file (TIMESTAMP <filename> <out-var> [...])file (GET_RUNTIME_DEPENDENCIES [...])file ({WRITE | APPEND} <filename> <content>...)file ({TOUCH | TOUCH_NOCREATE} [<file >...])file (GENERATE OUTPUT <output-file > [...])file (CONFIGURE OUTPUT <output-file > CONTENT <content> [...])file ({GLOB | GLOB_RECURSE} <out-var> [...] [<globbing-expr>...])file (MAKE_DIRECTORY [<dir>...])file ({REMOVE | REMOVE_RECURSE } [<files>...])file (RENAME <oldname> <newname> [...])file (COPY_FILE <oldname> <newname> [...])file ({COPY | INSTALL } <file >... DESTINATION <dir> [...])file (SIZE <filename> <out-var>)file (READ_SYMLINK <linkname> <out-var>)file (CREATE_LINK <original> <linkname> [...])file (CHMOD <files>... <directories>... PERMISSIONS <permissions>... [...])file (CHMOD_RECURSE <files>... <directories>... PERMISSIONS <permissions>... [...])file (REAL_PATH <path> <out-var> [BASE_DIRECTORY <dir>] [EXPAND_TILDE])file (RELATIVE_PATH <out-var> <directory> <file >)file ({TO_CMAKE_PATH | TO_NATIVE_PATH} <path> <out-var>)file (DOWNLOAD <url> [<file >] [...])file (UPLOAD <file > <url> [...])file (LOCK <path> [...])file (ARCHIVE_CREATE OUTPUT <archive> PATHS <paths>... [...])file (ARCHIVE_EXTRACT INPUT <archive> [...])
编译选项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 option (<variable> "<help_text>" [value])add_compile_definitions (<definition> ...)add_compile_options (<option > ...)
其他 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 add_libraries(LIB1 SHARED ${src_lib1} ) set_property (TARGET LIB1 PROPERTY POSITION_INDEPENDENT_CODE ON ) set_property (TARGET LIB1 PROPERTY COMPILE_FLAGS " -DMACRO1 -DMACRO2" ) set_target_properties (${obj} PROPERTIES C_VISIBILITY_PRESET hidden)set_target_properties (${obj} PROPERTIES CXX_VISIBILITY_PRESET hidden)set (CMAKE_C_VISIBILITY_PRESET hidden)set (CMAKE_CXX_VISIBILITY_PRESET hidden)set (CMAKE_C_FLAGS$ "${CMAKE_C_FLAGS} -fvisibility = hidden" )set (CMAKE_CXX_FLAGS$ "${CMAKE_CXX_FLAGS} -fvisibility = hidden" )SET_TARGET_PROPERTIES (hello_static PROPERTIES OUTPUT_NAME "hello" )SET_TARGET_PROPERTIES (hello PROPERTIES CLEAN_DIRECT_OUTPUT 1 )SET_TARGET_PROPERTIES (hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1 )<NAME>_FOUND <NAME>_INCLUDE_DIRS or <NAME>_INCLUDES <NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS <NAME>_DEFINITIONS
编译项目 单个源文件 假设现在我们的项目中只有一个源文件 main.cc ,该程序的用途是计算一个数的指数幂。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <stdio.h> #include <stdlib.h> double power (double base, int exponent) { int result = base; int i; if (exponent == 0 ) { return 1 ; } for (i = 1 ; i < exponent; ++i){ result = result * base; } return result; } int main (int argc, char *argv[]) { if (argc < 3 ){ printf ("Usage: %s base exponent \n" , argv[0 ]); return 1 ; } double base = atof(argv[1 ]); int exponent = atoi(argv[2 ]); double result = power(base, exponent); printf ("%g ^ %d is %g\n" , base, exponent, result); return 0 ; }
编写 CMakeLists.txt
首先编写 CMakeLists.txt 文件,并保存在与 main.cc 源文件同个目录下:
1 2 3 4 5 6 7 8 # CMake 最低版本号要求 cmake_minimum_required (VERSION 2.8) # 项目信息 project (Demo1) # 指定生成目标 add_executable(Demo main.cc)
CMakeLists.txt 的语法比较简单,由命令、注释和空格组成,其中命令是不区分大小写的。符号 # 后面的内容被认为是注释。命令由命令名称、小括号和参数组成,参数之间使用空格进行间隔。
对于上面的 CMakeLists.txt 文件,依次出现了几个命令:
cmake_minimum_required:指定运行此配置文件所需的 CMake 的最低版本;
project:参数值是 Demo1,该命令表示项目的名称是 Demo1 。
add_executable: 将名为 main.cc 的源文件编译成一个名称为 Demo 的可执行文件。
编译项目
之后,在当前目录执行 cmake . ,得到 Makefile 后再使用 make 命令编译得到 Demo1 可执行文件。
多个源文件 现在假如把 power 函数单独写进一个名为 MathFunctions.c 的源文件里,使得这个工程变成如下的形式:
1 2 3 4 5 6 7 /Demo2 | +--- main.cc | +--- MathFunctions.cc | +--- MathFunctions.h
这个时候,CMakeLists.txt 可以改成如下的形式:
1 2 3 4 5 6 7 8 cmake_minimum_required (VERSION 2.8 )project (Demo2)add_executable (Demo main.cc MathFunctions.cc)
唯一的改动只是在 add_executable 命令中增加了一个 MathFunctions.cc 源文件。这样写当然没什么问题,但是如果源文件很多,把所有源文件的名字都加进去将是一件烦人的工作。更省事的方法是使用 aux_source_directory 命令,该命令会查找指定目录下的所有源文件,然后将结果存进指定变量名。其语法如下:
1 aux_source_directory (<dir> <variable>)
因此,可以修改 CMakeLists.txt 如下:
1 2 3 4 5 6 7 8 9 10 11 12 cmake_minimum_required (VERSION 2.8 )project (Demo2)aux_source_directory (. DIR_SRCS)add_executable (Demo ${DIR_SRCS} )
这样,CMake 会将当前目录所有源文件的文件名赋值给变量 DIR_SRCS ,再指示变量 DIR_SRCS 中的源文件需要编译成一个名称为 Demo 的可执行文件。
多个目录,多个源文件 现在进一步将 MathFunctions.h 和 MathFunctions.cc 文件移动到 math 目录下。
对于这种情况,需要分别在项目根目录 Demo3 和 math 目录里各编写一个 CMakeLists.txt 文件。为了方便,我们可以先将 math 目录里的文件编译成静态库再由 main 函数调用。
根目录中的 CMakeLists.txt :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cmake_minimum_required (VERSION 2.8 )project (Demo3)aux_source_directory (. DIR_SRCS)add_subdirectory (math )add_executable (Demo main.cc)target_link_libraries (Demo MathFunctions)
该文件添加了下面的内容: 第3行,使用命令 add_subdirectory 指明本项目包含一个子目录 math,这样 math 目录下的 CMakeLists.txt 文件和源代码也会被处理 。第6行,使用命令 target_link_libraries 指明可执行文件 main 需要连接一个名为 MathFunctions 的链接库 。
子目录中的 CMakeLists.txt:
1 2 3 4 5 6 aux_source_directory (. DIR_LIB_SRCS)add_library (MathFunctions ${DIR_LIB_SRCS} )
在该文件中使用命令 add_library 将 src 目录中的源文件编译为静态链接库。