cmake基础教程(下)

针对更复杂的目录结构

再上一节的教程中,我们已经演示了如何优化目录结构来编译代码,下面我们展示一个更加复杂的目录并尝试构建项目。

build/  CMakeLists.txt  src/  bin/
  |	                    |		|
  |                     |		V
  V						|		存放生成的可执行文件
 (用于执行cmake的目录)	V
 					CMakeLists.txt    main.cpp      dir1/       dir2/ (和dir1/目录结构一样,有b.cpp)
										|			|
										|			V
										|		a.cpp a.h CMakeLists.txt
										V
							main函数所在的函数
							会使用到a.cpp和 b.cpp实现的函数

观察该目录结构,顶层目录有一个CMakeLists.txt,他应该继续执行 src/ 层的 CMakeLists.txt 然后执行 dir1/ 和 dir2/ 层的 CMakeLists.txt 。因为 main.cpp 中调用 a.cpp 和 b.cpp 中实现的函数,我们这里将 dir1/ 和 dir2/ 下的源码编译为静态库,再链接到 main.cpp 生成的可执行文件中。下面看一下四个CMakeLists.txt怎么编写:

  1. 顶层的CMakeLists.txt
cmake_minimum_required (VERSION 2.8)
PROJECT(TEST3)

# 添加子目录,会在该子目录中寻找CMakeLists.txt继续执行
ADD_SUBDIRECTORY(src)
  1. src/层的CMakeLists.txt
# CMake的最低版本号需求
cmake_minimum_required (VERSION 2.8)


# 将main.cpp的值赋给SRC_LIST
SET(SRC_LIST main.cpp)

# 添加头文件路径
INCLUDE_DIRECTORIES(dir1)
INCLUDE_DIRECTORIES(dir2)

# 添加子目录,会执行子目录的CMakeLists.txt
ADD_SUBDIRECTORY(dir1)
ADD_SUBDIRECTORY(dir2)

# 生成可执行文件Test
ADD_EXECUTABLE(Test ${SRC_LIST})

# 链接可执行文件所需要的库(test1和test2)
TARGET_LINK_LIBRARIES(Test test1 test2)


# 将可执行文件安装到顶层同级的bin目录下
INSTALL(TARGETS Test DESTINATION ${PROJECT_SOURCE_DIR}/bin)

这里注意,我们在使用静态库或者动态库的时候,除了需要库文件以外,还需要头文件,所以这里我们还需要把头文件所在的目录添加进来。

  1. dir1/ 和 dir2/ 层的CMakeLists.txt(这里给出的是 dir1/ , dir2/ 与之类似)
# 加载所有的源码到变量DIR_SRCS中 (这里作用和 SET(DIR_SRCS a.c) 一样 )
AUX_SOURCE_DIRECTORY(. DIR_SRCS)

# 将代码编译为静态库,供上一层的CMakeLists.txt使用
# 如若想编译为动态库, 则使用 ADD_LIBRARY(test1 SHARED ${DIR_SRCS})
ADD_LIBRARY(test1 ${DIR_SRCS})

1. INCLUDE_DIRECTORIES

添加找寻头文件的目录

2. TARGET_LINK_LIBRARIES

用于将指定的动态库或者静态库链接到指定的可执行文件

3. ADD_LIBRARY

用于将源文件生成动态库或者静态库

构建项目

进入到 build 目录中,执行以下命令即可成功构建项目。

cmake ..
make
make install

使用源码来编译

刚刚编译的方式是将子目录下的文件编译为静态库来连接到可执行文件中,那我们可以通过源码直接编译吗?答案当然是肯定的,对于原先那个工程,我们现在所需的CMakeLists结构如下:

build/  CMakeLists.txt  src/  bin/
  |	                    |		|
  |                     |		V
  V						|		存放生成的可执行文件
 (用于执行cmake的目录)	V
 					CMakeLists.txt    main.cpp      dir1/       dir2/ (和dir1/目录结构一样,有b.cpp)
										|			|
										|			V
										|		a.cpp a.h
										V
							main函数所在的函数
							会使用到a.cpp和 b.cpp实现的函数

dir1/ 和 dir2/ 下面不需要CMakeLists.txt文件了,顶层的CMakeLIsts.txt的编写和上一个版本的编写是相同的,我们这里不重复给出,下面看一下 src/ 层的 CMakeLIsts.txt 的编写:

# CMake的最低版本号需求
cmake_minimum_required (VERSION 2.8)

# 将main.cpp的值赋给SRC_LIST
SET(SRC_LIST main.cpp)

# 将dir1和dir2的值赋给SUB_DIR_LIST
SET(SUB_DIR_LIST "dir1" "dir2")

# 遍历所有的子目录
foreach(SUB_DIR ${SUB_DIR_LIST})
    #将对应子目录的源文件加入到SRC_LIST中
    AUX_SOURCE_DIRECTORY(${SUB_DIR} SRC_LIST)
endforeach()

# 添加头文件路径
INCLUDE_DIRECTORIES(dir1)
INCLUDE_DIRECTORIES(dir2)

# 生成可执行文件Test
ADD_EXECUTABLE(Test ${SRC_LIST})

# 将可执行文件安装到顶层同级的bin目录下
INSTALL(TARGETS Test DESTINATION ${PROJECT_SOURCE_DIR}/bin)

foreach() … endforeach()

用于遍历一个列表里的所有变量

AUX_SOURCE_DIRECTORY

找在某个路径下的所有源⽂件

构建项目

进入到 build 目录中,执行以下命令即可成功构建项目。

cmake ..
make
make install

将工程打包为动态库

以上我们演示了如何将工程编译为可执行文件,但有些时候,我们希望将代码打包为动态库以便提供给其他人使用。同时,我们之前并没有去区分编译出的文件是release版本还是debug版本,这里我们希望能指定编译的版本,并且将对应版本的动态库放置到对应的目录下。现在的目录结构如下:

a.cpp   a.h    build/    Debug/    Release/   CMakeLists.txt
							|			|
							|			V
							V		存放release版本的动态库
						存放debug版本的动态库

下面看一下如何编写 CMakeLists.txt 来实现我们的需求

cmake_minimum_required(VERSION 2.8s)
PROJECT(TEST4)

# 设置得到的是realse版本还是debug版本(默认一般是debug)
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
    SET(BuildType "Relaese")
else()
    SET(BuildType "Debug")
endif()

#设置生成的so动态库的目录
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/${BuildType})

# 增加-fPIC的编译选项
ADD_COMPILE_OPTIONS(-fPIC)

# 获取当前目录下的所有源文件
AUX_SOURCE_DIRECTORY(. DIR_LIB_SRCS)

# 生成动态库
ADD_LIBRARY (test SHARED ${DIR_LIB_SRCS}) 

这里注意 CMAKE_BUILD_TYPELIBRARY_OUTPUT_PATH 是Cmake提供的两个变量用于确定cmake的编译模式和库输出的路径,而非DIR_LIB_SRCS 这种我们自己定义的变量。

构建项目生成动态库

默认生成Debug版本的动态库,进入build 目录执行以下命令

cmake ..	# 或者 cmake -DCMAKE_BUILD_TYPE=Debug ..
make

执行完会发现会生成一个Debug目录,下面有一个 libtest.so 动态库.
欲生成Release版本的动态库,进入build执行以下命令

cmake -DCMAKE_BUILD_TYPE=Release ..
make
  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值