检查 makefile 中路径是绝对路径还是相对路径的便携方法

Portable way to check if a path is absolute or relative in a makefile

我正在研究一个新的 Makefile 基础结构,到目前为止,我已经设法使它在工作的意义上非常便携(GNU-make):

我正在使用罐装食谱,并且这些食谱使用了顶部提供的参数。这些参数通常是 header include dirs 和 library include dirs。

到目前为止,我假设所有提供给固定食谱的路径都是相对于 Makefile 所在位置的 - 在食谱中,这些路径总是以以下为前缀:

ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

最近,我遇到了一个示例,其中我需要指定的包含路径在相对术语中并不简单。 如果 coreutils "realpath --relative-to" 在 Windows 上工作,我会使用它,但事实并非如此。同样在 Windows 上,相对路径并不总是可行的,例如如果 include 目录和 makefile 在不同的驱动器上。

所以我目前首选的方法是在罐头食谱中检测作为参数提供的路径是绝对路径还是相对路径。仅当它是相对的时,它才会以 ROOT_DIR 为前缀,否则按原样使用。

关于如何以健壮且便携的方式执行此操作的任何建议?

我们可以检查各种情况:

  1. 领先/
  2. 领先~,
  3. 前导 X: 其中 X 是大写字母(Windows 驱动器),
  4. 领先\(Windows网络驱动器)

并为每个变量设置一个变量 yes 或空字符串:

IS_ROOT    := $(if $(patsubst /%,,$(THE_PATH_TO_CHECK)),,yes)
IS_HOME    := $(if $(patsubst ~%,,$(THE_PATH_TO_CHECK)),,yes)
IS_NETWORK := $(if $(patsubst \\%,,$(THE_PATH_TO_CHECK)),,yes)
IS_DRIVE   := $(foreach d,A B C D E...Z,$(if $(patsubst $(d):/%,,$(THE_PATH_TO_CHECK)),,yes))

然后,我们可以测试这些变量的串联是否等于yes

ifeq ($(strip $(IS_ROOT)$(IS_HOME)$(IS_NETWORK)$(IS_DRIVE)),yes)
<absolute>
else
<relative>
endif

当然,如果您有其他情况,可以使用类似的 make 函数组合来添加它们。