首页 > 编程语言 >CMake多个CMakeLists.txt共同合作编译一个C++项目

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

时间:2023-11-09 09:55:05浏览次数:41  
标签:11 CMakeLists set CMake LIB C++ CMAKE PATH 目录

一、概述

  在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

  

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

  

 

标签:11,CMakeLists,set,CMake,LIB,C++,CMAKE,PATH,目录
From: https://www.cnblogs.com/tony-yang-flutter/p/17819050.html

相关文章

  • C++跨DLL内存所有权问题探幽(一)DLL提供的全局单例模式
    最近在开发的时候,特别是遇到关于跨DLL申请对象、指针、内存等问题的时候遇到了这么一个问题。问题跨DLL能不能调用到DLL中提供的单例?问题比较简单,就是我现在有一个进程A,有DLLBDLLC,这两个DLL都依赖DLLD的单例,这个时候如果A调用了DLLB和DLLC,那么B和C能否正确引用到这个指......
  • 关于C++链接的一些理解
    无论是.h还是.cpp,都可以写声明或者实体,而且.h和.cpp的前面的名字相同不相同没有任何的影响最终一系列要连接的程序中,必须有且只有一个源文件有main函数,然后从这个main函数开始运行include的作用其实是跟define一样的,是纯文本替换进行替换之后,如果替换的内容是实体,那么就可以直......
  • c++简单的二分查找
    ints(intshuzu[],intlen,intx){ intlow=0,hight=len-1,mid; while(low<=hight) { mid=(low+hight)/2; if(shuzu[mid]==x)returnshuzu[mid]; elseif(shuzu[mid]<x)hight=mid-1; elselow=mid+1; } return-1;}i......
  • UE4 c++重构简单死亡之眼的效果
    虚幻社区中有蓝图教学视频使用C++重构,主要用到UGameplayStatics类中的SetGlobalTimerDilation方法,以及角色的相机管理器的调用,之后通过StartCameraFade方法实现显示效果UE4中的时间膨胀参考全局方法:SetGlobalTimerDilation(GetWorld(),Timer);对单个对象的时间膨胀:this->Cus......
  • 2309 c/c++二级
    5.话题焦点人物#include<bits/stdc++.h>usingnamespacestd;map<int,int>x;intmain(){intn,maxx=0,c;cin>>n;inta[n+1],b[n+1],k[n+1];for(inti=1;i<=n;i++){cin>>a[i]>>b[i];for(intj=1......
  • C++笔记 -- 使用STL的function实现回调机制(回调函数)
    1.使用普通函数示例一 代码:#include<iostream>#include<functional>//定义一个回调函数类型usingCallback=std::function<void(int)>;//定义一个函数,用于演示回调函数的使用voidperformOperation(intdata,Callbackcallback){//执......
  • C++中main(int argc, const char* argv[])的意义和命令参数的添加
    在C++程序中经常会看到main函数有两个输入参数,经常疑惑main不是C++入口吗,在调试的过程中有很少用到。最近查看一些工程时发现有些工程使用这两个参数,查资料得知这是命令,在没有UI但是又需要外部参数输入时极为方便。在VS中,该命令的设置在:项目"属性"->"调试"->"命令参数" ......
  • 第十四届C/C++研究生组省赛
    C.翻转首先如果第一个和最后一个棋子颜色不一样,那么是没办法用规则进行翻转的,输出-1。如果第一个和最后一个颜色相同,则遍历该串,若当前遍历的棋子颜色不一样,则看两边棋子颜色是否与当前棋子不同,若不同则可以改变颜色,若有一个相同则不能改变颜色,输出-1。#include<bits/stdc......
  • 【每日例题】蓝桥杯 c++ 绘制表格
    绘制表格题目蓝桥杯绘制表格题目分析阅读题目,我们可以将表格分为四个部分,头、中间的竖线部分与横线部分、尾。因此,我们可以启用多个for循环分别解决在第一行,我们也可以分为三个部分,第一部分符号为:“┌”,第二部分的中间部分使用for循环输入:“─┬”,第三部分符号为:“─┐”......
  • Visual C++ 6.0的快捷键
    F1-F12F1显示帮助,如果光标停在代码的某个字符上,显示MSDN中相应的帮助内容(需要安装MSDN才能使用)F2书签功能:Ctrl+F2--在某行设置一个书签(再按一次是取消)F2--跳到下一个书签位置Shift+F2--跳到上一个书签位置Ctrl+Shift+F2--删除所有书签F3查找:Ctrl+F3--在文件......