2017-05-04 34 views
1

我的项目包含.c和.s(asm)文件。我用'gcc'编译这两种类型,并将输出.o文件放在单独的目录'./bin'中。要做到这一点我使用单生成文件的规则是这样使用通配符搜索先决条件时,Makefile的'vpath'不起作用

bin/%.o: %.[cs] 
     $(CC) $(CFLAGS) -o [email protected] -c $< 

(据我了解,在这样的环境中使用方括号通配符是有点不合常规,但它的工作,它看起来整洁,所以.. 。)

有一天,我决定把我的一些.c文件移动到专用目录“./common”,所以我在生成文件的开头添加

vpath %.c common 

。现在,每当我尝试“制作”时,它就会停止并在我移动的文件上抛出错误。例如,对于'common/foo.c'我得到

"*** No rule to make target bin/foo.o, needed by..." 

好像我还没有指定'vpath'。但是,当我修改的规则只编译.c文件

bin/%.o: %.c 
     ... ... 

神奇它再次开始正常运行,并检查“./common”的来源。

看起来像'vpath'机制和通配符不能一起工作,但我仍然是'make'的新手,并且渴望知道这种行为的确切原因。任何想法的人?提前致谢。

(测试用make-3.81,使-4.1)。


UPD:把所有的文件和 'bin' 目录驻留在同一水平上,像这样

|-bin/ 
|-foo.c 
|-bar.s 
|-baz.c 
|-Makefile 

这里的MWE

ROOTS = foo.o bar.o 
OBJS = baz.o 
SS  = $(addprefix bin/,$(ROOTS) $(OBJS)) 

all: ff.out 

ff.out: $(SS) 
    ld -o [email protected] $^ 

bin/%.o: %.[cs] 
    gcc -o [email protected] -c $< 

现在,如果我动,说“foo.c的”以独立的目录,并指定“VPATH”,停止建设“无规则,使目标bin/foo.o,由ff.out需要“。

+0

发布原始生成文件的[mcve],为方括号指定没有特殊含义,因此它必须使用其内置规则,但是某些内容并不会增加您对行为的描述。 – user657267

+0

@ user657267那么,'make'spec/4.3会告诉别人:方括号会以类似bash的方式作为通配符处理。我已经将MWE添加到了我的问题中。 –

+0

对不起,你是对的,我不敢相信我不知道。 – user657267

回答

0

我建议仔细阅读How Not to Use VPATH,因为您似乎在第三步通过在一些地方使用OBJDIR而不是其他地方。

要显示,使用静态模式规则不会让您不必每个源目录至少需要一个规则,或者每个源目录至少需要一个调用。所以,简单的答案是添加新规则新common/目录是一样的另一种:

bin/%.o: common/%.[cs] 
    gcc -o [email protected] -c $< 

有很多更全面的,而是复杂的,答案,看到他们中的一些连打文章。

对于简单的项目,没有理由不通过添加额外的规则来跟踪主Makefile中的目录。此外,还有一个合理的情况是没有该bin/目录并将其分割为.o.out位置。经销商和其他人希望能够控制从哪里创建文件的目录。

我抛出了一个git repo with branches根据你的减少的例子,可能会澄清的事情。

+0

感谢您的回答!事实上,我读过你之前建议的文章,但它对我没有多大帮助,而你的第二个选择对我来说并不合适。现在我开始认为我必须拒绝使用'vpath'并直接指定所有源路径的想法。 但是真正让我感到困惑的是,我找不到任何Makefiles的例子,其中通配符如'?'或'[...]'被使用。奇怪。 –

+0

您应该直接指定srcdirs,我已经更新了我的答案以使其更清晰。您可能看不到通配符,因为明确列出文件是首选,或者是其他类型的制作工具。 –