Makefile 如何确保“make”在删除文件后重建所有对象
考虑以下Makefile 如何确保“make”在删除文件后重建所有对象,makefile,Makefile,考虑以下Makefile框架: HEADERS := $(shell find . -name "*.h" | sort) SOURCES := $(shell find . -name "*.c" | sort) OBJECTS := $(patsubst %.c, %.o, $(SOURCES)) executable: $(OBJECTS) $(CC) $(CFLAGS) -o $@ $(OBJECTS) %.o: %.c rm -f $@ $(CC) $(CF
Makefile
框架:
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
$(OBJECTS): Makefile $(HEADERS)
HEADERS:=$(shell find.-name“*.h”| sort)
来源:=$(shell find.-name“*.c”| sort)
对象:=$(patsubst%.c、%.o、$(源))
可执行文件:$(对象)
$(CC)$(CFLAGS)-o$@$(对象)
%.o:%.c
rm-f$@
$(CC)$(CFLAGS)-c-o$@$<|${rm-f$@;退出1;}
$(对象):Makefile$(标题)
如果修改了以下任何文件,这些规则可确保重新编译对象
和可执行文件
:
- 声明文件(*.h)
- 实现文件(*.c)
本身Makefile
cp-a
或mv
添加的)。没有涉及的情况是删除文件
删除时重新编译很有用,因为它捕获剩余源代码中的剩余部分,并从可执行文件中删除多余的数据
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
genlist:
find . -name \*.c -or -name \*.h > listfile
$(OBJECTS): Makefile $(HEADERS) listfile
.PHONY: genlist
从项目中删除源代码文件后,确保make
命令重建所有对象的简洁高效的方法是什么
答案可以通过$(shell…
使用任何常见的Linux命令。您可以创建一个列表文件(namelistfile
),其中包含头和C
源的列表。如果从源代码树中删除文件,则需要重新创建此listfile
。listfile
应该是Makefile
中的依赖项
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
genlist:
find . -name \*.c -or -name \*.h > listfile
$(OBJECTS): Makefile $(HEADERS) listfile
.PHONY: genlist
HEADERS:=$(shell find.-name“*.h”| sort)
来源:=$(shell find.-name“*.c”| sort)
对象:=$(patsubst%.c、%.o、$(源))
可执行文件:$(对象)
$(CC)$(CFLAGS)-o$@$(对象)
%.o:%.c
rm-f$@
$(CC)$(CFLAGS)-c-o$@$<|${rm-f$@;退出1;}
基因列表:
找到-name\*.c-或-name\*.h>列表文件
$(对象):Makefile$(标题)listfile
.伪造:基因列表
删除后,应运行生成genlist
当然,您可以扩展这个想法:您将创建一个列表文件,每个make
都将生成一个临时列表文件(例如使用mktemp
),并与“官方”列表文件进行比较。如果它们不同,则将覆盖“正式”列表文件,并且在删除后不必运行make genlist
。您可以创建一个列表文件(名称listfile
),其中包含标题列表和C
源。如果从源代码树中删除文件,则需要重新创建此listfile
。listfile
应该是Makefile
中的依赖项
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
genlist:
find . -name \*.c -or -name \*.h > listfile
$(OBJECTS): Makefile $(HEADERS) listfile
.PHONY: genlist
HEADERS:=$(shell find.-name“*.h”| sort)
来源:=$(shell find.-name“*.c”| sort)
对象:=$(patsubst%.c、%.o、$(源))
可执行文件:$(对象)
$(CC)$(CFLAGS)-o$@$(对象)
%.o:%.c
rm-f$@
$(CC)$(CFLAGS)-c-o$@$<|${rm-f$@;退出1;}
基因列表:
找到-name\*.c-或-name\*.h>列表文件
$(对象):Makefile$(标题)listfile
.伪造:基因列表
删除后,应运行生成genlist
当然,您可以扩展这个想法:您将创建一个列表文件,每个make
都将生成一个临时列表文件(例如使用mktemp
),并与“官方”列表文件进行比较。如果它们不同,则将覆盖“官方”列表文件,并且在删除后不必运行“生成genlist”。处理此问题的一种方法是使用现代自动生成的依赖项方法,例如。这些方法具有正确处理已删除文件的内置属性
如果您不想这样做,那么您需要做的就是类似于@uzsolt所建议的事情,但是如果您想避免在make发现文件丢失之前显式运行make genlist
,那么您必须玩一个小把戏:
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
$(OBJECTS): Makefile $(HEADERS) sourcelist
sourcelist: FORCE
@for f in $(SOURCES) $(HEADERS); do echo "$$f"; done > $@.tmp
@[ `comm -23 $@ $@.tmp | wc -l` -eq 0 ] || mv $@.tmp $@
FORCE:
HEADERS:=$(shell find.-name“*.h”| sort)
来源:=$(shell find.-name“*.c”| sort)
对象:=$(patsubst%.c、%.o、$(源))
可执行文件:$(对象)
$(CC)$(CFLAGS)-o$@$(对象)
%.o:%.c
rm-f$@
$(CC)$(CFLAGS)-c-o$@$<|${rm-f$@;退出1;}
$(对象):Makefile$(标题)源列表
来源列表:原力
@对于f,单位为$(来源)$(标题);做回显“$$f”;完成>$@.tmp
@[comm-23$@$@.tmp|wc-l`-eq 0]| mv$@.tmp$@
部队:
这里的想法是将旧列表与新列表进行比较,并且仅当旧列表包含新列表不包含的内容时才修改列表。这确保了除非删除某些内容,sourcelist
的时间戳不会更改,因此不会强制对象文件过期。处理此问题的一种方法是使用现代自动生成的依赖项方法,例如。这些方法具有正确处理已删除文件的内置属性
如果您不想这样做,那么您需要做的就是类似于@uzsolt所建议的事情,但是如果您想避免在make发现文件丢失之前显式运行make genlist
,那么您必须玩一个小把戏:
HEADERS := $(shell find . -name "*.h" | sort)
SOURCES := $(shell find . -name "*.c" | sort)
OBJECTS := $(patsubst %.c, %.o, $(SOURCES))
executable: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.c
rm -f $@
$(CC) $(CFLAGS) -c -o $@ $< || { rm -f $@; exit 1; }
$(OBJECTS): Makefile $(HEADERS) sourcelist
sourcelist: FORCE
@for f in $(SOURCES) $(HEADERS); do echo "$$f"; done > $@.tmp
@[ `comm -23 $@ $@.tmp | wc -l` -eq 0 ] || mv $@.tmp $@
FORCE:
HEADERS:=$(shell find.-name“*.h”| sort)
来源:=$(shell find.-name“*.c”| sort)
对象:=$(patsubst%.c、%.o、$(源))
可执行文件:$(对象)
$(CC)$(CFLAGS)-o$@$(对象)
%.o:%.c
rm-f$@
$(CC)$(CFLAGS)-c-o$@$<|${rm-f$@;退出1;}
$(对象):Makefile$(标题)源列表
来源列表:原力
@对于f,单位为$(来源)$(标题);做回显“$$f”;完成>$@.tmp
@[comm-23$@$@.tmp|wc-l`-eq 0]| mv$@.tmp$@
部队:
这里的想法是将旧列表与新列表进行比较,并且仅当旧列表包含新列表不包含的内容时才修改列表。这就确保了,除非某件事被删除