灵感来源: 'CI构建'用在非'C/C++'的工程中,只做'集成',不做'编译'
注意选择'对应的版本'解读 -->这里选择'3.16、3.17'
应用场景: 工程需要'编译'第'三方'源码,但是'第三方'源码和'自研'源码'不在'同一目录下
① 官网文档
语法: 'ExternalProject_Add'(<name> [<option>...])
+++++++++++++++++++++'参数解读'+++++++++++++++++++++
1)URL:代码'外部依赖'的路径
2)DOWNLOAD_DIR:存放'下载文件'的路径
3)SOURCE_DIR:存入'编译源文件'的路径
4)CONFIGURE_COMMAND:执行'shell命令、脚本、cmake命令等'
5)BINARY_DIR:输出目前的目录,也就是'平常'使用的'build目录'
6)INSTALL_COMMAND:等效于手动输入"make install"
② ExternalProject_Add实践
set(libhello_src ${CMAKE_CURRENT_SOURCE_DIR}/libhello/src)
set(libhello_binary ${CMAKE_CURRENT_SOURCE_DIR}/libhello/build)
set(libhello_download ${CMAKE_CURRENT_SOURCE_DIR}/libhello/download)
set(libhello_install ${CMAKE_CURRENT_SOURCE_DIR}/libhello/install)
ExternalProject_Add(libhello
URL可以直接使用'本地路径',但是文件必需为'压缩'文件
URL "/Users/wangshengxing/project/c/cmake/sharelib.zip"
DOWNLOAD_DIR ${libhello_download}
SOURCE_DIR "${libhello_src}"
# 思考: 如何调用shell脚本?
CONFIGURE_COMMAND ${CMAKE_COMMAND} ${libhello_src} -DCMAKE_INSTALL_PREFIX=${libhello_install}
BINARY_DIR ${libhello_binary}
# 等价-->CMAKE_BUILD_TOOL 实际构建过程中'使用的工具'-->'make、gmake'
INSTALL_COMMAND ${CMAKE_MAKE_PROGRAM} install
)
add_custom_target的'用处':增加一个'没有输出'的目标,使得它'总是被构建'
① 官方文档
② 常见参数解读
1)增加一个'自定义名字'的目标,并执行'指定的命令[非必须,多个命令可以写在COMMAND中]'
备注: 该目标'没有输出'文件,区别于'C/C++'工程
2)COMMENT "str_comment" 在'构建'的时候,该值会被'当成信息'在执行'命令(COMMAND)之前'显示 -->"重点"
3)WORKING_DIRECTORY 'dir_name' 该命令将会在'指定的目录'中运行-->"重点"
备注: 如果它是个'相对路径',那它会被'解析'为相对于'当前源码目录'对应的'构建目录' -->外部构建'build目录'
补充: 不推荐'使用默认(build目录-->污染)'或者'脚本的全路经',最好自定义该参数将'脚本'放到同一'目录下'
4)COMMAND command2 [args2...] '需要执行的命令' --> 'shell(命令、脚本)、python、cmake等' -->"重点"
'备注1':${CMAKE_COMMAND}是'cmake'的路径,'-E'使CMake'运行命令'而不是构建 -->'cmake命令'
'备注2':COMMAND bash ceshi.sh 1 2 -->'执行shell脚本(传参)'
'备注3':COMMAND bash -c 'python hello.py' -->'执行python脚本(也可以传参)'
思考: 脚本的'路径'-->'相对哪个?'
5)ALL 表明该目标会'被添加'到默认的构建目标,使得它'每次都被运行'
6)DEPENDS 指定'命令'所'依赖'的文件
③ 实践1
讲解: 'COMMENT'、'COMMAND'讲解
1)项目初始化
2)CMakeLists.txt文件
3)ceshi.sh脚本
4)测试1
保存: '脚本文件'找不到
5)测试2
修改: 'ceshi.sh'脚本'修改'为'绝对路径'
+++++++++++++++'常用的cmake内置变量'+++++++++++++++
1)CMAKE_CURRENT_'SOURCE'_DIR
当前处理的 'CMakeLists.txt' 所在的'路径'
2)CMAKE_CURRENT_'LIST'_DIR
自2.8.3开始,这是当前'正在处理'的'列表文件'的目录
说明: 执行之后'没有'任何'target'产物
备注: 其它'执行'方式-->'make target'
CMake命令之add_custom_comand 和 add_custom_target
④ 实践2
讲解: 'DEPENDS'
1)先自定义command、再自定义target
2)测试
⑤ 实践3
解读: 'ALL'参数 -->'重要'
+++++++++++++++'(1)'不加ALL+++++++++++++++
效果: 不加'ALL'参数make的时候,只会生成'二进制文件、库',默认'不会'生成自定义的target,也即'不会'执行自定义target'对应的命令',如果'需要'在生成'add_executable和add_library时',则需要指定
eg:make --target name
好处:可以更加'细粒度'的控制,但是多写'字符'
+++++++++++++++'(2)'加ALL+++++++++++++++
效果:所有('包括自定义')的'target'都会执行-->'推荐'
1)没有ALL参数
2)有ALL参数
⑥ 小结
理解上: 就是执行'一系列命令(shell、python等)'而已,将原来'shell命令(裸执行)'的方式通过'CMakeLists.txt'中'add_custom_target'的COMMAND来'体现'
① 使用execute_process调用shell命令或脚本
execute_process(COMMAND sh test.sh WORKING_DIRECTORY <test.sh所在目录>)
② 区别
1)在cmake中可以通过'add_custom_comand' 和 'add_custom_target'执行shell命令,但是他们是一般执行命令'跟target的生成'有关
2)execute_process只是'简单地'在cmake执行编译之前'调用shell命令',具体使用需要'结合需求'来选择
① 官方解读
依赖--> 有'先后顺序'
CMake的如何'正确'地创建'目标之间的依赖关系'
add_dependencies(Project 'Dependency')
add_dependencies可以在直接'编译上层target'时,'自动检查'下层依赖库'是否'已经生成;'没有'的话先'编译下层'依赖库,然后再'编译上层'target
② 参考博客