【问题标题】:Necessity of include_directories command in cmake projectcmake项目中include_directories命令的必要性
【发布时间】:2018-02-24 09:56:48
【问题描述】:

我正在学习有关 CMake 的教程,但我无法理解在某一时刻使用“include_directories”命令的必要性。

让我先解释一下这个项目:

在我的工作目录中,我有: - 一个 main.cpp 函数、一个 CMakeLists.txt(主要的)、一个配置文件、一个“MathFunction”目录和一个“build”目录

在 MathFunction 目录中,我有: - 将由主文件调用的 CMakeLists.txt 文件 - 一个文件“mysqrt.cxx”,其中包含将在“main.cpp”应用程序中使用的函数的实现 - 包含该函数原型的“MathFunctions.h”头文件

在“MathFunction”目录的 CMakeLists 中,我正在使用“mysqrt.cxx”中的代码创建一个库,如下所示:

add_library(MathFunctions mysqrt.cxx)

这个 sn-p 是我主要 CMake 代码的一部分:

# add the MathFunctions library?
#
if (USE_MYMATH)
 include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions") # WHY DO WE NEED THIS
 add_subdirectory (MathFunctions)
 set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)
endif (USE_MYMATH)

add_executable(Tutorial tutorial.cxx)
target_link_libraries (Tutorial MathFunctions)

现在我不明白为什么我还需要添加“include_directories”命令才能使用该库?最后一个命令'target_link_libraries'将已经创建的可执行文件和库链接在一起,这样就不需要include_directories,这还不够吗?

感谢您的阅读,如果我没有很好地解释它,我很抱歉,但我希望您能理解我的意思:D

【问题讨论】:

    标签: makefile cmake


    【解决方案1】:

    命令include_directories 设置要搜索的头文件 (.h) 的目录。 链接 (target_link_libraries) 与库基本上只指定一个库文件.so.dll 或其他类型)。如您所见,这些是不同的东西

    当将可执行文件与库 target 链接时,CMake 将该库目标的某些属性传播(更准确地说,“消耗”)到可执行文件。在这些属性中,有INTERFACE_INCLUDE_DIRECTORIES 属性,它将包含目录添加到可执行文件中。

    因此,当库目标正确设置了 INTERFACE_INCLUDE_DIRECTORIES 属性时,您无需显式指定可执行文件的包含目录:

    MathFunctions/CMakeLists.txt

    add_library(MathFunctions mysqrt.cxx)
    # Among other things, this call sets INTERFACE_INCLUDE_DIRECTORIES property.
    target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    

    CMakeLsits.txt

    add_executable(Tutorial tutorial.cxx)
    # This also propagates include directories from the library to executable
    target_link_libraries (Tutorial MathFunctions)
    

    注意,使用简单

    # This *doesn't* set INTERFACE_INCLUDE_DIRECTORIES property.
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    

    MathFunctions/CMakeLists.txt 中并不意味着将包含目录传播到链接的可执行文件。

    【讨论】:

    • 头文件和库不仅是不同的东西,而且与这个问题最相关的是它们通常存在于不同的目录中。头文件通常位于某种/path/to/include 目录中,而库位于某种/path/to/lib 目录中。所以,告诉 cmake 库在哪里是不够的:你还必须告诉它头文件在哪里。它不能假设它们是相同的。此外,包含目录的顺序可能很重要,因此需要明确说明。
    • Also, the order of directories for include can matter - 拥有相同名称的头文件被视为不好的方法,因此包含目录的顺序很少有问题。
    • 确实如此,但有时,对于第三方库,这是无法避免的。此外,有时你真的想要它;例如,一旦我创建了一个环境,该环境为在系统提供的系统中存在错误的系统提供标准 C/C++ 头文件的工作版本。在那种环境中,有多个副本,例如 stdio.h 等,您需要选择正确的副本。
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    相关资源
    最近更新 更多