CMake之嵌套的CMakeLists

举报
人才程序员 发表于 2024/09/14 19:03:04 2024/09/14
【摘要】 @TOC 前言在现代软件开发中,CMake 是一个非常重要的工具,它允许开发者编写可移植的构建脚本来管理项目。对于大型项目,通常会有多个模块或子项目,这时候就需要用到嵌套的 CMakeLists 文件来组织代码。本文将简要介绍如何使用嵌套的 CMakeLists 来管理复杂的项目结构。 项目结构.├── build│ ├── cJSON│ ├── CMakeCache.txt│ ...

@TOC


前言

在现代软件开发中,CMake 是一个非常重要的工具,它允许开发者编写可移植的构建脚本来管理项目。对于大型项目,通常会有多个模块或子项目,这时候就需要用到嵌套的 CMakeLists 文件来组织代码。本文将简要介绍如何使用嵌套的 CMakeLists 来管理复杂的项目结构。


项目结构

.
├── build
│   ├── cJSON
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── log
│   ├── Makefile
│   └── test1
├── cJSON
│   ├── cJSON.c
│   └── CMakeLists.txt
├── CMakeLists.txt
├── include
│   ├── cJSON.h
│   └── log.h
├── log
│   ├── CMakeLists.txt
│   └── log.c
└── test1
    ├── CMakeLists.txt
    └── main.c

9 directories, 12 files

节点关系

众所周知,Linux的目录是树状结构,所以嵌套的 CMake 也是一个树状结构,最顶层的 CMakeLists.txt 是根节点,其次都是子节点。因此,我们需要了解一些关于 CMakeLists.txt 文件变量作用域的一些信息:

根节点CMakeLists.txt中的变量全局有效
父节点CMakeLists.txt中的变量可以在子节点中使用
子节点CMakeLists.txt中的变量只能在当前节点中使用

这三个概念是CMake中变量作用域的基本规则,可以这样理解:

  • 根节点变量: 在最顶层的CMakeLists.txt文件中定义的变量,它们在整个项目中都是可见的。这意味着无论在项目的哪个位置,这些变量都可以被访问和使用。

  • 父节点变量: 在某个目录的CMakeLists.txt文件中定义的变量,它们可以被该目录下的子目录(即子节点)中的CMakeLists.txt文件使用。父节点变量对子节点来说是可见的,但不会影响到其他平行的目录。

  • 子节点变量: 在子目录的CMakeLists.txt文件中定义的变量,它们仅在当前子目录的范围内有效。这些变量对父目录或其他目录中的CMakeLists.txt文件是不可见的。

如何区分父子节点:
父节点:如果一个目录包含其他的子目录,并且这个目录下有一个CMakeLists.txt文件,那么我们就称这个目录为"父节点"。父节点中定义的变量可以在其所有子节点中使用。

子节点:如果一个目录位于另一个目录下,并且这个目录下也有一个CMakeLists.txt文件,那么我们就称这个目录为"子节点"。子节点可以使用其父节点中定义的变量,但是子节点中定义的变量只能在当前子节点中使用,对父节点或其他子节点不可见。

如何嵌套多个cmake

我们可以在每个小目录下的CMakeLists.txt里面去生成动态/静态库,然后在你含main.c里面的CMakeLists.txt去链接他们,这样就能实现对应的效果了。
那么,为什么不使用把源文件干过来呢?
这样就失去了意义啊,CMakeLists.txt就毫无作用了

在根目录中,我们可以使用add_subdirectory()这个去添加子目录

示例程序cmake

根节点:
一般,我们在根节点可以直接把头文件加入进去,就不用子节点去添加了

cmake_minimum_required(VERSION 3.2)
project(MyProject)

# 添加头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)

# 添加子目录
add_subdirectory(cJSON)
add_subdirectory(log)
add_subdirectory(test1)

log目录:

aux_source_directory(. DIR_LIB_SRCS)
add_library(log ${DIR_LIB_SRCS})

cJSON目录:

aux_source_directory(. DIR_LIB_SRCS)
add_library(cJSON ${DIR_LIB_SRCS})

main目录:

aux_source_directory(. DIR_SRCS)
add_executable(test1 ${DIR_SRCS})

# 链接库文件
target_link_libraries(test1 cJSON log)

总结

通过使用嵌套的 CMakeLists 文件,我们可以有效地管理大型项目中的多个子模块。这种方法提供了清晰的模块划分,便于维护和扩展。虽然初学者可能会觉得有些复杂,但一旦掌握了基本概念和语法,就能够利用 CMake 强大的功能来构建高效、可维护的构建系统。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。