【问题标题】:Whats wrong with make filemake文件有什么问题
【发布时间】:2019-11-08 17:38:42
【问题描述】:

我正在尝试让 makefile 将目标文件编译到 obj 目录中,然后链接编译后的代码并将其转换为可执行文件,就是这样

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

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

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

并且错误是没有规则来制作目标'obj / main.o','prog'需要。停止。 这是我从 makefile 教程中完成的纯复制粘贴,只是为了确保它不能正常工作。

那为什么这条线不起作用

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

【问题讨论】:

  • 很明显,您声明obj/main.o 可以从obj/main.c 构建,但您没有后者。
  • @Matt 后者?后者?
  • 你没有obj/main.c,所以配方不适用。
  • @Matt .o: %.c $(CC) -c -o $@ $
  • %.c 仅替换扩展名,但 obj/filename 保留为 make 在 obj 目录中查找它。所以你应该使用 -o obj/$@ 等,而没有 obj/的 OBJ/

标签: makefile


【解决方案1】:

这样的规则......

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

非常好(使用 GNU make -- 与其他 make 实现不一样)。它从对应的.c 文件构建一个.o 文件,其中“对应”意味着具有通过将尾部.o 更改为.c 形成的名称。不过,这实际上并不是必需的,因为 make 有一个内置规则,它的作用基本相同。

消息

没有规则来制作目标“obj/main.o”,这是“prog”所需要的。停下来。

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

绝对清楚:将obj/main.o中的.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)

【讨论】:

  • 非常感谢他为我澄清了一切。很有帮助的答案
猜你喜欢
  • 2011-10-08
  • 1970-01-01
  • 2021-05-03
  • 2013-02-17
  • 2012-05-26
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多