好的,我们进入 第五课:拆分模块与使用 add_subdirectory()
构建子目录项目。
你将学会如何:
拆分项目结构,把不同模块放入子文件夹;
在主项目中使用 add_subdirectory()
引入子模块;
使用 target_link_libraries()
连接模块;
初步理解项目的“库化”和模块化管理。
目录结构如下:
modular_project/
├── CMakeLists.txt # 主工程
├── main.cpp # 主函数
└── math/
├── CMakeLists.txt # 子模块自己的构建脚本
├── add.h
└── add.cpp
main.cpp
#include
#include "add.h"
int main() {
std::cout << "2 + 5 = " << add(2, 5) << std::endl;
return 0;
}
math/add.h
#pragma once
int add(int a, int b);
math/add.cpp
#include "add.h"
int add(int a, int b) {
return a + b;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(ModularProject LANGUAGES CXX)
add_subdirectory(math) # 引入 math 子目录
add_executable(main_app main.cpp)
# 设置标准
target_compile_features(main_app PRIVATE cxx_std_17)
# 链接 math 模块
target_link_libraries(main_app PRIVATE math_lib)
math/CMakeLists.txt
# 创建 math_lib 库目标
add_library(math_lib add.cpp)
# 设置 math_lib 的头文件路径
target_include_directories(math_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
注意:这里我们把
add.cpp
编译为一个库,叫math_lib
,供主程序使用。
命令 | 说明 |
---|---|
add_subdirectory(math) |
告诉 CMake 去处理 math/ 目录里的 CMakeLists.txt |
add_library(math_lib ...) |
创建一个库模块(可以是静态库或对象库) |
target_include_directories(... PUBLIC ...) |
表示该目标的头文件对外可见(可被 link 的目标访问) |
target_link_libraries(main_app PRIVATE math_lib) |
将主程序与 math_lib 链接起来 |
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022"
cmake --build . --config Release
./Release/main_app.exe
预期输出:
2 + 5 = 7
真实项目中每个模块都可能是独立库(比如通信、UI、算法)
可以独立编译、测试、调试
可以多人协作开发
模块和主程序解耦
add_subdirectory()
是干什么的?
✅ 引入子模块并执行其
CMakeLists.txt
add_library(math_lib ...)
与 add_executable(...)
有什么区别?
✅ 前者是生成库,后者是生成可执行文件
子模块里的头文件目录如何让主项目识别?
✅ 使用
target_include_directories(... PUBLIC ...)
【CMake基础入门】第四课:项目结构与多个源文件、头文件管理
下一课我们将深入:
STATIC
/ SHARED
库的区别
如何使用 install()
命令生成可分发组件
Windows 下构建 .dll
动态库和 .lib
静态库