本文主要用来记录使用CMake在编译代码时一些常用命令,及过程中注意的点。
CMake官方使用教程文档
# cmake的最低版本要求
cmake_minimum_required(VERSION 3.8)# 工程名称和版本
project(main VERSION 1.0)# 指定的C++编译器版本是必须的
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 指定为C++14 版本
set(CMAKE_CXX_STANDARD 14)# 为特定程序指定编译属性
set_property(TARGET ${CMAKE_PROJECT_NAME} PROPERTY CXX_STANDARD 14)# 可以添加一个编译的子路径,在子路径中查找CMakeLists.txt文件,并进行编译
# add_subdirectory(test)# 定义Include目录,方便后续建立依赖引用
# 判断运行环境
if(WIN32)set(Camport_DIR c:/camport3)
elseif(UNIX)set(Camport_DIR /home/bing/camport3)
endif()# 查找OpenCV包
find_package(OpenCV)# 输出OpenCV相关信息到编译日志,debug使用(可删除此段)
message(STATUS "OpenCV:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")# 指定包含文件
file(GLOB SOURCE_FILES ${CMAKE_SOURCE_DIR}/*.cpp)# 指定编译文件名及编译可执行文件
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})# 对目标的外部库进行链接操作
target_link_libraries (${CMAKE_PROJECT_NAME}${OpenCV_LIBS}${Camport_DIR}/lib/linux/lib_x64/*.so
)# 为指定项目添加 include 路径
include_directories(${PROJECT_SOURCE_DIR}/include${Camport_DIR}/include${Camport_DIR}/sample
)
add_library: 为生成的库添加源文件,是库的名字,直接写名字即可,不要写lib,会自动加上前缀。 STATIC表示静态库(lib),SHARED表示动态库(so)
add_library( [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL]source1 [source2 ...])
CMakeLists.txt实例
# cmake的最低版本要求
cmake_minimum_required(VERSION 3.8)# 工程名称和版本
project(main VERSION 1.0)# 指定的C++编译器版本是必须的
set(CMAKE_CXX_STANDARD_REQUIRED ON)# 指定为C++14 版本
set(CMAKE_CXX_STANDARD 14)# 为特定程序指定编译属性
set_property(TARGET ${CMAKE_PROJECT_NAME} PROPERTY CXX_STANDARD 14)# 定义Include目录,方便后续建立依赖引用
# 判断运行环境
if(WIN32)set(Camport_DIR c:/camport3)
elseif(UNIX)set(Camport_DIR /home/bing/camport3)
endif()# 查找OpenCV包
find_package(OpenCV)# 输出OpenCV相关信息到编译日志,debug使用(可删除此段)
message(STATUS "OpenCV:")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")# 指定包含文件
file(GLOB SOURCE_FILES ${CMAKE_SOURCE_DIR}/*.cpp)# 指定编译动态库文件名及动态库类型
add_library(${CMAKE_PROJECT_NAME} SHARED${SOURCE_FILES}
)# 对目标的外部库进行链接操作
target_link_libraries (${CMAKE_PROJECT_NAME}${OpenCV_LIBS}${Camport_DIR}/lib/linux/lib_x64/*.so
)# 为指定项目添加 include 路径
include_directories(${PROJECT_SOURCE_DIR}/include${Camport_DIR}/include${Camport_DIR}/sample
)
在外部指令中使用 ${} 进行变量的引用。在 IF 等语句中,是直接使用变量名而不通过 ${} 取值。
如果是in source编译,这个变量指得就是工程顶层目录,如果是out-of-source编译,指的是工程编译发生的目录。另外 和 CMAKE_BINARY_DIR 跟这个变量指代的内容是一致的。
不论采用何种编译方式,都是工程顶层目录。也就是在in source编译时,他跟PROJECT_BINARY_DIR等变量一致。另外和CMAKE_SOURCE_DIR跟这个变量指代的内容是一致的。
指的是当前处理的CMakeLists.txt所在的路径。
如果是in-source编译,它跟CMAKE_CURRENT_SOURCE_DIR一致,如果是out-ofsource编译,他指的是 target 编译目录。使用ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。
输出调用这个变量的CMakeLists.txt的完整路径。
输出这个变量所在的行。
这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理CMakeLists.txt时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。比如
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
这时候你就可以通过 INCLUDE 指令来调用自己的模块了。
前者用来重新定义目标二进制可执行文件的存放位置,后者用来重新定义目标链接库文件的存放位置。
返回通过 PROJECT 指令定义的当前项目名称。
project(A) add_subdirectory(B)
返回根项目的项目名称,比如B项目是A项目的子项目,在B项目中获取CMAKE_PROJECT_NAME得到的结果是A,获取PROJECT_NAME得到的结果是B