当前位置: 首页>>技术教程>>正文


如何使用CMake正确添加包含目录

, ,

问题描述

大约一年前,我询问了header dependencies in CMake

最近我意识到问题似乎是CMake认为这些头文件在项目外部。至少在生成Code :: Blocks项目时,头文件不会出现在项目中(源文件会出现)。因此,在我看来,CMake认为那些标头在项目外部,而不在依赖中跟踪它们。

在CMake教程中快速搜索仅指向include_directories,这似乎并没有达到我的期望。

向CMake发出信号的正确方法是什么,即特定目录包含要包含的标头,并且应由生成的Makefile跟踪这些标头?

最佳方法

必须做两件事。

首先添加要包含的目录:

target_include_directories(test PRIVATE ${YOUR_DIRECTORY})

如果您使用的是非常老的CMake版本(2.8.10或更早版本)而又不支持target_include_directories,则也可以改用旧版include_directories

include_directories(${YOUR_DIRECTORY})

然后,还必须将头文件添加到当前目标的源文件列表中,例如:

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})

这样,头文件将作为依赖项显示在Makefile中,如果生成的话也将显示在生成的Visual Studio项目中。

如何将这些头文件用于多个目标:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)

add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})

次佳方法

首先,使用include_directories()告诉CMake将目录作为-I添加到编译命令行。其次,您在add_executable()add_library()调用中列出标题。

例如,如果您项目的源位于src中,并且您需要来自include的标头,则可以这样进行:

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)

第三种方法

如果将CMake与其他创建Makefile的方式(例如make或qmake)进行比较,则CMake更像是一种脚本语言。它不像Python那样酷,但仍然如此。

如果在各种开源项目中查看人们如何包含目录,就没有”proper way”这样的东西。但是有两种方法可以做到这一点。

  1. 粗略的include_directories会将目录添加到当前项目以及所有其他后代项目,您将通过一系列add_subdirectory命令添加该目录。有时人们会说这种方法是遗留的。

  2. target_include_directories是更优雅的方法。它允许为特定项目/目标附加目录,而不会(可能)不必要地继承或冲突各种包含目录。还允许执行微妙的配置,并为此命令附加以下标记之一。

PRIVATE-仅用于此指定的构建目标

PUBLIC-将其用于指定目标和与此项目链接的目标

接口-仅将其用于与当前项目链接的目标

PS:

  1. 这两个命令都允许将目录标记为SYSTEM,以提示您指定目录包含警告不是您的公司。

  2. 其他对命令的相似答案是target_compile_definitions /add_definitionstarget_compile_options /CMAKE_C_FLAGS

第四种方法

添加include_directories("/your/path/here")

这类似于使用-I/your/path/here/选项调用gcc

确保在路径两边加上双引号。其他人没有提及,这让我呆了2天。因此,此答案适用于刚接触CMake且非常困惑的人。

第五种方法

我有同样的问题。

我的项目目录如下:

    --project
    ---Classes
    ----Application
    -----.h and .c files
    ----OtherFolders
    --main.cpp

以及我以前在所有这些文件夹中包括的文件:

    file(GLOB source_files
            "*.h"
            "*.cpp"
            "Classes/*/*.cpp"
            "Classes/*/*.h"
    )

    add_executable(Server ${source_files})

它完全有效。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/9081.html,未经允许,请勿转载。