如果目录不存在,如何创建目标创建目录?

时间:2019-05-29 18:47:57

标签: makefile gnu-make automake

在我的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作为每个其他目标文件的附加依赖项,或者我不想为静态模式匹配创建所有目标文件的单独列表。两种方法都非常脆弱且容易出错。

您建议如何解决这一任务?

2 个答案:

答案 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的输出。

请注意,手动维护标头依赖性很容易出错,因此应自动生成,最好由MadScientistcomprehensively engineered robust method生成。

此外,如果您的Makefile使用GNUmakeism,请考虑将其重命名为GNUmakefile

使用自动制作功能,无法编译放入特定目录中的目标文件,但是此问题的automake标记似乎是错误的。