目录
- 0.前言 & 准备
- 1.节点关系
- 2.添加子目录
- 3.解决问题
- 1.根目录
- 目录
- 目录
- 4.calc_test目录
- 5.sort_test
- 4.注意
0.前言 & 准备
- 如果项目很大,或者项目中有很多的源码目录,在通过CMake管理项目的时候如果只使用一个
,那么这个文件相对会比较复杂
- 有一种化繁为简的方式就是给每个源码目录都添加一个
文件(头文件目录不需要),这样每个文件都不会太复杂,而且更灵活,更容易维护
-
以下目录结构为例
. ├── ├── bin ├── build ├── calc │ ├── │ ├── │ ├── │ ├── │ └── ├── calc_test │ ├── │ └── calc_main.c ├── include │ ├── │ └── ├── lib ├── sort │ ├── │ └── └── sort_test ├── └── sort_main.c
1.节点关系
- Linux的目录是树状结构,所以嵌套的CMake也是一个树状结构,最顶层的
是根节点,其次都是子节点
- 因此,需要了解一些关于
文件变量作用域的一些信息:
-
根节点
中的变量全局有效
-
父节点
中的变量可以在子节点中使用
-
子节点
中的变量只能在当前结点中使用
-
根节点
2.添加子目录
-
CMake中建立父子节点关系
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
-
参数:
-
source_dir
:指定了源文件和代码文件的位置,其实就是指定子目录
-
binary_dir
:制定了输出文件的路径,一般不需要指定,忽略即可 -
EXCLUDE_FROM_ALL
:在子路径下的目标默认不会被包含到父路径的ALL目标里,并且也会被排除在IDE工程文件之外。用户必须显式构建在子路径下的目标
-
3.解决问题
1.根目录
-
根目录中的
文件
cmake_minimum_required(VERSION 3.15) project(mult_test) # 设置静态库生成路径 set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib) # 测试程序生成的路径 set(EXEC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin) # 头文件目录 set(HEAD_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include) # 静态库名字 set(CALC_LIB calc) set(SORT_LIB sort) # 可执行程序的名字 set(APP_NAME_1 calc_test) set(APP_NAME_2 sort_test) # 给当前结点添加子目录目录 add_subdirectory(calc) add_subdirectory(sort) add_subdirectory(sort_test) add_subdirectory(calc_test)
- 在根节点对应的文件中主要做了两件事情:定义全局变量和添加子目录
- 定义的全局变量主要是给子节点使用,目的是为了提高子节点中的文件的可读性和可维护性,避免冗余并降低出错的概率
- 一共添加了四个子目录,每个子目录中都有一个
文件,这样它们的父子关系就被确定下来了
目录
-
calc目录中的
文件
cmake_minimum_required(VERSION 3.15) project(calc) # 搜索源文件 aux_source_directory(./ SRC) include_directories(${HEAD_PATH}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH}) add_library(${CALC_LIB} STATIC ${SRC})
目录
-
sort目录中的
文件
cmake_minimum_required(VERSION 3.15) project(sort) # 搜索源文件 aux_source_directory(./ SRC) include_directories(${HEAD_PATH}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_PATH}) add_library(${SORT_LIB} STATIC ${SRC})
4.calc_test目录
-
calc_test目录中的
文件
cmake_minimum_required(VERSION 3.15) project(calc_test) # 搜索源文件 aux_source_directory(./ SRC) include_directories(${HEAD_PATH}) link_directories(${LIB_PATH}) link_libraries(${CALC_LIB}) set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH}) add_executable(${APP_NAME_1} ${SRC})
5.sort_test
-
sort_test目录中的
文件
cmake_minimum_required(VERSION 3.15) project(calc_test) # 搜索源文件 aux_source_directory(./ SRC) include_directories(${HEAD_PATH}) link_directories(${LIB_PATH}) link_libraries(${SORT_LIB}) set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH}) add_executable(${APP_NAME_2} ${SRC})
4.注意
- 在实际开发中,一个大型的 CMake 项目中,
project()
命令通常只在最外层的 文件中出现一次 -
顶层 文件是项目的入口点,在这里应该定义项目名称、全局设置和添加子目录
cmake_minimum_required(VERSION 3.10) project(MyLargeProject) # 设置全局属性 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) # 添加子目录 add_subdirectory(src) add_subdirectory(lib)
-
在子目录的 文件中,通常不需要重复使用
project()
命令,相反,应该专注于定义目标(例如:库或可执行文件)、设置目标属性和包含路径# 添加库文件 add_library(MyLibrary ) # 设置包含路径 target_include_directories(MyLibrary PUBLIC ${CMAKE_SOURCE_DIR}/include)