【工作向】CMakeLists.txt写作

1. CMakeLists.txt导览

1.1 cmake介绍
  • cmake是GNU工具链中构建项目的重要一环,Linux常用,Windows下有cmake软件
  • cmake根据CMakeLists.txt生成一个编译规则(Makefile文件)
  • 编译器逐个文件进行编译,生成中间件,Makefile是将中间件统一编译的规则
  • 查看cmake版本:cmake --version
1.2 CMakeLists.txt介绍
  • 项目构建,每个需要管理的目录下均存在一个CMakeLists.txt
  • CMakeLists.txt大小写敏感
  • 在需要进行编译的文件夹内编写CMakeList.txt,.cpp/.c的文件夹内
  • 通常将下层目录编译成一个静态库文件,让上层目录直接读取和调用,而上层目录就直接生成一个可执行文件
  • 在最顶层创建build或cmake目录,然后编译
1.3 cmake构建方式
mkdir cmake && cd cmake
cmake ..			# 指定CMakeLists.txt所在目录,cmake实际是做了一个转换,将CMakeLists.txt转换成Makefile文件
make project_name	# 然后由make进行编译,输出project文件

./project_name		# 运行可执行文件

2. CMakeLists.txt基本结构

# 简单举例:

cmake_minimum_required(VERSION 3.9)		# cmake版本【可省略】

project(my_project)						# 项目名称

add_executable							# 添加源文件

target_include_directories				# 添加头文件

target_link_directories					# 库文件目录

target_link_libraries					# 链接库文件

3. 命令介绍

1. set

功能:给文件名/路径名/源文件/库文件等起别名

	set(变量 文件名/路径名/库文件/源文件)
	set(THIRD_PARTY /data/libcommon.so)		// 显示定义变量, 用变量代替值

2. target_link_libraries

功能
将目标文件与库文件进行链接,不然会出现光声明没定义的错误

	# 对add_executable生成的文件进行链接操作
	# 库文件名称通常为libxxx.so,链接时只需要写xxx即可 */

	target_link_libraries(main THIRD_PARTY)		# THIRD_PARTY是多个库文件的别名
	target_link_libraries(main xxx.so)
	target_link_libraries(main xxx.a)

3. if else

功能:条件控制语句

	### 方式1: ###
	if()
		# do something
	endif()
	
	### 方式2: ###
	if(condition1)
		# do something
	elseif(condition2)
		# do something
	else()
		# do something
	endif()
	if (DEFINED cpu AND "${cpu}" STREQUAL "x86")
		set(THIRD_PARTY /x86/.../xx.so)
	else()
		set(THIRD_PARTY /arm/.../xx.so)
	endif()
	
	# DEFINED: 是否定义过
	# AND/OR/NOT:与或非

4. -D和-G选项

功能
-D: 使用cmake -D 创建一个要用的编译类型的cmake缓存
-G:设置指定的生成器,generator,可以设置IDE

	# CMakeLists.txt中使用:
	if (TARGET_CPU STREQUAL "x86")
		# do something
	else()
		# do something
	endif()

5. file

功能
查找头文件/源文件
file参数较多,还有WRITE/READ/RENAME/REMOVE等参数

	file(GLOB HEADER_FILES ${DIR}/*.h)			# 查找DIR目录下所有头文件并保存到HEADER_FILES变量里
	file(GLOB_RECURSE SRC_FILES ${DIR}/*.cpp)	# 查找DIR目录下所有源文件并保存到SRC_FILES变量里

	# GLOB和GLOB_RECURSE推荐使用RECURSE递归版本,避免源文件添加或删除引起识别错误

6. add_executable

功能
添加不同项目要编译的可执行文件
将.cpp/.c/.cc等文件生成可执行文件

	# add_executable(${PROJECT_NAME} xxx.cpp)

	project(test)
	add_executable(test ${SRC_FILES1} ${SRC_FILES2})

7. option

功能
提供一个用户可以选择的选项:ON 或 OFF, 如果不提供初始值,默认为OFF

	option(option_variable "variable description" variable_value)

8. add_definitions

功能
相当于添加编译宏,方便通过命令行而不是改代码进行参数控制
或用于添加编译选项

	option(TORCH_DEBUG "option for torch debug" OFF)
	if(TORCH_DEBUG)
		add_definitions(-DTORCH_DEBUG)
	endif(TORCH_DEBUG)
	/* 源文件中 */
	#ifdef TORCH_DEBUG
	...
	#else
	...
	#endif
  • 构建项目的时候就可以添加参数控制宏的开启和关闭
	cmake -DTORCH_DEBUG=ON ..	# 打开
	cmake -DTORCH_DEBUG=OFF ..	# 关闭
	# 添加编译选项
	add_definitions("-Wall -g")		# 显示所有类型log,用于gdb调试

9. target_include_directories

功能
指定编译target所需要的头文件路径
添加头文件搜索路径,可解决源文件中头文件相对路径引用问题

	# PUBLIC和INTERFACE具有依赖传递性,而PRIVATE没有
	
	PRIVATE: 指这里引用的头文件路径仅仅被这个目标使用,目标不会对外暴露引用的头文件路径
	
	PUBLIC:不仅被这个目标使用,目标还会对外暴露引用的头文件路径
	
	INTERFACE:引用头文件不被这个目标使用,但目标会对外暴露引用的头文件路径
	target_include_directories(test PRIVATE ${OFFLINE_HEADERS})

10. target_link_directories

功能
目标添加链接库的查找目录,只是提供目录,具体链接库文件通过 target_link_libraries 添加
用法和 target_include_directories 基本类似

	# target_link_libraries 		# 链接单个库文件或库文件目录下的所有库文件
	# target_include_directories	# 包含头文件
	
	# 举例
	target_link_directories(test PRIVATE ${OFFLINE_LIB})

11. target_compile_definitions

功能:目标添加编译器编译选项

	target_compile_definitions(test PRIVATE -DUSE_ARM)

12. message

功能:打印消息

	message([mode] "message to display" ...)
	
	mode: 模式,可不写;有STATUS/ERROR/DEBUG/TRACE等选项, STATUS表示一般的打印信息
	"..."	为要显示的内容
	...		表示可以连接多个输出

	message(${STRING})		# 打印STRING变量值

13. add_subdirectory

功能
添加编译的子文件夹
当执行到 add_subdirectory 这一句时会先将子文件夹进行编译生成库文件
在 add_subdirectory 之前set的各个变量,包括子文件中生成的库文件,在子文件夹中可以调用
子文件夹里添加CMakeList.txt就可进行编译

	# 代码结构
	
	|--- example.cpp
	|--- CMakeLists.txt		# add_subdirectory(SubDir)
	|--- SubDir
		|-- subExample.xpp
		|-- subHeader.h
		|-- CMakeLists.yxy
	|--- ThirdParty
		|--- bin			# 可执行文件
		|--- include		# 头文件
		|--- lib			# 库文件

14. aux_source_directory

功能:获取路径下所有的源文件.cpp/.c/.cc文件,并赋值给变量中

	# aux_source_directory(路径 变量)
	
	aux_source_directory(${PROJECT_SRC_DIR} SRC_FILES)

15. add_library

功能:将指定的源文件生成一个目标库

	# add_library(name STATIC/SHARED/MODULE sourceFiles)
	
	name: 库文件名字,全局唯一
	库类型;
		STATIC:静态库,xxx.a
		SHARED:动态库, xxx.so
		MODULE:模块库
	
	# 生成动态库 liboutput.so
	add_library(output SHARED source.cpp)
	
	# 生成静态库 liboutput.a
	add_library(output STATIC source.cpp)

参考文章:
cmake: 推荐阅读
编译选项介绍
cmake基本用法
cmake备忘录
add_library案例

created by shuaixio, 2021.07.30

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值