【问题标题】:cmake find all directories by name on the include path and add them to the include pathcmake 在包含路径上按名称查找所有目录并将它们添加到包含路径
【发布时间】:2021-07-24 21:39:36
【问题描述】:

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

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

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 标头下载到某个本地目录的构建环境中呢? cmake 的重点是使用不同的本地配置,因此添加基于平台的硬编码单一路径将是愚蠢的。我希望未来的某个人想要使用下载到~/projects/headers/SDL2 的 SDL2 头文件来编译我的代码,以便能够在仅指定 ~/projects/headers 到他们的包含路径后进行编译,这样他们就不必处​​理内部的 SDL问题。

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

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

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

【问题讨论】:

  • @Tsyvarev 请参阅编辑
  • 我并没有责怪 cmake 没有添加它。我在问如何正确使用 cmake。
  • @Tsyvarev 没用。仍然收到有关 begin_code.h 丢失的相同错误。
  • 好的,看来脚本/usr/lib/x86_64-linux-gnu/cmake/SDL2/sdl2-config.cmake 是包libsdl2-dev 的一部分,是错误的。就其本身而言,CMake 对这个问题无能为力。作为修复,您可以调用类似find_path(SDL_INC_DIR1 "begin_code.h" PATH_SUFFIXES "SDL2") 并将${SDL_INC_DIR1} 添加到包含目录列表中。这样您就可以避免硬编码。
  • 这行得通,尽管我试图避免依赖该文件的名称,因为 SDL 完全有权更改该文件的名称而不会发出警告。所以这让我们回到了最初的问题:我是否可以简单地将所有恰好位于现有包含路径目录下的名为“SDL2”的文件夹添加到包含路径。多次拿起错误的文件夹将是无害的,并且更适合未来,因此更可取。

标签: cmake configuration include


【解决方案1】:

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

这种形式用命令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")

将使用包含标题begin_code.h 的目录填充变量SDL2_INCLUDE_DIR_1

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

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

如果您认为 SDL2 开发人员可以重命名有问题的文件,但希望该文件位于 SDL2.h 附近,那么您可以将上述命令更改为搜索 SDL2.h 而不是 begin_code.h

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-04
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多