如果不存在,如何创建一个创建目录的目标?
How to create a target that creates a directory if it doesn't exist?
在我的 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
的最后一个目标 运行s。我本来希望两个对象目标分别为 运行。
当我用静态 obj/example.o
替换模式匹配时,我得到了想要的结果。此外,当我使用像 obj/example.o : obj/%.o :: obj
.
这样的静态模式匹配时
我真的不想包含 obj
作为每个其他目标文件的附加依赖项,也不想为静态模式匹配创建所有目标文件的单独列表。无论哪种方式都非常脆弱且容易出错。
你有什么建议来解决这样的任务?
您不能使用模式规则 "add extra prerequisites" 一组目标。模式规则必须提供配方;如果他们不这样做,那么他们将被视为 delete the pattern rule.
因为您提供的真实 makefile 太少,所以很难提出适合您的解决方案。
如果您想使用 order-only 先决条件,您需要将它们添加到与您的目标匹配的模式规则中:
obj/%.o : src/%.cc | obj
$(build_obj_file)
否则单独定义前提关系:
obj/example.o: | obj
使用 (GNU) make 和易于理解的规则,或多或少改编自 automake 生成的规则集:
MKDIR_P = mkdir -p
obj/%.o: src/%.cc
@$(MKDIR_P) $(@D)
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
这将为每个 object 文件 $@
创建目标目录 $(@D)
,如果目标已经存在,mkdir -p
仍将以 0 退出,因此不会中止目标规则集。
使用 (GNU) make 并稍微难以理解,但规则更有效(obj
目录仅 mkdir -p
ed 一次):
MKDIR_P = mkdir -p
obj:
@$(MKDIR_P) $@
obj/%.o: src/%.cc | obj
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
| obj
部分将确保目标 object 文件不会仅仅因为有人在 obj/
中添加或删除了文件并因此更改了 [=15] 而重建=] 目录的时间戳。
$(COMPILE.cc)
行基本上取自 GNU make -p
的输出。
请注意,手动维护 header 依赖项很容易出错,因此应该自动生成,最好由 MadScientist's comprehensively engineered robust method。
此外,如果您的 Makefile
使用 GNUmakeism,请考虑重命名它 GNUmakefile
。
使用 automake,您无法将 object 文件放入特定目录进行编译,但是此问题的 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
的最后一个目标 运行s。我本来希望两个对象目标分别为 运行。
当我用静态 obj/example.o
替换模式匹配时,我得到了想要的结果。此外,当我使用像 obj/example.o : obj/%.o :: obj
.
我真的不想包含 obj
作为每个其他目标文件的附加依赖项,也不想为静态模式匹配创建所有目标文件的单独列表。无论哪种方式都非常脆弱且容易出错。
你有什么建议来解决这样的任务?
您不能使用模式规则 "add extra prerequisites" 一组目标。模式规则必须提供配方;如果他们不这样做,那么他们将被视为 delete the pattern rule.
因为您提供的真实 makefile 太少,所以很难提出适合您的解决方案。
如果您想使用 order-only 先决条件,您需要将它们添加到与您的目标匹配的模式规则中:
obj/%.o : src/%.cc | obj
$(build_obj_file)
否则单独定义前提关系:
obj/example.o: | obj
使用 (GNU) make 和易于理解的规则,或多或少改编自 automake 生成的规则集:
MKDIR_P = mkdir -p
obj/%.o: src/%.cc
@$(MKDIR_P) $(@D)
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
这将为每个 object 文件 $@
创建目标目录 $(@D)
,如果目标已经存在,mkdir -p
仍将以 0 退出,因此不会中止目标规则集。
使用 (GNU) make 并稍微难以理解,但规则更有效(obj
目录仅 mkdir -p
ed 一次):
MKDIR_P = mkdir -p
obj:
@$(MKDIR_P) $@
obj/%.o: src/%.cc | obj
$(COMPILE.cc) -o $@ -c $<
obj/example.o : includes/example.hh
| obj
部分将确保目标 object 文件不会仅仅因为有人在 obj/
中添加或删除了文件并因此更改了 [=15] 而重建=] 目录的时间戳。
$(COMPILE.cc)
行基本上取自 GNU make -p
的输出。
请注意,手动维护 header 依赖项很容易出错,因此应该自动生成,最好由 MadScientist's comprehensively engineered robust method。
此外,如果您的 Makefile
使用 GNUmakeism,请考虑重命名它 GNUmakefile
。
使用 automake,您无法将 object 文件放入特定目录进行编译,但是此问题的 automake
标记似乎是一个错误。