检查makefile中路径是绝对路径还是相对路径的可移植方法

时间:2018-09-21 21:53:56

标签: makefile gnu-make

我正在研究一个新的Makefile基础结构,到目前为止,我已经设法使其变得可移植(就GNU-make而言):

  • 在Linux上
  • 在Windows上(仅适用于CMD shell + GnuWin32 CoreUtils + GnuWin32 Make)
  • 在Windows上(带有MSYS2 shell)

我正在使用罐装食谱,并且食谱使用顶部提供的参数。这些参数通常是标头包含目录,库包含目录。

到目前为止,我已经假定提供给罐装配方的所有路径都是相对于Makefile所在的位置的-在配方中,这些路径始终以以下前缀:

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

最近,我遇到了一个例子,其中我需要指定的包含路径相对而言并不简单。 如果coreutils“ realpath --relative-to”在Windows上运行,我会使用它,但事实并非如此。同样在Windows上,相对路径并非总是可能的,例如如果包含目录和Makefile位于不同的驱动器上。

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

任何建议如何以健壮和可移植的方式做到这一点?

1 个答案:

答案 0 :(得分:0)

我们可以检查各种情况:

  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函数的类似组合添加。