本文主要用来记录使用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使用(可删除此段)
# STATUS:正常输出 WARNING:警告 FATAL_ERROR:异常
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