1、嵌套的CMake
如果项目很大或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个CMakeLists.txt
,那么这个文件会相对比较复杂,有一种化繁为简的方式就是给每个源代码目录都添加一个CMakeLists.txt
文件(头文件不需要),这样每个文件都不会太复杂,而且更灵活,更容易维护。
.
├── calc
│ ├── add.cpp
│ ├── CMakeLists.txt
│ ├── dived.cpp
│ ├── mul.cpp
│ └── sub.cpp
├── inc
│ ├── calc.h
│ └── sort.h
├── sort
│ ├── CMakeLists.txt
│ ├── insert.cpp
│ └── select.cpp
├── test1
│ ├── calc.cpp
│ └── CMakeLists.txt
└── test2
│ ├── CMakeLists.txt
│ └── sort.cpp
├── CMakeLists.txt
calc目录
:目录中的四个源文件对应加、减、乘、除算法- 对应的头文件是
inc
中的calc.h
- 对应的头文件是
inc目录
:所有头文件存放目录sort目录
:目录中的两个源文件分别是插入和选择排序算法- 对应的头文件
inc
中的sort.h
- 对应的头文件
test1目录
:测试目录,对加减乘除算法进行测试test2目录
:测试目录,对排序算法进行测试
可以看到各个源文件目录所需要的CMakeLists.txt
文件现在已经添加完毕了。接下来可以依次分析一下各个文件中需要添加的内容
2、具体流程
2.1、节点关系
Linux中的目录是一个梳妆结构,所以嵌套的CMake也是一个梳妆结构,最顶层的CMakeLists.txt
是根节点,其次都是子节点。对于父子CMakeLists.txt
文件变量作用域存在一些关系
- 根节点
CMakeLists.txt
中的变量全局有效 - 根节点
CMakeLists.txt
中的变量可以在子节点中使用 - 子节点
CMakeLists.txt
中的变量只能在当前节点中使用
对于多级子目录的项目需要再根节点CMakeLists.txt
中使用CMake的命令
# 添加子节点目录
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
source_dir
:指定了CMakeLists.txt
源代码和代码文件的位置,其实就是指定子目录binary_dir
:指定了输出文件的路径,一般不需要指定,忽略即可。EXCLUDE_FROM_ALL
:在子路径下的目录默认不会被包含到父路径ALL
目标里,并且也会被排除在IDE工程文件之外。用户必须显示构建在子路径下的目标
2.2、具体实现
2.2.1、根目录CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2)
set(CMAKE_CXX_STANDARD 14)# 主项目名称
project(main_project)
# 静态库生成的路径
set(LIBPATH ${PROJECT_SOURCE_DIR}/lib)
# 可执行程序的存储目录
set(EXECPATH ${PROJECT_SOURCE_DIR}/bin)
# 头文件目录
set(HEADPATH ${PROJECT_SOURCE_DIR}/inc)# 库文件的名字
set(CALCLIB calc)
set(SORTLIB sort)# 可执行程序的名字
set(EXECNAME1 main1)
set(EXECNAME2 main2)# 添加子节点目录
# add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
add_subdirectory(calc)
add_subdirectory(sort)
add_subdirectory(test1)
add_subdirectory(test2)
- 根节点下的
CMakeLists.txt
文件中定义了一系列的可能用到的全局变量的值 - 添加子节点目录进行引用
2.2.2、calc目录CMakeLists.txt
calc目录下的源代码打包生成一个静态库文件,并且存放到指定的目录下
cmake_minimum_required(VERSION 3.10.2)
project(calc)# 搜索源文件
aux_source_directory(./ src_list)
# 添加头文件
include_directories(${HEADPATH})
# 设置库文件存储的位置
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 制作静态库文件
add_library(${CALCLIB} STATIC ${src_list})
aux_source_directory
:搜索当前目录下的所有.cpp源代码include_directories
:指定头文件,具体的值从父节点的全局变量中获取set(LIBRARY_OUTPUT_PATH ${LIBPATH})
:指定静态库存储的位置add_library(${CALCLIB} STATIC ${src_list})
:制作一个静态库,并且指定名称和源文件列表
2.2.3、sort目录CMakeLists.txt
sort目录下的源代码打包生成一个动态库文件,并且存放到指定的目录下
cmake_minimum_required(VERSION 3.10.2)
project(sort)# 搜索源文件
file(GLOB src_list ./*.cpp)
# 添加头文件
include_directories(${HEADPATH})
# 设置库文件存储的位置
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 制作动态库文件
add_library(${SORTLIB} SHARED ${src_list})
2.2.4、test1目录CMakeLists.txt
用于生成测试静态库calc的可执行程序
cmake_minimum_required(VERSION 3.10.2)
project(test1)# 搜索源代码
file(GLOB main ./*.cpp)
# 指定头文件
include_directories(${HEADPATH})
# 链接静态库
link_libraries(${CALCLIB})
# 指定静态库的路径
link_directories(${LIBPATH})# 指定可执行程序存放的位置
set(EXECUTABLE_OUTPUT_PATH ${EXECPATH})# 生成可执行程序
add_executable(${EXECNAME1} ${main})
include_directories(${HEADPATH})
:指定头文件的目录,对应Makefile中的-I
(大写i)link_libraries(${CALCLIB})
:指定需要链接静态库的名称,对应Makefile中的-l
(小写L)link_directories(${LIBPATH})
:指定需要链接静态库的路径,对应Makefile中的-L
(大写L)
2.2.5、test2目录CMakeLists.txt
用于生成测试动态库sort的可执行程序
cmake_minimum_required(VERSION 3.10.2)
project(test2)# 搜索源文件
aux_source_directory(./ main)
# 设置可执行程序输出位置
set(EXECUTABLE_OUTPUT_PATH ${EXECPATH})# 包含头文件
include_directories(${HEADPATH})
# 生成可执行程序
add_executable(${EXECNAME2} ${main})# 链接动态库
link_directories(${LIBPATH})
target_link_libraries(${EXECNAME2} ${SORTLIB})
include_directories(${HEADPATH})
:指定头文件的目录,对应Makefile中的-I
(大写i)link_directories(${LIBPATH})
:指定需要链接动态库的路径,对应Makefile中的-L
(大写L)target_link_libraries(${EXECNAME2} ${SORTLIB})
:可执行程序链接动态库libsort.so