我正在编写一个生成文件来处理构建单元 ONE 和 TWO -> 构建单元 LIB 的依赖关系。
“构建单元”是指包含目录 src、lib、include 和 bin 的目录,以及用于在 src 中编译源代码的 makefile。库放在“lib”中,库头文件放在“include”中。编译后的二进制文件放在“bin”中。构建单元接受“make”、“make all”、“make lint”和“make clean”。
当对 LIB 中的头文件进行更改时,此 makefile 旨在检测它并在编译之前重新编译 + 安装(将 .a+.h 文件复制到 ONE 和 TWO)新版本的 LIB。
.PHONY: ONE TWO CLEAN LINT
ALL: ONE TWO
%.a %.h:
@echo ---------- Compiling LIB ----------
@cd LIB && gmake.exe LIB
LIB_HEADERS := $(wildcard LIB/src/*.h)
ONE: ONE/lib/libLIB.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
@echo ---------- Compiling $@ ----------
@cd $@ && gmake.exe
TWO: TWO/lib/libLIB.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
@echo ---------- Compiling $@ ----------
@cd $@ && gmake.exe
CLEAN LINT:
@cd ONE && gmake.exe $@
@cd TWO && gmake.exe $@
@cd LIB && gmake.exe $@
(假设 LIB 的 makefile 处理复制到 ONE 和 TWO 中)
- 当我对 LIB/src 中的一个头文件进行更改时,为什么 make 不运行规则“%.a %.h:”?
如何将 ONE 和 TWO 概括为一条规则?我想这样做(但目标不能在依赖项中使用,至少这样):
ONE TWO: $@/lib/libLIB.a $(subst LIB/src/,$@/include/,$(LIB_HEADERS)) @echo ---------- Compiling $@ ---------- @cd $@ && gmake.exe
更新:
我通过退后一步,绘制有向无环图并考虑单个文件而不是某种类型的所有文件来找到解决方案。
为了完整起见,这是(不是很优雅的)解决方案:
.PHONY: ONE TWO CLEAN LINT
ALL: ONE TWO
LIB_HEADERS := $(sort $(subst name.h,,$(wildcard LIB/src/*.h)))
# ------------------------------------------------------------
ONE/include/%.h: LIB/src/%.h
@echo Copying $< to $@
@mkdir ONE\\include 2> NUL || :)
@copy $(subst /,\,$<) ONE\\include\\ 1> NUL
TWO/include/%.h: LIB/src/%.h
@echo Copying $< to $@
@mkdir TWO\\include 2> NUL || :)
@copy $(subst /,\,$<) TWO\\include\\ 1> NUL
# ------------------------------------------------------------
ONE/lib/liblib.a: LIB/bin/liblib.a
@echo Copying $< to $@
@mkdir ONE\\lib 2> NUL || :)
@copy $(subst /,\,$<) ONE\\lib\\ 1> NUL
TWO/lib/liblib.a: LIB/bin/liblib.a
@echo Copying $< to $@
@mkdir TWO\\lib 2> NUL || :)
# Windows-equivalent of touch (discarding any output to stdout):
@copy $(subst /,\,$<) TWO\\lib\\ 1> NUL
# ------------------------------------------------------------
LIB/bin/liblib.a: $(LIB_HEADERS) $(wildcard LIB/src/*.cpp)
@echo ---------- Looking for changes to liblib ----------
@cd LIB && gmake.exe LIB
@copy /b $(subst /,\,$@) +,, 1> NUL || :)
# ------------------------------------------------------------
ONE: ONE/lib/liblib.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
@echo ---------- Compiling ONE ----------
@cd ONE && gmake.exe
TWO: TWO/lib/liblib.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
@echo ---------- Compiling TWO ----------
@cd TWO && gmake.exe
# ------------------------------------------------------------
CLEAN LINT:
@cd ONE && gmake.exe $@
@cd TWO && gmake.exe $@
@cd LIB && gmake.exe $@
我非常欢迎关于如何进一步概括 ONE 和 TWO 的提示。