CMake多个CMakeLists.txt共同合作编译一个C++项目

发布时间 2023-11-09 09:54:03作者: 飘杨......

一、概述

  在C++项目比较大或者要根据不同的规则生成不同的执行文件或者动态库/静态库的时候。单独的CMakeLists.txt会变的比较复杂,此时可以利用CMakeLists.txt的父子关系分目录分模块的进行编译及输出。

  就相当于项目模块化编译

  参考博客:【大丙课堂】

二、具体实现

  1.demo目录

  

  目录说明:

    bin目录代表可执行文件输出目录

    build目录是cmake编译目录

    lib目录是静态/动态库输出目录

    include目录是头文件输出目录

    student、teacher、student_test、teacher_test目录是子目录,每个子目录下都有一个CMakeLists.txt文件。其中student、和teacher目录用于生成静态库/动态库,即.a/.so文件,静态/动态库存放到 lib目录中。

    student_test和teacher_test目录用于生成可执行文件,可执行文件存入bin目录中

    根目录下的CMakeLists.txt是父文件

    run.sh是执行脚本,编译的时候直接运行./run.sh就可以了。

 

  1.根目录CMakeLists.txt的内容如下

#参考样例(Cmake保姆级教程):https://subingwen.cn/cmake/CMake-primer/
cmake_minimum_required(VERSION 3.0.0)
#设置C++的编译版本,其中CMAKE_CXX_STANDARD是固定的,11代表C++11
set(CMAKE_CXX_STANDARD 11)

#设置项目名称
project(school VERSION 0.1.0)

# 定义变量
# 静态库生成的路径
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(STUDENT_LIB student)
set(TEACHER_LIB teacher)
# 可执行程序的名字(可执行文件的项目名),他们两者公用一个,其实他们一毛钱关系都没有,可以单独设置,这里为了方便设置成一样
set(STUDENT_TEST student_test)
set(TEACHER_TEST teacher_test)
# 添加子目录,参数是项目名称
add_subdirectory(${STUDENT_LIB})
add_subdirectory(${TEACHER_LIB})
add_subdirectory(${STUDENT_TEST})
add_subdirectory(${TEACHER_TEST})

  2.student目录下的CMakeLists.txt

#参考样例(Cmake保姆级教程):https://subingwen.cn/cmake/CMake-primer/
cmake_minimum_required(VERSION 3.0.0)
#设置C++的编译版本,其中CMAKE_CXX_STANDARD是固定的,11代表C++11
set(CMAKE_CXX_STANDARD 11)

#设置项目名称(父CMakeLists.txt中设置过的)
project(${STUDENT_LIB} VERSION 0.1.0)
#搜索当前目录下的所有源文件
aux_source_directory(./ SRC)
#导入头文件
include_directories(${HEAD_PATH})
#设置生成库的路径,输出路径是根节点定义的
set(LIBRARY_OUTPUT_PATH ${LIB_PATH})
#生成静态库,静态库的名字是根节点定义的
add_library(${STUDENT_LIB} STATIC ${SRC})

  3.teacher目录下的CMakeLists.txt

#参考样例(Cmake保姆级教程):https://subingwen.cn/cmake/CMake-primer/
cmake_minimum_required(VERSION 3.0.0)
#设置C++的编译版本,其中CMAKE_CXX_STANDARD是固定的,11代表C++11
set(CMAKE_CXX_STANDARD 11)

#设置项目名称
project(${TEACHER_LIB} VERSION 0.1.0)
#搜索当前目录下的所有源文件
aux_source_directory(./ SRC)
#导入头文件
include_directories(${HEAD_PATH})
#设置生成库的路径,输出路径是根节点定义的
set(LIBRARY_OUTPUT_PATH ${LIB_PATH})
#生成静态库,静态库的名字是根节点定义的
add_library(${TEACHER_LIB} STATIC ${SRC})

  4.student_test目录下的CMakeLists.txt

#参考样例(Cmake保姆级教程):https://subingwen.cn/cmake/CMake-primer/
cmake_minimum_required(VERSION 3.0.0)
#设置C++的编译版本,其中CMAKE_CXX_STANDARD是固定的,11代表C++11
set(CMAKE_CXX_STANDARD 11)

#设置项目名称
project(${STUDENT_TEST} VERSION 0.1.0)
#搜索当前目录下的所有源文件
aux_source_directory(./ SRC)
#导入头文件
include_directories(${HEAD_PATH})
#指定库文件路径
link_directories(${LIB_PATH})
#指定可执行程序要链接的静态库
link_libraries(${STUDENT_LIB})

#设置可执行程序的生成路径
set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
#生成可执行程序
add_executable(${STUDENT_TEST} ${SRC})

  5.teacher_test目录下的CMakeLists.txt

#参考样例(Cmake保姆级教程):https://subingwen.cn/cmake/CMake-primer/
cmake_minimum_required(VERSION 3.0.0)
#设置C++的编译版本,其中CMAKE_CXX_STANDARD是固定的,11代表C++11
set(CMAKE_CXX_STANDARD 11)

#设置项目名称
project(${TEACHER_TEST} VERSION 0.1.0)
#搜索当前目录下的所有源文件
aux_source_directory(./ SRC)
#导入头文件
include_directories(${HEAD_PATH})
#指定库文件路径
link_directories(${LIB_PATH})
#指定可执行程序要链接的静态库
link_libraries(${TEACHER_LIB})

#设置可执行程序的生成路径
set(EXECUTABLE_OUTPUT_PATH ${EXEC_PATH})
#生成可执行程序
add_executable(${TEACHER_TEST} ${SRC})

  6.run.sh脚本代码

#!/usr/bin/env bash
#自动化运行的脚本
BUILD_DIR='build'
#删除build目录
rm -rf $BUILD_DIR
#重新编译 -B build代表编译文件存放目录
cmake -B build -G "MinGW Makefiles"
echo $BUILD_DIR
#进入build目录
cd $BUILD_DIR
#执行make编译
mingw32-make
#运行可执行文件
../bin/student_test.exe
../bin/teacher_test.exe

  

  总结:每行代码的意思注释都很详细了。要看再详细一点的可以看【大丙】的博客,我也是参考那个写的。