【问题标题】:CMake add library with subdirectoriesCMake添加带有子目录的库
【发布时间】:2017-02-19 00:14:14
【问题描述】:

TL;DR

使用 CMake,我如何将子目录包含到库中,以便在不引用它们所在目录的情况下包含它们?

结束 TL;DR

为了尽量简明扼要,并以更高层次的想法说明什么和如何,我删除了所有我认为不必要的细节。如果需要,我会进行编辑。因此,这是我的项目结构的简要概要。

ParentDir
--src
----source.cpp
----source.h
----entities_dir
------entity.cpp
------entity.h
------CMakeLists.txt
----CMakeLists.txt
--CMakeLists.txt
--main.cpp

就目前而言,我在 src 目录中有一个由 CMakeLists 定义的库。因此,我可以通过#include 将src 文件包含在main 中,与#include "src/file.h" 相对,我希望能够对src 子目录中存在的头文件执行相同的操作。

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(Project) 

add_executable(Project ${SOURCE_FILES} main.cpp)
include_directories(src)
add_subdirectory(src)
target_link_libraries(Project Library) # Engine Libraries

src/CMakeLists.txt

file(GLOB SOURCE_FILES *.cpp)
file(GLOB HEADER_FILES *.h)

add_library(Library STATIC ${SOURCE_FILES} ${HEADER_FILES})

ma​​in.cpp

#include <source.h> // this works
#include <entity.h> // this does not work but I want it to
#include <entities/entity.h> // this works but I don't want this
int main() {}

我不确定该怎么做。我尝试了 GLOB_RECURSE、add_subdirectory(entities) 等。我还尝试在 src/entities/CMakeLists.txt 中创建一个名为 Entities 的库,并将其与 link_libraries 链接。这些都没有成功。完成此操作的正确方法是什么,因为我认为我可能完全错误地处理了这个问题。

【问题讨论】:

  • 您需要在编译器头文件搜索路径中使用该路径,这是通过 include_directories() 调用实现的。您可以将现有的 include_directories(src) 调用修改为 include_directories(src src/entities)。我不知道如何进行递归,我也不推荐它。
  • 这样就行了。不过,这似乎在挑战我对您应该如何使用 cmake 的理解。我已经看到在每个目录中都有 cmakelists 是司空见惯的。由于在这种情况下,src cmakelists 正在创建实际的库,所以父 cmake 不应该只需要引用 src cmake 而不需要了解 src 子目录吗?
  • @qexyn 如果你想留下答案,我会接受。

标签: c++ cmake


【解决方案1】:

您需要编译器头文件搜索路径中的该路径,这是通过 include_directories() 调用实现的。您可以将现有的 include_directories(src) 调用修改为:

include_directories(src src/entities)

另外,这篇 SO 帖子是相关的,值得一读:Recursive CMake search for header and source files。 CMake网站本身有一段摘录建议不要使用文件(GLOB ...),这有助于推荐一般的递归解决方案。作为 CMake 的重度用户,我同意反对它的论点。

【讨论】:

    【解决方案2】:

    你只需要添加:

    include_directories(${CMAKE_CURRENT_LIST_DIR})
    

    在您的层次结构中的每个 CMakeLists.txt 中。

    CMake 本身不会编译您的项目,它只会调用您的工具链并将参数传递给它,而您的工具链并不“知道”它正在被 CMake 调用,或者您的项目结构。因此,您需要告诉工具链在哪里找到包含文件。

    虽然在每个子目录中都有一个 CMakeLists.txt 是司空见惯的,但这绝不是必需的。 src 目录中的 CMakeLists.txt 可能包含生成构建所需的所有指令。通常,CMakeLists.txt 放在每个级别,以使结构更易于管理,例如。每个目录只需要知道它需要做什么(大概是该目录中的文件)。

    【讨论】:

    • 很遗憾,这不起作用。根据评论的建议,我确实添加了“include_directories(src/entities)”,它起作用了,但是我真的在寻找一个答案,我可以只使用“include_directories(src)”和 src 目录中的 CMakeLists.txt 句柄所有子目录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2012-02-14
    • 1970-01-01
    • 2018-04-08
    • 1970-01-01
    相关资源
    最近更新 更多