2010-01-12 382 views
12

有沒有辦法讓GNU make與包含冒號的文件名一起正確工作?在Makefile中轉義文件名冒號

我遇到的具體問題恰好涉及模式規則。下面是一個不依賴於剪切和粘貼製表符的簡化版本:

% 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 $< [email protected] 
x.bar: x.foo 
%.foo: ; touch [email protected] 
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 

用文字代替$(冒號):產生完全相同的結果。如果沒有反斜槓,它這樣做:

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

回答

2

下面的黑客爲我工作,雖然它不幸依賴於$(shell)。

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

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

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

由於PRE分配有:=,因此在計算XDLS變量之前運行其關聯的shell命令。關鍵是要通過顯式調用$(POST)將冒號放回原處。

+0

相當不錯的破解!我用$(shell)很好,我的問題是GNU make特有的。我想這應該是另一個答案中提到的「討厭的臨時文件安排」的例子。我確實擔心在「ls」是佔位符的情況下失敗並且$(POST)因此無法運行的情況下會發生什麼情況。我的意思是我猜這可能大多是好的,因爲$(PRE)是冪等的,對嗎?如果您的文件名中可能包含真正的@ COLON @ s,那麼您只需使用更長,更荒謬的佔位符,可能會嵌入一長串隨機字符串.... – zaphod 2014-07-11 22:37:40

0

我不positivie這應該工作,但它說:「缺少目標文件」的原因很簡單:

%.bar: ; cp $< [email protected] 

該行表示,以複製目標從開始依賴。您的a:b.bar沒有任何依賴關係,所以cp失敗。你想拷貝什麼? a:b.foo?在這種情況下,你將需要:

%.bar: %.foo ; cp $< [email protected] 
+0

一般規則沒有依賴關係,但我爲後續規則中的兩個特定情況提供了第一個依賴項。是的,我不知道你也可以這樣做,但事實證明你可以。你會注意到它能夠弄清楚如何從x.foo創建x.bar就好了。 – zaphod 2010-01-12 22:29:01

9

我懷疑這是可能的:見this discussion about colons in Makefiles。總之,GNU make對於包含空格或冒號的文件名從來沒有很好的處理過。維護者Paul D. Smith說,增加對轉義的支持將傾向於break existing makefiles。此外,增加這種支持需要對代碼進行重大更改。

你可能能夠解決某種令人討厭的臨時文件安排。

祝你好運!

+0

很好找。當我說我沒有積極的時候,這就是我害怕的事情,它應該工作! – Bahbar 2010-01-12 21:40:30

+0

哇!那沒什麼好玩的。 Make是我的工作流程不可或缺我很沮喪,這是不可能的 – AndyL 2013-04-16 14:17:44

1

今天我發現了另一種處理Makefile變量定義文件名(包含冒號)的方法。

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

# usage in target 
foo: 
    $(do_something) $(subst __colon__,:,$(SOME_FNAME))