在我的makefile配置中,所有目标文件都被编译到特定目录中。编译器会抱怨它不存在。我想创建一个可以识别任何目标文件的makefile目标,并在其他目标运行并实际编译目标文件之前创建该目录。
到目前为止,我已经尝试了模式匹配和双冒号规则。
obj:
mkdir obj
obj/%.o :: | obj
obj/example.o :: src/example.cc includes/example.hh
$(build_obj_file) # macro to do the actual job
使用此代码,仅最后一个目标运行obj/example.o
。我希望两个对象目标都可以单独运行。
当我用静态obj/example.o
替换模式匹配时,我得到了想要的结果。同样,当我使用obj/example.o : obj/%.o :: obj
之类的静态模式匹配时。
我真的不想包含obj
作为每个其他目标文件的附加依赖项,或者我不想为静态模式匹配创建所有目标文件的单独列表。两种方法都非常脆弱且容易出错。
您建议如何解决这一任务?
答案 0 :(得分:1)
您不能使用模式规则向一组目标“添加其他先决条件”。模式规则必须提供配方;如果没有,则将其视为delete the pattern rule。
由于您提供的真实Makefile很少,因此很难提出适合您的解决方案。
如果要使用仅订购的前提条件,则需要将其添加到与目标匹配的模式规则中:
obj/example.o: | obj
或者另外定义先决条件关系:
routerLink
答案 1 :(得分:1)
借助(GNU)make和易于理解的规则,或多或少地根据自动生成的规则集进行了修改:
MKDIR_P = mkdir -p
obj/%.o: src/%.cc
@$(MKDIR_P) $(@D)
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
这将为每个目标文件$(@D)
创建目标目录$@
,并且如果目标已经存在,mkdir -p
仍将以0退出,因此不会中止目标规则集。
使用(GNU)make并使其更难理解,但是规则更有效(obj
目录仅mkdir -p
被访问一次):
MKDIR_P = mkdir -p
obj:
@$(MKDIR_P) $@
obj/%.o: src/%.cc | obj
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
| obj
部分将确保不会仅由于有人在obj/
中添加或删除了文件并因此更改了obj
目录的时间戳而重建目标对象文件。 / p>
$(COMPILE.cc)
行基本上取自GNU make -p
的输出。
请注意,手动维护标头依赖性很容易出错,因此应自动生成,最好由MadScientist的comprehensively engineered robust method生成。
此外,如果您的Makefile
使用GNUmakeism,请考虑将其重命名为GNUmakefile
。
使用自动制作功能,无法编译放入特定目录中的目标文件,但是此问题的automake
标记似乎是错误的。