我一直在阅读Makefiles,但我仍然对如何将以下命令编写到Makefile中一无所知。
gcc -std=c89 A.c -c
gcc -std=c89 B.c -c
gcc -std=c89 C.c -c
gcc -std=c89 A.o B.o -o A
gcc -std=c89 C.o B.o -o C
A和C依赖于B,但是是单独的程序。
这就是我提出的不起作用的地方:
CC = gcc -std=c89
FILES = A.c B.c C.c
OUT = out
build: $(FILES)
$(CC) -o $(OUT) $(Files)
clean:
rm -f *.o core
答案 0 :(得分:3)
这是一个没有gimmicks的makefile,而gcc和rm之前必须是'tab'字符,它们不是空格。
all: A C
A.o: A.c
gcc -std=c89 -c A.c
B.o: B.c
gcc -std=c89 -c B.c
C.o: C.c
gcc -std=c89 -c C.c
A: A.o B.o
gcc -std=c89 -o A A.o B.o
C: C.o B.o
gcc -std=c89 -o C C.o B.o
clean:
rm A C a.o b.o c.o core
答案 1 :(得分:2)
试试这个:
X1 = A
O1 = A.o B.o
X2 = B
O2 = C.o B.o
DBGFLAGS = -g -O0
CFLAGS = -W -Wall $(DBGFLAGS)
all: $(X1) $(X2)
$(X1): $(O1)
$(CC) $(LDFLAGS) -o $@ $(O1) $(LIBS)
$(X2): $(O2)
$(CC) $(LDFLAGS) -o $@ $(O2) $(LIBS)
.PHONY: clean
clean:
rm -f $(X1) $(O1) $(X2) $(O2) *~
如果复制粘贴不执行,则将8个空格更改为一个选项卡。
答案 2 :(得分:2)
当你编写一个makefile时,你通常会从最后开始,然后按照你的方式开始。您从最终产品开始,并提供有关如何从起点产生该规则的规则。
在这种情况下,您似乎有两个最终产品:A
和C
。
all: A C
如果未在命令行上指定目标,make将构建它在makefile中看到的第一个目标。因此,您希望将此作为文件中的第一个目标,其他目标位于其下方。如果您将其视为树,则这是树的根,下面的每个项都是该树的一个分支。
还可以定义在此根下面包含 not 的辅助目标。例如,许多(大多数?)makefile包含一个名为clean
的目标,它删除将在构建过程中创建的所有中间文件。当/用户调用make clean
时,这将仅,而不是仅仅作为命令发出make
的一部分。
无论如何,那么你告诉它每个人依赖什么,以及如何根据它所依赖的东西来创造它:
A: A.o B.o
$(CC) -o A A.o B.o
C: B.o C.o
$(CC) -o B B.o C.o
然后(如果有必要 - 它不在这里)你会告诉它每个.o
文件如何依赖于.c
文件。然而,Gmake(就像现有的make
工具一样)有内置规则来告诉它如何编译C或C ++文件以生成匹配的目标文件。这些将与您的makefile包含类似的内容一样:
CC = gcc
.c.o:
$(CC) $(CFLAGS) -c $*.c
将CFLAGS的当前值作为标志传递给编译器,因此您希望将其设置为您需要的标志 - 在您的情况下:
CFLAGS = -std=c89
您通常希望将其放在makefile的顶部,通常在任何目标之前。
我应该补充说,这甚至没有涵盖你在makefile中可以做的所有事情。当你处理大量文件时,有很多很多的快捷方式非常方便,但是当你只有三个源文件时它们并没有用。
答案 3 :(得分:1)
假设您使用GNU make,您通常可以依赖内置规则:
CFLAGS = -std=c89
LDFLAGS = -std=c89
A: A.o B.o
C: C.o B.o
这将执行您列出的命令。但是,它并不关心清洁或类似它的东西。但是你并不一定需要 - make
程序会注意到什么东西需要重新编译/重新链接并自动完成。