我有一个简单的makefile,它在Linux上使用gcc
将p.c
文件编译为可执行文件。 p.c
文件取决于a.h
文件。 我的makefile文件看起来是这样的:即使我编译源代码,为什么我的makefile会重新编译?
//makefile
CC = gcc
build: p.c a.h
$(CC) -o out p.c
clean:
rm -f *.exe
rebuild: clean build
我有一个简单的makefile,它在Linux上使用gcc
将p.c
文件编译为可执行文件。 p.c
文件取决于a.h
文件。 我的makefile文件看起来是这样的:即使我编译源代码,为什么我的makefile会重新编译?
//makefile
CC = gcc
build: p.c a.h
$(CC) -o out p.c
clean:
rm -f *.exe
rebuild: clean build
Makefile中不产生它有望产生,即build
,clean
和rebuild
文件。由于这些目标不是文件,它们应该被标记为phony targets:
.PHONY: build clean rebuild
build
的目标应该是:
build : out
out : p.c a.h
$(CC) -o [email protected] p.c
什么是$ @? – batman
除非您有名为build,clean或rebuild的文件,否则不需要.PHONY。 –
@learner:[$ @](http://www.gnu.org/software/make/manual/make.html#index-g_t_0040_0040-_0040r_007b_0028automatic-variable_0029_007d-939) –
Makefile中具有的一般语法:
target : dependencies
commands to make target from dependencies
所以你的Makefile希望使用build : p.c a.h
目标创建一个名为build
的文件。 由于命令实际上并不会在每次调用时都创建该文件,因此必须重新执行命令。
(PS:Linux程序没有一个扩展名为.exe)
这部分
build: p.c a.h
$(CC) -o out p.c
说:“我用$(CC)-O了PC和结果将汇编成为一个名为“build”的文件。由于你骗了make
(这会创建out
文件),它会尝试再次构建“构建”。
还有这里的Makefile作家上了一课:始终使用[email protected]
变量(表示对象)来避免这个错误:
out: p.c a.h
$(CC) -o [email protected] p.c
有关更多建议,请参阅Paul's Rules for Makefiles。
学习者,这里是一个使用变量来存储可执行文件名称的例子。这样,你只需要在你的Makefile开始在一个地方指定:
EXECUTABLE = out
.PHONY: build clean rebuild
build: $(EXECUTABLE)
$(EXECUTABLE): p.c a.h
$(CC) -o [email protected] p.c
clean:
rm -f $(EXECUTABLE)
rebuild: clean build
通常情况下,你也必须在变量列出您.c
和.h
文件太多,这样就可以添加/从您的构建中删除文件很容易,无需搜索您的Makefile中所有使用它们的位置。
如果你想避免总是重新编译源,那么你的目标应该取决于对象文件,没有源文件:
target.exe : p.o $(CC) -o [email protected] $?; p.o: p.c a.h $(CC) -c [email protected] $?;
典型的makefile通常不必每一个明确的规则目标文件,也不会列出实现和头文件之间的显式依赖关系;大家平时看到的一样
%.o : %.c $(CC) -c $(CFLAGS) $?;
(其中$?
表示先决条件的列表为目标),或者,如果你的项目是死的简单(一个源文件),你甚至不需要是一个隐含的规则;你通常可以用
都跑不掉:目标 目标:target.o
假设你有一个名为target.c
文件,上面会使用默认的编译器和CFLAGS选项建立target
。
同样,一个典型的makefile(至少在我的经验)没有明确列出头依赖;相反,它依靠编译器选项自动生成这些依赖项列表(对于gcc,该选项为-M
)。一个例子见here。
'make'的调用是什么? –
一个小问题:当你试图删除一个'.exe'文件时,'make clean'不起作用,并且你的可执行文件没有这样的扩展名。 –
'p.c文件依赖于a.h文件'...这是不正确的。 ** out **依赖于a.h以及p.c,但你的makefile并不这么说。 –