3

我一直在阅读 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
4

4 回答 4

3

这是一个没有噱头的 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
于 2012-04-10T16:50:11.333 回答
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 个空格更改为一个选项卡。

于 2012-04-10T16:37:47.157 回答
2

当你编写一个 makefile 时,你通常从头开始,然后朝着开始的方向努力。您从最终产品开始,并给出有关如何从起点开始生产的规则。

在这种情况下,您似乎有两个最终产品:AC.

all: A C

如果您没有在命令行上指定目标,make 将构建它在 makefile 中看到的第一个目标。因此,您希望它作为文件中的第一个目标,其他目标在其下方。如果你把它想象成一棵树,这就是树的根,下面的每一项都是那棵树的一个分支。

也可以定义包含在此根之下的次要目标。例如,许多(大多数?)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 中执行的所有操作。当您处理大量文件时,有很多快捷方式非常方便,但当您只有三个源文件时,它们就不是很有用了。

于 2012-04-10T16:54:07.367 回答
1

假设您使用GNU make,您可以主要依赖内置规则:

CFLAGS = -std=c89
LDFLAGS = -std=c89
A: A.o B.o
C: C.o B.o

这将执行您列出的命令。但是,它不关心清洁或类似的东西。不过,您不一定需要 -make程序会注意到何时需要重新编译/重新链接并自动执行此操作。

于 2012-04-10T16:37:16.093 回答