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:相对头文件路径的主要内容,如果未能解决你的问题,请参考以下文章
Windows + VS2019 + CMake + CLion + Conan:如何启用C++20?