Экранирование двоеточий в именах файлов в Makefile - PullRequest
16 голосов
/ 13 января 2010

Есть ли способ заставить GNU make правильно работать с именами файлов, которые содержат двоеточия?

Конкретная проблема, с которой я сталкиваюсь, связана с правилом шаблона. Вот упрощенная версия, которая не зависит от вырезания и вставки символов табуляции:

% make --version
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-redhat-linux-gnu
% cat Makefile
COLON := \:
all: ; true
%.bar: ; cp $< $@
x.bar: x.foo
%.foo: ; touch $@
a$(COLON)b.bar: a$(COLON)b.foo
all: x.bar a$(COLON)b.bar
clean: ; rm -f *.foo *.bar
% make clean
rm -f *.foo *.bar
% make
touch x.foo
cp x.foo x.bar
cp  a\:b.bar
cp: missing destination file operand after `a:b.bar'
Try `cp --help' for more information.
make: *** [a\:b.bar] Error 1

Замена $ (COLON) на литерал: дает точно такой же результат. Без обратной косой черты он делает это:

Makefile:6: *** target pattern contains no `%'.  Stop.

Ответы [ 4 ]

11 голосов
/ 13 января 2010

Я сомневаюсь, что это возможно: см. это обсуждение двоеточий в Makefiles . Таким образом, GNU make никогда не работал хорошо с именами файлов, которые содержат пробелы или двоеточия. Сопровождающий, Пол Д. Смит, говорит, что добавление поддержки для экранирования будет иметь тенденцию нарушать существующие make-файлы . Кроме того, добавление такой поддержки потребует значительных изменений в коде.

Возможно, вам удастся обойти какую-то неприятную временную организацию файлов.

Удачи!

2 голосов
/ 18 сентября 2015

Сегодня я нашел другой способ работы с переменными Makefile, определяющими имена файлов (содержащие двоеточия).

# definition
SOME_FNAME = $(NAME)__colon__$(VERSION)

# usage in target
foo:
    $(do_something) $(subst __colon__,:,$(SOME_FNAME))
2 голосов
/ 29 июня 2014

У меня сработал следующий хак, хотя, к сожалению, он использует $ (shell).

# modify file names immediately
PRE := $(shell rename : @COLON@ *)
# example variables that I need
XDLS = $(wildcard *.xdl)
YYYS = $(patsubst %.xdl,%.yyy,$(XDLS))
# restore file names later
POST = $(shell rename @COLON@ : *)

wrapper: $(YYYS)
    @# restore file names
    $(POST)

$(YYYS):
    @# show file names after $(PRE) renaming but before $(POST) renaming
    @ls

Поскольку PRE назначается с: =, связанная с ним команда оболочки запускается до оценки переменной XDLS. Ключ должен затем поставить двоеточия на место после факта, явно вызвав $ (POST).

0 голосов
/ 13 января 2010

Я не утверждаю, что это должно работать, но причина, по которой он говорит "отсутствует файл назначения", проста:

%.bar: ; cp $< $@

В этой строке указано, что нужно скопировать цель из зависимости first . Ваш a: b.bar не имеет никакой зависимости, поэтому cp не работает. что ты хотел скопировать? a: b.foo? в этом случае вам потребуется:

%.bar: %.foo ; cp $< $@
...