CMakeLists.txt编写知识记录

CMakeLists.txt编写知识记录

一.ubuntu安装cmake

# 方法1:指令安装
sudo apt install cmake

# 方法2:源码编译安装
## download src: https://cmake.org/download/下载cmake源码,如cmake-3.17.1.tar.gz
## 安装依赖
sudo apt-get install g++
sudo apt-get install libssl-dev

## 源码编译
sudo tar -zxv -f cmake-3.17.1.tar.gz
cd cmake-3.17.1
make -j${nproc}
make install
cmake --version

二. CMakeLists.txt编写基础知识

1.设定cmake版本

cmake_minimum_required(VERSION 3.1)  # 指定cmake的最低版本是3.1
cmake_minimum_required(VERSION 3.1...3.12) # 指定cmake版本为3.1至3.12之间的版本

2.设置生成项目名称

project(MyProject) # 设定项目名称为MyProject
# 说明!!!
# 执行该指令后会创建2个不同的变量,分别为PROJECT_BINARY_DIR、PROJECT_SOURCE_DIR。
# 当内部构建时,PROJECT_BINARY_DIR指向CMakeLists.txt文件的目录,PROJECT_SOURCE_DIR指向工程的src目录(如果没有src文件夹,则指向源码目录);
# 当外部构建时,PROJECT_BINARY_DIR指向target生成的目录,PROJECT_SOURCE_DIR指向工程的src目录(如果没有src文件夹,则指向源码目录)。
# e.g
project(demo) # 指定该项目名称为demo

3.生成可执行文件

aux_source_directory(<dir> <variable>)
## 说明!!!
# 将当前目录下的源文件名字存放到变量DIR_SRCS里面 ,如果源文件比较多,直接用DIR_SRCS变量即可

add_executable(exename srcname)
# 说明!!!
# exename为可执行程序的名称 srcname为源码名称
# 该指令指定生成可执行文件的名字以及指出需要依赖的源文件的文件名
# e.g
aux_source_directory(. DIR_SRCS) # 将当前目录下的所有源码文件存放在DIR_SRCS变量中
add_executable(Demo ${DIR_SRCS}) # 依赖DIR_SRCS变量存放的文件,生成名为Demo的可执行文件

4.生成lib库

add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) 
# 说明!!!
# libname:生成库的名称
# [SHARED|STATIC|MODULE]:生成库文件的类型(动态库|静态库|模块)
# [EXCLUDE_FROM_ALL]:有这个参数表示该库不会被默认构建
# source2 ... sourceN:生成库依赖的源文件,如果源文件比较多,可以使用​aux_sourcr_directory命令获取路径下所有源文件
# e.g
add_library(alib SHARE a.cpp) # 依赖a.cpp生成alib动态库文件

5.添加头文件目录

################ 指令1 ################
target_include_directories(<target> [SYSTEM] [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1...] [<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
# 说明!!!
## 指定target来加载include目录
## [AFTER|BEFORE]:指定了要添加路径是添加到原有列表之前还是之后
## [SYSTEM]​:若指定了system参数,则把被包含的路径当做系统包含路径来处理
# e.g
target_include_directories(RigelEditor PUBLIC ./include/rgeditor)  # 表示给RigelEditor 这个子项目添加一个库文件的路径

################ 指令2 ################
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …])
# 说明!!!
## 添加include目录到本工程的所有target,包含调用节点后的子目录的target
# e.g
include_directories("/opt/torch/inlcude") # 向所有的target(包含调用节点后的所有子目录的target)添加对应的include头文件

6.添加链接库文件路径

################ 指令1 ################
target_link_libraries(<target> [item1 [item2 [...]]] [[debug|optimized|general] <item>] ...)
# 说明!!!
# 为给定的目标设置链接时使用的库(设置要链接的库文件的名称)
# 链接库文件的顺序符合gcc/g++链接顺序规则,即:被依赖的库放在依赖他的库的后面,如果顺序有错,链接将会报错
# e.g
target_link_libraries(demo b.a c.so)   # 将若干库文件链接到demo中

################ 指令2 ################
link_libraries("/opt/torch/lib/script.so") 
# 说明!!!
## 给当前工程链接需要的库文件(绝对路径)

################ 指令1与指令2的区别 ################
# target_link_libraries可以给工程或者库文件设置其需要链接的库文件,而且不需要填写全路径,但是link_libraries只能给工程添加依赖的库,而且必须添加全路径

7.添加链接库文件目录

link_directories(directory1 directory2 ...) 
# 说明!!!
## link_directories(添加需要链接的库文件目录),与link_libraries/target_link_libraries不同的是,该指令指定的是链接库文件目录,而不是指定的单一链接库的名称
# e.g
link_directories("/opt/torch/lib")

8.内置变量

# cmake里面包含大量的内置变量,和自定义的变量相同,常用的有以下:
CMAKE_C_COMPILER # 指定C编译器
CMAKE_CXX_COMPILER # 指定C++编译器
EXECUTABLE_OUTPUT_PATH # 指定可执行文件的存放路径
LIBRARY_OUTPUT_PATH # 指定库文件的放置路径
CMAKE_CURRENT_SOURCE_DIR # 当前处理的CMakeLists.txt所在的路径
CMAKE_BUILD_TYPE # 控制构建的时候是Debug还是Release, set(CMAKE_BUILD_TYPE Debug)
CMAKE_SOURCR_DIR # 无论外部构建还是内部构建,都指的是工程的顶层目录(参考project命令执行之后,生成的_SOURCR_DIR以及CMake预定义的变量PROJECT_SOURCE_DIR)
CMAKE_BINARY_DIR # 内部构建指的是工程顶层目录,外部构建指的是工程发生编译的目录(参考project命令执行之后,生成的_BINARY_DIR以及CMake预定义的变量PROJECT_BINARY_DIR)
CMAKE_CURRENT_LIST_LINE # 输出这个内置变量所在的行

三. find_package

  1. 查找链接库的指令find_package()解析
FIND_PACKAGE( <name> [version] [EXACT] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] )
# 说明!!!
## version:需要一个版本号,给出这个参数而没有给出EXACT,那个就是找到和给出的这个版本号相互兼容就符合条件
## EXACT:要求版本号必须和version给出的精确匹配
## QUIET:会禁掉查找的包没有被发现的警告信息
## NO_MODULE:给出该指令之后,cmake将直接跳过Module模式的查找,直接使用Config模式查找
## REQUIRED:该选项表示如果没有找到需要的包就会停止并且报错
## COMPONENTS:在REQUIRED选项之后,或者如果没有指定REQUIRED选项但是指定了COMPONENTS选项,在COMPONENTS后面就可以列出一些与包相关部分组件的清单 
# COMPONENTS选项,有些库不是一个整体比如Qt,其中还包含QtOpenGL和QtXml组件,当我们需要使用库的组件的时候,就使用COMPONENTS这个选项  e.g find_package(Qt COMPONENTS QtOpenGL QtXml REQUIRED)

2.find_package()目的就是查找XXXXX.cmake文件,具有module模式和config模式。cmake默认采用module模式查找,当module查找不到对应的库时,接着以config模式查找。

###################### module模式######################
# find_package指令查找FindXXX.cmake的文件,如FindTorch.cmake文件
# 工程量较大的时候,我们经常会通过设定CMAKE_MODULE_PATH的值,让程序自动搜索CMAKE_MODULE_PATH下的所有目录
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # 在${PROJECT_SOURCE_DIR}/cmake下存放FindXXX.cmake文件
###################### module模式######################

###################### config模式######################
# config模式下是在XXX_DIR路径下查找XXXConfig.cmake文件
set(OpenCV_DIR /opt/opencv440/lib/cmake/opencv4/) # 指定OpenCV路径,设定为OpenCVConfig.cmake文件的上级目录
find_package(OpenCV REQUIRED)
###################### config模式######################

找到packages后,则可以通过在工程的顶层目录中的CMakeLists.txt中添加对应的include和libs。指令如下

# 链接头文件
include_directories(<Name>_INCLUDE_DIRS) # 向所有target(包括此指令后的所有子target添加头文件)
# or 
target_include_directories(<target> <Name>_INCLUDE_DIRS) # 向指定target添加头文件

# 链接库文件
target_link_libraries(<target> <NAME>_LIBS) 

四. 构建项目

1.单目录项目构建

工程目录
	a.h
	a.cpp
	main.cpp
    CMakeLists.txt

CMakeLists.txt

cmake_minium_required(VERSION 2.8)  # 指定cmake版本不低于2.8
project(main)  # 指定工程名称为main
set(CMAKE_CXX_STANDARD 11)  # 指定c++11编译
set(CMAKE_BUILD_TYPE Relaese)  # 指定编译模式为release
aux_source_directories(. DIR_SRC) # 将本目录下所有源码存为DIR_SRC变量中
add_executable(main ${DIR_SRC})# 依赖DIR_SRC变量中的源码指定生成main可执行文件
target_include_directories(main ./)  # 向main中添加本目录下的头文件

2.两个目录项目构建

工程目录
	lib 
		a.cpp
		CMakeLsits.txt
	inlcude
		a.h
	main.cpp
    CMakeLists.txt

根目录下的CMakeLists.txt

cmake_minium_required(VERSION 2.8)  # 指定cmake版本不低于2.8
project(main)  # 指定工程名称为main
set(CMAKE_CXX_STANDARD 11)  # 指定c++11编译
set(CMAKE_BUILD_TYPE Relaese)  # 指定编译模式为release
aux_source_directories(. DIR_SRC) # 将本目录下所有源码存为DIR_SRC变量中
add_subdirectories(lib) # 添加子目录lib文件夹
add_executable(main ${DIR_SRC})# 依赖DIR_SRC变量中的源码指定生成main可执行文件
target_include_directories(main include)  # 向main中添加include目录下的头文件
target_link_libraries(main test)# 向main中链接依赖test链接库  test链接库是lib文件夹下生成的

lib文件夹下的CMakeLists.txt

aux_source_director(. DIR_LIB) # 将当前的源文件名字都添加到DIR_LIB变量下
add_libraries(test SHARED ${DIR_LIB}) # 依赖DIR_LIB生成名为test的动态链接库

3.多级目录项目构建

include                     # 根目录下的include,头文件目录
	test1					# include文件夹下的第一个头文件文件夹
		test1.h				# test1头文件文件夹下的头文件test1.h
		test.h				# test1头文件文件夹下的头文件test.h
	test2					# include文件夹下的第二个头文件文件夹
		test2.h				# test2头文件文件夹下的头文件test2.h
lib	                        # 根目录下的lib,链接库目录
	libtest1.a				
	libtest2.a
main.cpp				    # 根目录下的main.cpp,主程序文件
CMakeLists.txt				# 根目录下的CMakeLists.txt
src							# 根目录下的src文件夹
	CMakeLists.txt			# scr文件夹下的CMakeLists.txt
	test1					# scr文件夹下的第一个源码文件夹
		CMakeLists.txt		# test1源码文件夹下的CMakeLists.txt
		test1.cpp			# test1源码文件夹下的源码test1.cpp
		test.cpp			# test1源码文件夹下的源码test.cpp
	test2					# scr文件夹下的第一个源码文件夹
		CMakeLists.txt		# test2源码文件夹下的CMakeLists.txt
		test2.cpp			# test2源码文件夹下的源码test2.cpp

CMakeLists.txt

################ ./CMakeLists.txt  ################
#设置CMAKE最小版本
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#设置工程名称
PROJECT(CMAKEDemo)
#自定义
SET(MY_TARGET demo)  # 指定MY_TARGET为demo
SET(MY_LINK test1 test2) # 指定MY_LINK包含test1 test2

#设置编译器
SET(CMAKE_CXX_COMPILER "g++")
# 指定c++11编译
set(CMAKE_CXX_STANDARD 11)  
#设置构建类型,及相应的编译选项
SET(CMAKE_BUILD_TYPE "Release")
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

#设置执行文件输出目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#设置库输出路径
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#当前目录的文件
AUX_SOURCE_DIRECTORY(. SRC_LIST)
#添加子目录
ADD_SUBDIRECTORY(src)
#头文件搜索目录
INCLUDE_DIRECTORIES(include)
#链接库搜索路径
LINK_DIRECTORIES(lib)
#设置链接库
SET(EXTRA_LIBS ${EXTRA_LIBS} ${MY_LINK})

#生成可执行文件
ADD_EXECUTABLE(${MY_TARGET} ${SRC_LIST})
#执行文件链接属性
TARGET_LINK_LIBRARIES(${MY_TARGET} ${EXTRA_LIBS})
################ ./CMakeLists.txt  ################

################ ./src/CMakeLists.txt  ################
ADD_SUBDIRECTORY(test1)
ADD_SUBDIRECTORY(test2)
################ ./src/CMakeLists.txt  ################

################ ./src/test1/CMakeLists.txt  ################
#所有的路径变量都不允许重名
AUX_SOURCE_DIRECTORY(. T1_SRC_LIST)
#设置成静态库
ADD_LIBRARY(test1 ${T1_SRC_LIST})
################ ./src/test1/CMakeLists.txt  ################

################ ./src/test2/CMakeLists.txt  ################
#所有的路径变量都不允许重名
AUX_SOURCE_DIRECTORY(. T2_SRC_LIST)
#设置成静态库
ADD_LIBRARY(test2 ${T2_SRC_LIST})
################ ./src/test2/CMakeLists.txt  ################
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hanqu3456

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值