CMake 的继承关系

1. CMake如何确定继承关系

        在 CMake 中,父子关系是通过文件系统中的目录结构来定义的。当你在一个目录中创建一个 CMakeLists.txt 文件时,该目录就被视为一个 CMake 项目的目录,而该文件中的内容将被用于配置和构建该目录中的项目。

        当你在父目录的 CMakeLists.txt 文件中使用 `add_subdirectory()` 命令来包含子目录时,CMake 就会将子目录与父目录建立起父子关系。这意味着子目录中的 CMakeLists.txt 文件可以访问并继承父目录的变量、函数和设置,除非在子目录中显式地覆盖或修改了这些设置。

        因此,父子关系是由项目的目录结构和 `add_subdirectory()` 命令来确定的。只有在父目录中包含了子目录,并且在子目录中包含了父目录的设置时,才能说这两个目录之间存在父子关系。

2. 继承关系        

        在 CMake 项目中,`find_package()` 和 `target_link_libraries()` 分别用于查找和链接外部库。通常,当你在根目录的 CMakeLists.txt 文件中使用了这些命令,并且子目录的 CMakeLists.txt 文件没有覆盖或修改这些设置时,这些设置将会被继承到子目录中。

        在 CMake 中,当你在一个目录中包含另一个目录时,就会建立父子关系。这通常是通过在父目录的 CMakeLists.txt 文件中使用 `add_subdirectory()` 命令来实现的。

例如,假设有以下的目录结构:

project/
├── CMakeLists.txt (父目录)
├── subdirectory/
│   └── CMakeLists.txt (子目录)

在父目录的 CMakeLists.txt 文件中,你可以包含子目录,如下所示:

# 父目录的 CMakeLists.txt 文件
add_subdirectory(subdirectory)

        这样做后,子目录中的 CMakeLists.txt 文件就能够访问和继承父目录的设置。

        现在让我们考虑一个更具体的例子。假设在父目录的 CMakeLists.txt 文件中定义了一个变量 `FOO`,子目录的 CMakeLists.txt 文件也想使用这个变量。可以这样做:


# 父目录的 CMakeLists.txt 文件
set(FOO "Hello from the parent directory")

add_subdirectory(subdirectory)


# 子目录的 CMakeLists.txt 文件
message("In the subdirectory: ${FOO}")

        在这个例子中,子目录的 CMakeLists.txt 文件能够访问并使用父目录中定义的变量 `FOO`,因为父目录通过 `add_subdirectory()` 命令包含了子目录。

        因此,父目录和子目录之间的关系建立在包含关系的基础上,而不是在代码中直接指定父子关系。只要在父目录中包含了子目录,并且子目录中的 CMakeLists.txt 文件使用了父目录中定义的设置,就可以说这两个目录之间存在父子关系。

        以上说明的是显示的继承关系,也包含隐式的继承关系,如果子目录的 CMakeLists.txt 文件没有使用父目录中定义的任何变量、函数或设置,并且没有任何其他方式显式地依赖于父目录,那么可以说它们之间没有显式的父子关系。

        在这种情况下,尽管你可能在父目录的 CMakeLists.txt 文件中使用了 `add_subdirectory()` 命令包含了子目录,但子目录不会继承父目录的任何设置或变量,也不会被视为父目录的子项目。相反,子目录会被视为独立的项目,它们之间的联系仅限于目录结构。

        这种情况下的父子关系是隐式的,因为你使用了 `add_subdirectory()` 命令包含了子目录,但子目录并没有直接依赖于父目录。

        这种继承关系主要表现在项目构建过程中。当你在父目录中执行 CMake 构建时,它会递归地构建子目录,从而构建整个项目。因此,子目录会受到父目录构建过程的影响,即使子目录中的 CMakeLists.txt 文件没有显式地引用父目录的设置或变量。

        这种继承关系主要影响构建过程,而不会直接影响 CMake 变量或设置的传递。如果在子目录中需要访问父目录的设置或变量,仍然需要在子目录的 CMakeLists.txt 文件中显式地引用它们。

3. 其他        

        在 CMake 中,`find_package()` 和 `target_link_libraries()` 命令的行为取决于它们的位置和作用域。通常情况下,子目录的 CMakeLists.txt 文件中的命令会覆盖父目录中相同名称的命令。

        但是,如果在子目录的 CMakeLists.txt 文件中使用了 `PRIVATE`、`PUBLIC` 或 `INTERFACE` 关键字将目标链接到库时,它会将链接的设置限定在当前目标中,而不会影响到父目录或其他目标。这意味着,即使子目录中使用了 `target_link_libraries()` 命令,也不会影响到父目录的设置。

        因此,如果子目录的 CMakeLists.txt 文件中的 `target_link_libraries()` 命令没有将目标链接到 某个库,那么父目录中的 连接到这个库的设置仍然会保持有效,并且可以在子目录中使用 这个库的头文件和链接库,而不会报错。

当在子目录的 CMakeLists.txt 文件中使用 `target_link_libraries()` 命令时,如果使用了 `PUBLIC`、`PRIVATE` 或 `INTERFACE` 关键字,它们会指定链接的属性范围。具体来说:

PUBLIC: 当使用 `PUBLIC` 关键字时,链接的设置会应用于当前目标和所有依赖该目标的目标。这意味着,这些设置会被继承到依赖目标中,同时也会保留在当前目标中。

PRIVATE: 当使用 `PRIVATE` 关键字时,链接的设置仅适用于当前目标,不会被传递到依赖目标中。

INTERFACE: 当使用 `INTERFACE` 关键字时,链接的设置不会应用于当前目标,而是仅应用于依赖目标。这意味着,这些设置会被传递到依赖目标中,但不会影响当前目标。

        因此,如果在子目录的 CMakeLists.txt 文件中使用了 `target_link_libraries()` 命令,并且使用了 `PUBLIC` 关键字,那么链接的设置会同时继承父目录的设置,并保留在当前目标中。这样既可以继承父目录的设置,又可以在子目录中保留自己的设置,不会覆盖父目录的设置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值