我正在尝试将此Makefile用于C程序。你能否跟我分享一下如何更好地理解Make实用程序?我正在尝试以下方法:
# stack/Makefile
CC := gcc
CFLAGS += -std=c99
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -g
VPATH = main src
all: bin/main.exe clean run
bin/main.exe: bin/main.o bin/stack.o
$(CC) -o $@ $^ $(LDFLAGS) $(LDLIBS)
bin/main.o: main.c
bin/stack.o: stack.c stack.h
bin/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
demo:
../bin/main.exe
clean:
rm -f bin/*.o
run:
bin/main.exe
.PHONY: all clean run
我收到了这条消息:
gcc -std=c99 -Wall -Wextra -g -c -o bin/main.o main.c
error: unable to open output file 'bin/main.o': 'No such file or directory'
1 error generated.
make: *** [bin/main.o] Error 1
答案 0 :(得分:2)
错误源于您的Makefile想要的事实
生成子目录bin
中的可执行文件和目标文件但是它
不包含确保bin
存在的规则
需要。正如@JonathanLeffler评论,你可以解决这个问题
只需自己手动创建bin
。
但通常希望Makefile本身能够确保 当它存在时,存在一个子目录或一些其他资源 需要,你可能假设模式规则
bin/%.o: %.c
会根据需要创建bin
。它赢了。
如果你的话,你的Makefile可以确保bin
的存在
像这样修改它:
在all
规则以下的某处,添加新目标:
bin:
mkdir -p $@
这是为了bin
子目录,如果它不存在。
然后更改规则:
bin/%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
为:
bin/%.o: %.c | bin
$(CC) $(CFLAGS) -c -o $@ $<
其他| bin
是order-only prequisite的示例
这意味着:如果任何目标(bin/%.o
事物)需要从之前的任何先决条件(|
之前的那些,即%.c
重新制作。
事情),然后必须先bin
。因此,只要需要在bin
中进行任何操作,bin
将首先制作。
Makefile中还有另一个更基本的缺陷。 all
取决于clean
,因此每次成功构建时都是如此
你的程序删除了目标文件。我知道你打算这个,但它完全是
挫败make
的目的,即避免重建所有(目标文件,可执行文件)的需要
相反,只需重建那些已经过时的先决条件。
所以all
不应该依赖clean
,然后只有当需要时才会重新编译目标文件
被重新编译,即比相应的源文件旧。如果你想要清理的话
目标文件,运行make clean
。
最后,您的demo
规则:
demo:
../bin/main.exe
与其他人不一致。其他人假设可执行文件所在的bin
被放在当前目录中。 demo
规则假定它位于父中
当前目录。如果您更正了demo
规则,那么它将与之相同
run
规则,所以它是多余的,但如果它不是多余的那么应该
将其添加到.PHONY
目标。
答案 1 :(得分:-1)
学习使用makefile的正确方法的最佳方法是阅读manual。此外,您可以使用Google simple tutorials。