有没有办法让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.
答案 0 :(得分:11)
我怀疑这是可能的:见this discussion about colons in Makefiles。总之,GNU make从未与包含空格或冒号的文件名一起使用。维护者Paul D. Smith说,增加对转义的支持往往会break existing makefiles。此外,添加此类支持需要对代码进行重大更改。
您可能可以使用某种令人讨厌的临时文件安排。
祝你好运!答案 1 :(得分:3)
这里的答案似乎都太复杂了,无法提供帮助。我终于找到了解决方法here:
colon := :
$(colon) := :
,然后将文件名中的宏用作:
filename$(:)
经评估成功转换为“文件名:”。
答案 2 :(得分:2)
以下黑客为我工作,但不幸的是它依赖于$(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变量之前运行其关联的shell命令。关键是通过显式调用$(POST)来将冒号放回原位。
答案 3 :(得分:2)
今天我在处理定义文件名(包含冒号)的Makefile变量时还有另一种方法。
function my_scripts() {
wp_enqueue_style( 'google-styles', get_template_directory_uri() . '/css/mdb.css');
wp_enqueue_style( 'bootstrap-styles', get_template_directory_uri() . '/css/goldbootstrap.css', array(), '3.3.4', 'all' );
wp_enqueue_style( 'font-awesome', get_template_directory_uri() . '/css/font-awesome.min.css', array(), '4.3.0', 'all' );
wp_enqueue_style( 'my-style', get_stylesheet_uri() );
wp_enqueue_script( 'bootstrap-js', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), '3.3.4' );
wp_enqueue_script('mdb-js', get_template_directory_uri() . '/js/mdb.js' );
if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
wp_enqueue_script( 'comment-reply' );
}
}
add_action( 'wp_enqueue_scripts', 'my_scripts' );
答案 4 :(得分:0)
我不认为这应该有用,但它说“丢失目标文件”的原因很简单:
%.bar: ; cp $< $@
该行表示从第一个依赖项中复制目标。你的a:b.bar没有任何依赖关系,所以cp失败了。你想要它复制什么? a:b.foo?在这种情况下,你需要:
%.bar: %.foo ; cp $< $@
答案 5 :(得分:0)
我无法得到@navjotk发布的答案,所以我只是作弊而已;
FILENAME:=foo:bar
foo_bar:
touch $(FILENAME)
run:
if [ ! -e "$(FILENAME)" ]; then $(MAKE) foo_bar; fi
输出:
$ make run
if [ ! -e "foo:bar" ]; then /Library/Developer/CommandLineTools/usr/bin/make foo_bar; fi
touch foo:bar
$ ls
Makefile foo:bar
对我来说足够近了。