使用 CMake 从没有相对路径的子目录导入

Posted

技术标签:

【中文标题】使用 CMake 从没有相对路径的子目录导入【英文标题】:Importing from child directory without a relative path with CMake 【发布时间】:2020-08-17 12:20:14 【问题描述】:

鉴于这样的项目结构:

project/
    src/
        CMakeLists.txt
        foo.h
        main.cpp
        util/
            CMakeLists.txt
            bar.h 

bar.h 内部是否可以有一个包含语句为 #include "foo.h" ?我已经通过 Visual Studio 中的“预编译头”配置看到了一些可能的方法,但不直接使用 CMake。

【问题讨论】:

假设您在 include 目录中有project/src 目录,那么#include "foo.h" 将起作用。在 CMake 中包含目录是使用 include_directories 命令指定的。 也可以使用https://cmake.org/cmake/help/v3.9/command/target_include_directories.html 这与预编译的头文件无关。 #include "../foo.h" 有什么问题?为什么util 会触及其父级?听起来设计很糟糕。 @WilliamBright 关键是,为源代码树中的每个目录都有一个 CMakeLists.txt 不是正确的方法。 【参考方案1】:

好消息是 CMake 中的编译过程适用于 target 依赖项,而不是 file 依赖项。所以你不需要改变你的文件层次结构,你只需要修改目标层次结构,而不是太多。

    在文件 src/CMakeLists.txt 中,创建额外的 INTERFACE 目标,例如 src_interface
    add_library( src_interface INTERFACE )
    
    将包含目录添加到其中:
    target_include_directories( src_interface INTERFACE $CMAKE_CURRENT_SOURCE_DIR )
    
    这需要在添加 util 作为子目录之前完成
    add_subdirectory( util )
    
    在 src/util/CMakeLists.txt 中,添加到界面的链接:
    target_link_libraries( util_target PRIVATE src_interface )
    

更多关于 CMake 中的 INTERFACE 库:https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries

【讨论】:

好的,我刚刚测试过,效果很好。当然,您需要将它与 CMakeLists.txt 的其余内容正确集成。一个问题可能是目标范围命令与文件范围命令的混合。另一个问题可能是 target_link_libraries 命令,您需要在其中放置实际 util 目标的名称。如果您需要更多帮助,只需发布​​您的完整构建脚本即可。

以上是关于使用 CMake 从没有相对路径的子目录导入的主要内容,如果未能解决你的问题,请参考以下文章

[cmake][转载]add_subdirectory详解

Python 导入相对路径

相对导入

在Python中以绝对路径或者相对路径导入文件(或模块)的方法

使用相对路径时,./../../../,代表的什么?

ReferenceError: $ is not defined (绝对路径和相对路径)