cmake 在包含路径上按名称查找所有目录并将它们添加到包含路径

cmake find all directories by name on the include path and add them to the include path

我正在使用一个库,该库名义上将其内部 header 存储在一个目录中,该目录本身不在包含路径中,尽管它的 parent 是。包含预期的入口点 header 最终会失败,因为它通过引用的 include 链接到其他内部 headers 而没有目录名称。

我在我系统的 /usr/include/SDL2/SDL.h 中执行编译器确实找到的 #include <SDL2/SDL.h>,但它随后找不到“begin_code.h”,它包含在 SDL 内部更深的几层中header代码。

In file included from /usr/include/SDL2/SDL.h:32:
In file included from /usr/include/SDL2/SDL_main.h:25:
In file included from /usr/include/SDL2/SDL_stdinc.h:31:
In file included from /usr/include/SDL2/SDL_config.h:4:
In file included from /usr/include/x86_64-linux-gnu/SDL2/_real_SDL_config.h:33:
/usr/include/x86_64-linux-gnu/SDL2/SDL_platform.h:179:10: fatal error: 'begin_code.h' file not found
#include "begin_code.h"
         ^~~~~~~~~~~~~~
1 error generated.

手动添加 -iquote /usr/include/SDL2 在我的情况下有效,但是在 SDL2 header 被下载到某个本地目录的构建环境中呢? cmake 的要点是使用不同的本地配置,因此添加基于平台的 hard-coded 单一路径是愚蠢的。我希望未来的某个人想要使用下载到 ~/projects/headers/SDL2 的 SDL2 header 编译我的代码,以便能够在仅指定 ~/projects/headers 到他们的包含路径后进行编译,例如,所以他们不必处理 SDL 的内部问题。

在我看来,我只需要遍历 -iquote 路径上的每个目录,如果它包含目录名称 SDL2,则将该目录添加到 -iquote。 cmake 是否提供(取决于系统配置)-iquote 路径作为可遍历列表?

为了清楚起见,我试图改写 this unasnwered question 这个问题。

编辑: 我知道 cmake 不负责 解决问题,但 cmake(或者更确切地说,CMakeList.txt 文件)应该能够 解决这个 SDL 错误。 Hard-coding 假定路径仅对通过某些标准包管理器安装 SDL2 header 的构建系统可靠。我从未见过 unix 开发人员手动下载 header 文件并将它们粘贴到系统包含路径中,因为担心它们可能被覆盖或以其他方式与将来安装的官方 headers 包发生冲突。还有其他放置包含文件的有效位置,因此 cmake 应该能够搜索它们。消除 hard-coded 路径不是 cmake 的一半吗?

CMake 不提供对包含目录进行 custom 迭代的方法。 相反,您可以将您的意图重新表述为“查找具有给定 header”的目录。

该形式用命令find_path表示,这是CMake中搜索包含目录的一种自然方式。

例如那个电话:

# Task for CMake: Find a directory with "begin_code.h" header in it.
#   Possibly, this is subdirectory 'SDL2' of a "normal" include directory.
find_path(SDL2_INCLUDE_DIR_1 "begin_code.h" PATH_SUFFIXES "SDL2")

将用包含 header begin_code.h.

的目录填充变量 SDL2_INCLUDE_DIR_1

如果使用 CMAKE_PREFIX_PATH 变量为 CMake 提示该安装,则这种方式在本地安装 SDL2 的情况下非常有效。为了支持其他提示,例如SDL2DIR 环境变量,您需要在调用中添加适当的 PATHS 选项:

find_path(SDL2_INCLUDE_DIR_1 "begin_code.h" PATH_SUFFIXES "SDL2" PATHS ENV SDL2DIR)

如果您觉得 SDL2 开发人员可以重命名有问题的文件,但希望该文件靠近 SDL2.h,那么您可以将上述命令更改为搜索 SDL2.h 而不是 [=14] =]:

find_path(SDL2_INCLUDE_DIR_1 "SDL2.h" PATH_SUFFIXES "SDL2" PATHS ENV SDL2DIR)