我有下面的Makefile,它工作得很好,但不太优雅。
bin/a.gb: obj/main.o obj/i.o obj/in.o obj/g.o obj/an.o obj/s.o obj/b.o obj/b_m.o obj/b_r.o obj/b_e.o
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -o bin/a.gb obj/main.o obj/i.o obj/in.o obj/g.o obj/an.o obj/s.o obj/b.o obj/b_m.o obj/b_r.o obj/b_e.o
obj/main.o: src/main.c include/common.h include/i.h include/in.h include/an.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/main.o src/main.c
obj/i.o: src/i.c include/common.h include/i.h include/b_m.h include/b.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/i.o src/i.c
obj/in.o: src/in.c include/common.h include/in.h include/g.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/in.o src/in.c
obj/g.o: src/g.c include/common.h include/g.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/g.o src/g.c
obj/an.o: src/an.c include/common.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/an.o src/an.c
obj/s.o: src/s.c include/s.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/s.o src/s.c
obj/b.o: src/b.c include/b.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/b.o src/b.c
obj/b_m.o: src/b_m.c include/b_m.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/b_m.o src/b_m.c
obj/b_r.o: src/b_r.c include/b_r.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/b_r.o src/b_r.c
obj/b_e.o: src/b_e.c include/b_e.h
/opt/gbdk/bin/lcc -Iinclude -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug -c -o obj/b_e.o src/b_e.c
.PHONY: clean
clean:
find bin obj -type f \( -name '*.gb' -o -name '*.o' -o -name '*.ihx' -o -name '*.cdb' -o -name '*.map' -o -name '*.noi' -o -name '*.adb' -o -name '*.lst' -o -name '*.sym' -o -name '*.asm' \) -exec rm {} +为了使它更加精简和通用,使我不必为每个新的源文件编辑它,我想出了以下内容:
IDIR=include
BDIR=bin
ODIR=obj
SDIR=src
CC=/opt/gbdk/bin/lcc
CFLAGS=-I$(IDIR) -Wa-l -Wl-m -Wl-j -Wl-y -Wl-w -Wf--debug
DEPS := $(wildcard $(IDIR)/*)
_OBJ = an.o b_e.o b_m.o b_r.o b.o g.o i.o in.o main.o s.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(SDIR)/%.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
$(BDIR)/a.gb: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/* *~ core $(IDIR)/*~ $(BDIR)/*这也很管用。到目前为止,唯一的缺点是它失去了哪个头文件与哪个对象文件的依赖关系。因此,对于原始的Makefile,如果我更改了单个头文件的内容,那么只有其源包含该头的对象文件才会被重建。但是现在,如果对任何头文件进行了编辑,则会重新构建所有的对象文件。有什么聪明的办法吗?我希望我的新的,流线型Makefile只重建必要的目标文件,如果一个头文件被改变。
我找到了this解决方案,但我很难理解如何将它合并到我的新Makefile中。例如,我不明白-include $(ODIR)/*.d行的目的,也不明白它将走向何方。
编辑:我现在意识到,我所链接的解决方案可能不适用于lcc编译器,因为它似乎没有-MMD选项(至少据我所知)。
发布于 2020-10-29 14:33:48
您可以在声明的菜谱旁边的规则中添加任意数量的额外依赖项:
$(ODIR)/%.o: $(SDIR)/%.c
$(CC) -c -o $@ $< $(CFLAGS)
$(ODIR)/an.o: $(DEPS)/dep1.h $(DEPS)/dep2.h $(DEPS)/dep3.h
$(ODIR)/b_e.o: $(DEPS)/dep1.h $(DEPS)/dep3.h(使用patsubst减少学生练习时留下的锅炉板)
GNUmake4.3中还有.EXTRA_PREREQS变量,如果前提条件不是食谱的一部分,https://lwn.net/Articles/810071/就更方便了:
新特性:.EXTRA_PREREQS变量
此变量中的单词被认为是目标的先决条件,但在展开配方时,它们不会添加到任何自动变量值中。该变量可以是全局变量(适用于所有目标),也可以是特定于目标的变量。若要检测此特性,请在.FEATURES特殊变量.中搜索“extra”。
https://stackoverflow.com/questions/64583566
复制相似问题