image.png
cmake
image.png
CMake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装编译过程。
他能够输出各种各样的makefile或者project文件,能测编译器所支持的C 特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。
Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C 的 projects/workspaces),然后再依一般的建构方式使用。
这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件,这种可以使用各平台的原生建构系统的能力是 CMake 和 SCons 等其他类似系统的区别之处。
使用实例
步骤一
编写 CMake 配置文件 CMakeLists.txt 。
CMakeLists.txt 实例:
代码语言:javascript复制# 本CMakeLists.txt的project名称
# 会自动创建两个变量,PROJECT_SOURCE_DIR和PROJECT_NAME
# ${PROJECT_SOURCE_DIR}:本CMakeLists.txt所在的文件夹路径
# ${PROJECT_NAME}:本CMakeLists.txt的project名称
project(xxx)
# 获取路径下所有的.cpp/.c/.cc文件,并赋值给变量中
aux_source_directory(路径 变量)
# 给文件名/路径名或其他字符串起别名,用${变量}获取变量内容
set(变量 文件名/路径/...)
# 添加编译选项
add_definitions(编译选项)
# 打印消息
message(消息)
# 编译子文件夹的CMakeLists.txt
add_subdirectory(子文件夹名称)
# 将.cpp/.c/.cc文件生成.a静态库
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
add_library(库文件名称 STATIC 文件)
# 将.cpp/.c/.cc文件生成可执行文件
add_executable(可执行文件名称 文件)
# 规定.h头文件路径
include_directories(路径)
# 规定.so/.a库文件路径
link_directories(路径)
# 对add_library或add_executable生成的文件进行链接操作
# 注意,库文件名称通常为libxxx.so,在这里只要写xxx即可
target_link_libraries(库文件名称/可执行文件名称 链接的库文件名称)
步骤二
执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile PATH 是 CMakeLists.txt 所在的目录。
步骤三
使用 make 命令进行编译。
CMakeList语法
cmake版本要求
代码语言:javascript复制cmake_minimum_required( VERSION 2.8 )
工程名字
工程文件名test123,可任取
代码语言:javascript复制project( test123)
编译模式设置
代码语言:javascript复制IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release)
ENDIF()
set(CMAKE_BUILD_TYPE debug)
添加依赖库
如果包含第三方库,为库形式(此处以静态库为例(.a后缀))
代码语言:javascript复制set( DBoW3_INCLUDE_DIRS "/usr/local/include")
set( DBoW3_LIBS "/usr/local/lib/libDBoW3.a")
target_link_libraries(${PROJECT_NAME}
${DBoW3_LIBS}
)
设置编译类型
代码语言:javascript复制add_executable(demo demo.cpp) # 生成可执行文件
add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库
搜索所有的 cpp 文件
aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。
代码语言:javascript复制aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})
设置包含的目录
代码语言:javascript复制include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
代码语言:javascript复制
设置链接库目录
代码语言:javascript复制link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs
)
Linux 下还可以通过如下方式设置包含的目录
代码语言:javascript复制set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")
设置 target 需要链接的库
代码语言:javascript复制target_link_libraries( # 目标库
demo
# 目标库需要链接的库
# log-lib 是上面 find_library 指定的变量名
${log-lib} )
指定链接动态库或静态库
代码语言:javascript复制target_link_libraries(demo libface.a) # 链接libface.a
target_link_libraries(demo libface.so) # 链接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)
环境变量
使用环境变量
代码语言:javascript复制 $ENV{Name}
写入环境变量
代码语言:javascript复制 set(ENV{Name} value) # 这里没有“$”符号
预定义变量
变量 | 含义 |
---|---|
PROJECT_SOURCE_DIR | 工程的根目录 |
PROJECT_BINARY_DIR | 运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build |
PROJECT_NAME | 返回通过 project 命令定义的项目名称 |
CMAKE_CURRENT_SOURCE_DIR | 当前处理的 CMakeLists.txt 所在的路径 |
CMAKE_CURRENT_BINARY_DIR | target 编译目录 |
CMAKE_CURRENT_LIST_DIR | CMakeLists.txt 的完整路径 |
CMAKE_CURRENT_LIST_LINE | 当前所在的行 |
CMAKE_MODULE_PATH | 定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块 |
EXECUTABLE_OUTPUT_PATH | 重新定义目标二进制可执行文件的存放位置 |
LIBRARY_OUTPUT_PATH | 重新定义目标链接库文件的存放位置 |
参考
CMakeLists.txt的超傻瓜手把手教程(附实例源码) CMakeLists.txt 语法介绍与实例演练