资料:
文档:https://www.zybuluo.com/khan-lau/note/254724
常规使用:https://zhuanlan.zhihu.com/p/315768216
1、生成文件的过程
半路出家没学过编译原理,这只是个人理解。c++的编译采用了分离编译,先编译后链接的方式。分离编译的时候,先将不同的cpp文件编译成目标文件(执行文件和库文件),再链接到一起。
因为是分离编译的,所以单独的cpp文件中,可能会用到没有在本文件定义的变量和函数,这个时候就要利用头文件。头文件会在编译之前的预编译阶段用到,会告诉编译器之后将定义哪些变量和函数,为用到这些变量和函数的文件说明这些“未知”变量和函数的类型,就像留下特定的“接口”,之后在链接阶段再将不同的目标文件根据这些接口链接在一起。
库文件有两种,一种是用自己编写的cpp文件生成的库文件,另一种是第三方的库(动态库.so和静态库.a)。
2、常见命令和用法
可能是没有学过编译原理的原因,我感觉cmake的语法挺乱的,好像格式类似的语法没有相同的性质,也只能硬记了。
(1)基础配置
命令 | 实例 | 作用 |
---|---|---|
cmake_minimum_required | cmake_minimum_required(VERSION 3.5) | 设置cmake最低版本 |
project | project(demo) | 生成项目 |
(2)生成目标文件
命令 | 实例 | 作用 |
---|---|---|
add_library | add_library(${PYMODULE} STATIC ${SOURCE_FILES}) | 生成库文件 |
add_executable | add_executable(hello world.c) | 生成执行文件 |
(3)设置头文件
命令 | 实例 | 作用 |
---|---|---|
include_directories | include_directories(${PYTHON_INCLUDE_DIR}) | 搜索头文件时,添加搜索路径。影响范围大,本目录下的文件都会添加 |
target_include_directories | target_include_directories(clib PRIVATE ${CURL_INCLUDE_DIR}) | 给指定目标添加头文件搜索路径 |
(4)链接目标文件
命令 | 实例 | 作用 |
---|---|---|
LINK_LIBRARIES | LINK_LIBRARIES(“/opt/MATLAB/R2012a/bin/glnxa64/libeng.lib”) | 链接静态库文件 |
target_link_libraries | target_link_libraries(${PYMODULE} ${Boost_LIBRARIES}) | 给指定目标添加链接文件 |
(5)安装到制定位置
- 使用make编译完成之后,有时候会使用make install去安装编译结果。这个功能在cmakelists里就是使用install完成的,即install用于指定安装规则,所谓安装规则就是将编译的结果复制到制定的位置。
- 安装目标到指定位置
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 静态库
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 动态库
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 运行时的依赖文件
)
- 安装文件到制定位置
install(FILES plugin_description.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
(6)其他操作
命令 | 实例 | 作用 |
---|---|---|
find_package | find_package(PythonLibs 3.7 REQUIRED) | 通过cmake编译的库,可以这样快速查找,会得到路径、库、头文件的相关信息 |
message | message(PYTHON_INCLUDE_DIR " ${PYTHON_INCLUDE_DIR}") | 打印log |
set | set(BOOST_ROOT D:/boost_1_72_0) | 设置局部变量 |
if-else
if(expression1)
# commands ...
elseif(expression2)
# commands ...
else()
# commands ...
endif()
else(expression1)和endif(expression1)可以简化成else()和endif()
3、添加静态库和动态库的常见方法
(1)静态库
#设置链接目录
link_directories( ${PROJECT_SOURCE_DIR}/lib/linux)
#链接静态库
link_libraries(
lib1.a
lib2.a
)
(2)动态库
target_link_libraries(所需生成的文件名称 所需链接的动态库名称)
(3)自定义的cpp文件
#########################1、基础设置#####################################33
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
project(vector_project)
#########################2、生成执行文件和库#####################################33
add_executable(vector_test ./src/vector_test.cpp) #生成执行文件。当前路径就在cmakelist在的地址
add_library(utils
/home/wangyuanhao/core_repository/c-_example/cmake_test/src/utils_test.cpp
) #生成库
#########################3、包括头文件#####################################33
//target_include_directories(vector_test PUBLIC ./include/)
target_include_directories(utils PRIVATE ./include/)
target_include_directories(vector_test PRIVATE ./include/)
//nclude_directories(vector_test PUBLIC ./include/)
#########################4、把库链接到执行文件#####################################33
target_link_libraries(vector_test utils) #库链接到执行文件