CMakelists.txt 实现多级目录编译

一、单项目模式

指的是我有多个cpp文件,但是man函数入口只有一个;这种项目就称为 单项目;

1、单目录编译--单项目模式

单目录编译比1简单,以下代码即可满足,这种适合只有一个main函数入口的项目;

复制代码
# 单目录编译,只编译根目录下的文件
file (GLOB files  *.cpp) # 创建变量files
add_executable (lern  ${files} )

2、多目录编译--单项目模式

第一种方式:比较死板

以下这种方式比较死板,每添加一个文件都往 cMakeLists.txt 文件中加入cpp的路径,但却是最有效的方法;

复制代码
add_executable (main  a.cpp b.cpp a/c.cpp ... )
第二种方式:灵活,但是支持2级目录

以下方案是编译2级目录的方法,如果超过2级目录,目前还没找到更好的方法,

复制代码
# 多目录编译,编译根目录和子目录下的文件
file (GLOB_RECURSE files  *.cpp) # 创建变量files
add_executable (lern  ${files} )

二、多项目模式

指的是有多个cpp文件,每个文件都是一个单独的项目;也就是说,每个文件内都有一个main 函数;

1、多级目录-多项目模式

目录级别如下图,可以看到有三级目录,

2、传统方式-多项目模式

关键带看 *.cpp */*.cpp 所在行,这种方式只能编译当前目录以及子目录下的.cpp文件;

复制代码
file (GLOB_RECURSE files  *.cpp */*.cpp) # 创建变量files
# 对 files进行遍历
foreach (file ${files})
    message(STATUS ${file})
    string(REGEX REPLACE ".+/(.+)/(.+)\\..*" "\\1-\\2" exe ${file})
	# 每个文件内都有一个main 函数入口,所以要调用多次 add_executable() 函数
    add_executable (${exe} ${file} )
endforeach () # foreach 结束

3、新模式-递归编译-多项目模式

代码如下,这种方式可以编译所有的级别目录下的cpp文件,不管你有多少级,都可以完整编译整个项目,很实用

复制代码
# 定义函数,函数名为 makeAll
function(makeAll)
    # 遍历项目根目录和子目录下所有的 .cpp 文件
    makeDir(*)
    # 当前目录的cpp文件编译
    makeCpp(.)
endfunction()

# 编译目录
function(makeDir dir)
    # 判断字符串是否包含 cmake-build-debug ,将结果输出到indexOfStr变量,若包含返回 > -1的值,若不包含返回-1
    STRING(FIND ${dir} cmake-build-debug indexOfStr)

    if(NOT indexOfStr MATCHES -1)
        # 和 cpp的 return; 一样用法
        return()
    endif()

    file (GLOB dirs ${dir}) # 创建变量files
    foreach(item ${dirs})
        if(${item} EQUAL cmake-build-debug)
            # 和 cpp的 continue; 一样用法
            continue()
        endif()
        if(IS_DIRECTORY ${item}) # 判断是否目录,必须加上${} ,如果不加 ${} 就是字符串,无法判断是否目录

            makeDir(${item}/*) # 递归
            makeCpp(${item}) # 编译cpp
        endif()
        #    message(STATUS ${item})
    endforeach()

endfunction()


# 编译单个目录下的所有cpp文件
function(makeCpp dir)
    file (GLOB cpp_files ${dir}/*.cpp) # 创建变量files
    foreach(item ${cpp_files})
        message("make cpp file ->" ${item})
        string(REGEX REPLACE ".+/(.+)/(.+)\\..*" "\\1-\\2" exe ${item})
        add_executable (${exe} ${item} )
    endforeach()
endfunction()

# 调用函数--编译所有的目录以及子目录
makeAll()

让我们看看编译后的打印的信息

相关推荐
qq_460978404 分钟前
实现 Svelte 中基于数组索引的 details 元素单开单关交互
jvm·数据库·python
A-Jie-Y12 分钟前
JAVA设计模式-抽象工厂模式
java·设计模式
@insist12325 分钟前
信息安全工程师-密码学专题(下):构建可信网络空间的核心机制
java·大数据·密码学·软考·信息安全工程师·软件水平考试
这个DBA有点耶30 分钟前
3步抓出慢SQL,别等半夜被叫醒😴
数据库·代码规范
摇滚侠34 分钟前
Java 零基础全套视频教程,面向对象(高级),笔记 105-120
java·开发语言·笔记
dfdfadffa36 分钟前
SQL窗口函数如何优化嵌套子查询_提升执行效率
jvm·数据库·python
叶落阁主42 分钟前
Spring Boot 4 实战:Jackson 2.x 升级到 3.x 踩坑全记录
java·后端·架构
布吉岛的石头42 分钟前
Java 中高级面试:JVM 内存模型 + GC 算法高频题总结
java·jvm·面试
m0_588758481 小时前
如何查看集群版本_crsctl query crs activeversion当前版本
jvm·数据库·python
Mortalbreeze1 小时前
软件包管理器yum和编辑器vim详解 —— 附带vim配置链接
linux·服务器