有多个路径的话要给每个路径都创建CMakeLists。

创建工程名称的指令: PROJECT(projectname [CXX] [C] [Java]) 工程名之后的语言列表是可以省略的

两个预定义变量: PROJECT_BINARY_DIRPROJECT_SOURCE_DIR 内部编译时这两个变量指向同一个路径 外部编译时不同

定义变量: SET(VAR [VALUE]) VALUE可以有多个值,用空格隔开

MESSAGE指令可向终端输出信息: MESSAGE([SEND_ERROR|STATUS|FATAL_ERROR] "message to display") SEND_ERROR,会打印错误消息,并跳过生成过程 STATUS,打印带前缀-的消息 FATAL_ERROR,会立即终止

生成一个可执行文件: ADD_EXECUTABLE(hello ${SRC_LIST}) 取变量值使用${}

指令都应该大写,参数之间用空格隔开,如果参数中使用了空格,应该用双引号引起来

可以使用make clean清理构建结果 但是不能使用make distclean命令清理中间文件

外部编译就是在工程下创建一个文件夹 比如新建一个build文件夹,进入build文件夹,执行cmake ..就可以 这样就分离了源代码和构建的中间结果

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 向当前工程添加存放源代码的子目录,并且可以指定中间二进制和目标二进制文件存放位置,EXCLUDE_FROM_ALL会将该目录排除在编译过程外 ADD_SUBDIRECTORY(src bin)就会在构建目录下创建bin目录,相当与将src目录重命名为bin

在定义ADD_EXECUTABLE的文件中定义SET(EXECUTABLE_OUTPUT_PATH ${PRJECT_BINARY_DIR}/bin)可以指定生成的二进制文件位置

INSTALL指令来指定安装位置 执行cmake ..的时候可以指定-DCMAKE_INSTALL_PREFIX=/sth/sth/sth来设置路径前缀 INSTALL安装指令放在项目的CMakeLists.txt中

编译共享库和编译可执行文件是类似的,可以通过SET(LIBRARY_OUTPUT_PATH )来指定共享库的生成路径

ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ...) libname不需要指定后缀

为了指定相同名称的静态库和动态库,可以使用指令SET_TARGET_PROPERTIES SET_TARGET_PROPERTIES(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...)

获取设置的属性名使用GET_TARGET_PROPERTY(VAR target property)指令

如果构建生成.a后.so被删除,则设置CLEAN_DIRECT_OUTPUT来解决:

SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)

设置版本号SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1) VERSION是动态链接库版本,SOVERSION是API版本

安装库时使用:

INSTALL(TARGETS hello hello_static
   LIBRARY DESTINATION lib
   ARCHIVE DESTINATION lib)

安装文件使用INSTALL(FILES hello.h DESTINATION include/hello)

使用外部库: INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)设置搜索的头文件路径 SET(CMAKE_INCLUDE_DIRECTORIES_BEFORE on)可以将添加的头文件搜索路径放在已有路径前面,AFTER类似 LINK_DIRECTORIES(dir1 dir2 ...)设置搜索共享库的路径,该命令必须放在ADD_EXECUTABLE前面 TARGET_LINK_LIBRARIES(target lib1 <debug | optimized> lib2 ...)为目标文件添加共享库

还可以使用通用的方法提供搜索路径,在bash的变量中定义CMAKE_INCLUDE_PATH=dir然后在cmake文件中使用FIND_PATH()指令指定搜索路径,同样的,CMAKE_LIBRARY_PATH=dir用来设置搜索库的路径,FIND_LIBRARY()用来搜索

引用变量时,在IF中引用不需要使用${}

CMAKE自带常量:

CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR 

这三个变量指向同一内容,内部编译指向工程顶层目录,外部编译则指向工程编译发生的目录

CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR

该指令和上面的差不多,都指向项目顶层目录

CMAKE_CURRENT_SOURCE_DIR指当前CMakeLists.txt所在路径

CMAKE_CURRENT_BINARY_DIR内部编译时与CMAKE_CURRENT_SOURCE_DIR一致,外部编译时指target目录,ADD_SUBDIRECTORY(src bin)就可以改变这个变量

CMAKE_CURRENT_LIST_FILE输出调用这个变量的CMakeLists.txt的完整路径

CMAKE_CURRENT_LIST_LINE该变量所在的行

CMAKE_MODULE_PATH定义cmake模块所在路径,使用SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)这样的方式设置值,然后可以用INCLUDE指令调用

EXECUTABLE_OUTPUT_PATHLIBRARY_OUTPUT_PATH用来定义最终结果的存放目录

PROJECT_NAME为项目名称

$ENV{NAME}该指令用来调用系统环境变量

SET(ENV{变量名} 值)设置环境变量

CMAKE_INCLUDE_CURRENT_DIR自动添加CMAKE_CURRENT_BINARY_DIRCMAKE_CURRENT_SOURCE_DIR到当前CMakeLists.txt中

CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE将工程设置的头文件目录在系统头文件目录前,冲突时会优先使用工程的

CMAKE_MAJOR_VERSIONCMAKE_MINOR_VERSIONCMAKE_PATCH_VERSION这三个代表了比如2.4.6中的2,4,6三个版本号

CMAKE_SYSTEM表示系统名称

CMAKE_SYSTEM_NAME表示不包含版本号的系统名

CMAKE_SYSTEM_VERSION系统版本号

CMAKE_SYSTEM_PROCESSOR处理器名称

UNIX类UNIX平台为TRUE

WIN32所有win32平台为TRUE

CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS控制IF ELSE的书写方式

BUILD_SHARED_LIBS是指为ON会默认编译动态库,否则为静态库

CMAKE_C_FLAGS设置C编译选项

CMAKE_CXX_FLAGS设置C++编译选项

基本指令 ADD_DEFINITIONS给编译器添加-D定义,多个参数用空格分开 如:ADD_DEFINITIONS(-DENABLE_DEBUG -DXXX)

ADD_DEPENDENCIES定义依赖的target

ADD_TESTENABLE_TESTING指令控制makefile是否构建test ENABLE_TESTING()一般放在住CMakeLists.txt中 ADD_TEST使用方法:ADD_TEST(mytest ${PROJECT_BINARY_DIR}/bin/main) 在需要测试的目录的CMakeLists.txt中都要加ENABLE_TESTING()

AUX_SOURCE_DIRECTORY(dir VARIABLE)将dir目录下的源文件添加在VARIABLE变量中

CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])设置cmake版本

EXEC_PROGRAM在cmake命令生成Makefile过程中执行命令,如ls查看某个路径的文件,可以用这个指令

FILE指令操作文件

INCLUDE指令用来载入CMakeLists.txt文件

FIND_FILE FIND_LIBRARY FIND_PATH FIND_PROGRAM FIND_PACKAGE用来查找路径

IF指令

IF(expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ELSE(expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDIF(expression)

出现IF的地方必须有ENDIF

WHILE指令

WHILE(condition)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDWHILE(condition)

`FOREACH`指令有三种形式
第一种
```cmake
FOREACH(loop_var arg1 arg2 ...)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDFOREACH(loop_var)

第二种

FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)

第三种

FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)