CMake用法总结
CMakeLists.txt首部增加对CMake的版本限制:
CMAKE_MINIMUN_REQUIRED(VERSION 2.6)
定义工程名:
PROJECT (MyProject [CXX] [C] [JAVA]) //默认支持所有语言
输出提示信息:
MESSAGE ([SEND_ERROR | STATUS | FATAL_ERROR] "message")
生成可执行对象:
ADD_EXECUTABLE (MyExe ${SRC_FILES})
生成子目录下的模块或程序并放在build的相应子目录下:
ADD_SUBDIRECTORY(source_dir [binary_dir])
制定二进制目标的保存位置:
无论是否在ADD_SUBDIRECTORY中制定了编译输出目录,都可以制定最终二进制的位置
SET (EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET (LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
在哪里ADD_EXECUTABLE或ADD_LIBRARY,就在哪个CMakeLists.txt中放上述的定义
设置变量:
SET (variable_name variable_value)
增加配置文件模板,用来生成源码中可用的头文件:
CONFIGURE_FILE(
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
该用法中,模板文件主要有以下用法:
a. /// @variable_name@ 部分会替换成为CMAKE里设置的变量的值
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
b. /// #cmakedefine variable_name 会根据CMAKE文件中变量是否为真决定是否要定义该变量
#cmakedefine variable_name
增加INCLUDE目录:
INCLUDE_DIRECTORIES ("${PROJECT_BINARY_DIR}")
载入其他cmake文件:
INCLUDE (file1)
INCLUDE (module)
生成静态库、动态库:
ADD_LIBRARY (MyLib [SHARED | STATIC | MODULE] "${SRC_FILES}")
增加链接对象:
TARGET_LINK_LIBRARIES (MyExe "${LIB_NAMES}")
制定编译选项的内置变量:
CMAKE_C_FLAGS,设置C编译选项,也可以通过ADD_DEFINITIONS()添加
CMAKE_CXX_FLAGS,支持C++编译选项,也可以通过ADD_DEFINITIONS()
增加选项以及逻辑判断(样例):
OPTION(USE_MYMATH "Use tutorial provided math implementation" ON)
IF (USE_MYMATH)
INCLUDE_DIRECTORIES ("${PROJECT_SOURCE_DIR}/MathFunctions")
ADD_SUBDIRECTORY (MathFunctions)
SET (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
ENDIF (USE_MYMATH)
同时相应增加代码中的#ifdef USE_MYMATH逻辑
有IF的地方一定要有ENDIF,有ELSEIF的地方ENDIF可选
IF (expression1)
COMMAND1
COMMAND2
ELSE (expression1)
command1
command2
ENDIF (expression1)
IF (WIN32)
COMMAND1
ELSEIF (UNIX)
COMMAND2
ELSEIF (APPLE)
COMMAND3
ENDIF (WIN32)
CMake中系统信息的内置变量:
CMAKE_SYSTEM,系统名称,比如Linux-2.6.22
CMAKE_SYSTEM_NAME,不包含版本的系统名,比如Linux
UNIX,所有的类UNIX平台上为TRUE,包括OS X和cygwin
WIN32,所有win32平台上为TRUE,包括cygwin
CMake常用变量:
CMAKE_BINARY_DIR & PROJECT_BINARY_DIR,执行cmake的目录。
CMAKE_SOURCE_DIR $ PROJECT_SOURCE_DIR,工程顶层目录
CMAKE_CURRENT_SOURCE_DIR,当前处理的CMakeLists.txt的所在路径
CMAKE_CURRENT_BINARY_DIR,当前处理的CMakeLists.txt的输出路径
增加项目依赖:
ADD_DEPENDENCIES,定义target依赖其他target,保证在编译本target之前,其他target已经被构建。
ADD_DEPENDENCIES (target-name depend-target1 depend-target2)
文件操作:
FILE (WRITE filename "message to write")
FILE (APPEND filename "message to write")
FILE (READ filename variable)
FILE (GLOB variable [RELATIVE PATH] [GLOBBING EXPRESSIONS])
FILE (GLOB_RECURSE variable [RELATIVE PATH] [GLOBBING EXPRESSIONS])
FILE (REMOVE [DIRECTORY])
FILE (REMOVE_RECURSE [DIRECTORY])
FILE (MAKE_DIRECTORY [DIRECTORY])
设置make install的安装路径:
INSTALL (TARGETS Tutorial DESTINATION bin)
INSTALL (FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h" DESTINATION include)
注意CMAKE_INSTALL_PREFIX变量,按如上方式分别会安装到 ${CMAKE_INSTALL_PREFIX}/bin ${CMAKE_INSTALL_PREFIX}/include
增加make test的测试用例:
// 用指定参数运行
ADD_TEST (${TestName} ${TargetName} ${ARGS})
// 检验输出结果中有没有制定的正则式的子串
SET_TESTS_PROPERTIES (${TestName} PROPERTIES PASS_REGULAR_EXPRESSION "${RESULT_SUBSTRING}")
检测系统是否有某函数:
INCLUDE (CheckFunctionExists) 或者 INCLUDE (${CMAKE_ROOT}/Modules/CheckFunctionExists.cmake)
CHECK_FUNCTION_EXISTS (log HAVE_LOG)
CHECK_FUNCTION_EXISTS (exp HAVE_EXP)
需要注意的:
a. CMake对于 module 与 file 的处理方式是不一样的,module 只要写 module name 就可以了。
b. 教程以 log 和 exp 函数为例。结果呢,是大出意料:找不到。想到一个问题:Linux 下面有无数 library , CMake 不可能无端知道这个函数在哪个库里。所以查手册,加上一句:set(CMAKE_REQUIRED_LIBRARIES “m”)