1)如果子目录代码文件相对独立,也就是没有引用其他子目录的文件,可以单独编译成库文件
上层CMakeLists.txt通过link_libraries()来添加这个库文件
2)如果子目录代码引用了其他子目录的文件,建议在上一层编译(前提也是相对独立)
上层CMakeLists.txt通过aux_source_directory()来添加子目录文件
举个例子,假设有个src目录下的代码结构如下
- src
- ├── CMakeLists.txt
- ├── main.c
- ├── utils
- │ ├── utils.h
- │ └── utils.c
- └── log
- ├── CMakeLists.txt
- ├── log.h
- └── log.c
其中,log模块相对独立,而utils模块调用了log模块。
log.h(在log目录)
- #pragma once
-
- void log1( const char* text );
log.c(在log目录)
- #include "log.h"
- #include
-
- void log1( const char* text ){
- printf("[DEBUG] %s\n",text);
- }
log目录下的CMakeLists.txt
- cmake_minimum_required(VERSION 3.16)
- project(log)
-
- #搜索当前目录下所有源文件
- aux_source_directory(./ SRC)
-
- #编译静态库文件
- add_library(log ${SRC})
utils.h(在utils目录)
- #pragma once
-
- void doSomething();
utils.c(在utils目录)
- #include "utils.h"
- #include "log.h"
-
- void doSomething(){
- log1("--doSomething--");
- }
utils目录下没有CMakeLists.txt
src目录(log和utils目录的上一级目录)下的main.c
- #include "utils.h"
- #include "log.h"
- int main(int argc, char** argv ){
- log1("--main--");
- doSomething();
- return 0;
- }
src目录的CMakeLists.txt
- cmake_minimum_required(VERSION 3.16)
- project(test)
-
- #添加头文件搜索路径
- include_directories(${PROJECT_SOURCE_DIR}/log)
- include_directories(${PROJECT_SOURCE_DIR}/utils)
-
- #添加和构建子目录,会执行子目录的CMakeLists.txt
- add_subdirectory(log)
-
- #连接静态库
- link_libraries(log)
-
- #搜索utils子目录源代码文件(名), 记在UTILS_SRC变量
- aux_source_directory(${PROJECT_SOURCE_DIR}/utils UTILS_SRC)
-
- #生成可执行文件
- add_executable(demo main.c ${UTILS_SRC})
注意到,对log模块的处理方式是
#添加和构建子目录,会执行子目录的CMakeLists.txt
add_subdirectory(log)#连接静态库
link_libraries(log)
对utils模块的处理方式是
#搜索utils子目录源代码文件(名), 记在UTILS_SRC变量
aux_source_directory(${PROJECT_SOURCE_DIR}/utils UTILS_SRC)#生成可执行文件
add_executable(demo main.c ${UTILS_SRC})
也就是通过UTILS_SRC来记录utils的所有源文件名,通过${UTILS_SRC}来引用。
然后,构建工程&编译
- cd src
- cmake . -B build
- cmake --build build
cmake . -B build 作用是 构建工程并且把中间文件保存在build目录,子目录的中间文件也会存到里面
cmake --build build 作用是在build目录编译&链接生成目标文件(此处是demo)
最后,可以在build目录下看到demo这个程序。
如果要删除 build目录,这条命令:rm -rf build (也就是普通删除文件夹命令)
末了,切记,要根据实际情况来配置CMakeLists.txt,不要生搬硬套别人的做法,此文只是抛砖引玉。