CMake:Include vs add_subdirectory:相对头文件路径

Posted

技术标签:

【中文标题】CMake:Include vs add_subdirectory:相对头文件路径【英文标题】:CMake: Include vs add_subdirectory: Relative header file path 【发布时间】:2018-04-23 14:50:57 【问题描述】:

我有一个包含多个子目录的 c++ 项目,例如

src/
  CMakeLists.txt
  main.cpp
  module1/
     CMakeLists.txt
     code.cpp
     code.h
  module2/
     CMakeLists.txt
     code2.cpp

似乎在cmake中处理这个问题的两种方法是在我的src/CMakeLists.txt中使用add_subdirectory(module1)include(module1)。我在某处读到,include 的使用被视为遗留/弃用。我的src/module1/CMakeLists.txt 看起来像这样:

include_directories($CMAKE_CURRENT_LIST_DIR)

set( SRCS
    $SRCS
    $CMAKE_CURRENT_LIST_DIR/code.cpp
   )

set( QT_FILE_HEADERS 
    $QT_FILE_HEADERS code.h
   )

如果我尝试使用add_subdirectory 方法并想在main.cpp 中使用code.h,我必须写#include "module1/code.h"。如果我做include添加module1的方法,我可以简单地写#include "code.h"。当我在其他地方使用包含文件时,我不想指定它们的相对路径,有没有办法使用add_subdirectory 方法来实现这一点?我认为include_directories 行应该已经解决了这个问题。

【问题讨论】:

CMake 的 include 绝对不会被弃用或遗留 通常认为将头文件放入子目录以避免名称冲突并在安装后具有更好的结构/usr/include 是一种很好的做法。它还消除了为您的代码用户指定 -Imodule1 的要求。 如果我没记错的话,这意味着使用 include 添加包含自己的 CMakeList 文件的子目录 我不明白为什么这被标记为重复。另一篇文章与include 关键字无关。简而言之,add_subdirectory 引入了一个新的作用域,而include 没有。您将在这篇文章中找到更多解释:crascit.com/2016/01/31/enhanced-source-file-handling-with-target_sources。我认为一般来说最好使用add_subdirectory,除非你出于某种原因需要使用include。例如,在定义新目标或在子目录中启用新语言时,有时会发生这种情况。 @numberCruncher 您的代码是否使用add_subdirectory 编译?在您的set(SRC... 声明中没有PARENT_SCOPE,因此似乎实际上并未包含该源文件。 【参考方案1】:

这不是你应该制作模块的方式——确保你可以这样做,它有效,但它不是很有用。根据您的布局,只需在 CMakeLists.txt 主文件中引用 module1/code.cpp

但是,如果您想使用模块,请将每个模块都设为单独的静态库。这将真正简化事情!

src/CMakeLists.txt 写:

add_subdirectory(module1)

add_executable(myprogram main.cpp)
target_link_libraries(myprogram module1)

src/module1/CMakeLists.txt 写:

add_library(module1 STATIC code.cpp)
target_include_directories(module1 PUBLIC $CMAKE_CURRENT_SOURCE_DIR)

这样,您只需从module1 CMake 脚本传回一件事:module1 目标。你的main 不需要知道里面发生了什么。如果module1 中的代码需要特定的外部库,请将它们链接到那里,主 CMake 脚本不需要知道它。只需链接到module1,所有的魔法都会在幕后发生,您的程序将使用正确的包含目录编译并链接到正确的库。

【讨论】:

以上是关于CMake:Include vs add_subdirectory:相对头文件路径的主要内容,如果未能解决你的问题,请参考以下文章

vs+cmake+使用静态库

Windows + VS2019 + CMake + CLion + Conan:如何启用C++20?

CMake 为 VS 项目生成循环依赖,但不生成文件。如何避免?

cmake编译后能给vs使用吗

使用 WSL 和 VS2019 进行 Cmake

VS2017 CMake配置