Make文件怎么了

时间:2019-06-26 17:48:45

标签: makefile

我正在尝试使makefile将目标文件编译到obj目录中,然后链接已编译的代码,然后将其转换为可执行文件。

CC=gcc
CFLAGS=-Iinclude.
OBJ = obj/main.o obj/print.o

%.o: %.c 
    $(CC) -c -o $@ $< $(CFLAGS)

prog: $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS)

,错误是“ prog”需要目标“ obj / main.o”没有规则。停止。 这是我在makefile教程中完成的纯复制粘贴,目的是确保它也无法正常工作。

那为什么这行不起作用

%.o: %.c 
        $(CC) -c -o $@ $< $(CFLAGS)

1 个答案:

答案 0 :(得分:1)

这种规则...

%.o: %.c 
    $(CC) -c -o $@ $< $(CFLAGS)

非常好(对于GNU make,在其他make实现中就没有那么多了)。它从相应的.o文件构建一个.c文件,其中“相应”表示具有通过将结尾的.o更改为.c而形成的名称。不过,实际上并不需要这样做,因为make具有一个内置的规则,可以执行基本上相同的操作。

消息

  
    

'prog'不需要创建目标'obj / main.o'的规则。停止。

  

obj/main.o标识为目标prog所需的先决条件,该目标不存在且没有[适用]规则。如果存在对应的来源(按照上述意义),则上面的模式规则将适用,但显然没有。

要绝对清楚:将.o中的obj/main.o替换为.c形成的相应源是obj/main.c。除非存在这样的文件,否则您提供的模式规则不适用于构建obj/main.omake程序本身并不真正了解或关心目录。它执行的命令可以执行,但是对于make本身,目标和先决条件标识符只是字符的平面序列。

我对这类事情的第一个建议是不要试图变得可爱。在与目标文件源相同的目录中构建目标文件是最简单,最常见的。假设您的C源代码位于相对于makefile的src/子目录中,则该makefile就足够了(依赖于内置的.c.o规则):

CC=gcc
CFLAGS=-Iinclude.

prog: src/main.o src/print.o
    $(CC) -o $@ $^ $(CFLAGS)

但是,如果您坚持将对象编译到单独的目录中,则您的模式规则需要反映出这一点:

CC=gcc
CFLAGS=-Iinclude.
OBJ = obj/main.o obj/print.o

obj/%.o: src/%.c 
    $(CC) -c -o $@ $< $(CFLAGS)

prog: $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS)