Портативный способ проверить, является ли путь абсолютным или относительным в make-файле - PullRequest
0 голосов
/ 22 сентября 2018

Я работаю над новой структурой Makefile, которую мне удалось сделать очень переносимой в том смысле, что она работает (с GNU-make):

  • в Linux
  • в Windows (только с оболочкой CMD + GnuWin32 CoreUtils + GnuWin32 Make)
  • в Windows (с оболочкой MSYS2)

Я использую консервированные рецепты, а в рецептах используются аргументыпредоставляется сверху.Эти аргументы, как правило, включают заголовочные каталоги dirs, а библиотечные включают dirs.

До сих пор я предполагал, что все пути, предоставленные для консервированных рецептов, относятся к месту, где находится Makefile. Внутри рецептов эти пути всегда начинаются с префикса:

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

Совсем недавно я натолкнулся на пример, где путь включения, который мне нужно указать, не так просто указать в относительном выражении.Если бы coreutils "realpath --relative-to" работал в Windows, я бы использовал его, но это не так.Также в Windows относительные пути в любом случае не всегда возможны, например, если каталоги include и make-файл находятся на разных дисках.

Поэтому в настоящее время мой предпочтительный подход заключается в том, чтобы определить в готовом рецепте, если путь указан какаргумент является абсолютным или относительным.Только если он относительный, к нему добавляется префикс ROOT_DIR, в противном случае он используется как есть.

Есть предложения, как это сделать, надежным и переносимым способом?

1 Ответ

0 голосов
/ 22 сентября 2018

Мы можем проверить различные случаи:

  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.

...