【问题标题】:How do you construct a C makefile so that it compiles the source.c file?你如何构造一个 C makefile 以便它编译 source.c 文件?
【发布时间】:2021-04-23 01:01:36
【问题描述】:

我有三个文件。 main.c、graph.c 和 graph.h。 我知道代码可以在没有 makefile 的情况下工作,因为我在 onlinegbd 编译器上对其进行了测试。一切顺利。

当我尝试在终端中运行我的 makefile 时,我收到以下错误:

undefined reference to "function"

“函数”是我在 main 中调用的每个函数,它位于 graph.c 中。

所以这让我认为我没有在我的 makefile 中编译 graph.c。

编辑 我已经确认它是makefile。我使用以下方法编译它:

gcc -o xGraph main.c graph.c

它运行没有问题。 这是生成文件:

CC = gcc

VPATH = SRC INCLUDE

TARGET = XGraph

CFLAGS = -g -Wall

all: $(TARGET)

$(TARGET): main.o graph.o
    $(CC) main.o graph.o -o $(TARGET)

main.o: main.c graph.h
    $(CC) $(CFLAGS) main.c

graph.o: graph.c graph.h
    $(CC) $(CFLAGS) graph.c

clean:
    rm *.o *~ $(TARGET)

【问题讨论】:

  • 你用什么代码得到那个错误?
  • 是的,我一点也不精通makefile。那是根据我拥有的三年前的 c++ makefile 编辑的。
  • main.ograph.o 的配方已损坏。只需删除它们并让make 使用其默认规则。 (这将忽略 graph.h 依赖项,但稍后会担心。)
  • 很高兴你得到了答案。以后在问这样的问题时,最好在问题中包含您输入的命令和获得的完整输出;特别是生成的命令和您在生成时看到的错误消息(未提取并单独显示)。如果有太多类似的错误,则只显示 FIRST 4 或 5 个错误行(不是最后一个错误!第一个错误几乎总是更有趣的错误)。适当地剪切、粘贴和格式化。干杯!

标签: c makefile


【解决方案1】:

编译 C 代码时,第一阶段是生成 .o 文件。将 -c 标志传递给 gcc 以执行此操作。


main.o: main.c graph.h
    $(CC) $(CFLAGS) -c main.c

graph.o: graph.c graph.h
    $(CC) $(CFLAGS) -c graph.c

【讨论】:

  • 感谢您的解决。我是空的。
  • 但是make 已经有编译 C 源文件的隐含规则。这两条规则是多余的。
  • 是的;但是,使用隐式规则并不是很有教育意义。大多数简单的程序都可以完全使用自动先决条件和隐式规则进行编译。
【解决方案2】:

在 C 中,有两种类型的未定义引用错误。第一个导致implicit declaration of function 错误,而第二个导致您的undefined reference。第一个说gcc 找不到您的函数的定义。但第二个意味着gcc 认为您的代码没有任何问题,然后尝试使用ld 链接目标文件,that 使代码崩溃。确保您的源文件包含在编译中并且它们具有声明,而不仅仅是定义。此外,在这里提供代码的最小可重现示例可能会有所帮助。

【讨论】:

  • 好的,我现在就开始。我可能需要一些时间。
【解决方案3】:

您最简单的Makefile 可以是:

CFLAGS = -g -Wall

xGraph_objs = main.o graph.o

xGraph: $(xGraph_objs)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(xGraph_objs)

main.o graph.o: graph.h

因为有隐式规则(使用$CFLAGS变量,所以编译时不需要添加规则,只需要指定对象和头文件之间的额外依赖关系)

我经常用于小型项目的结构与您的非常相似:

targets = xGraph
toclean = $(targets)

xGraph_deps = # no dependencies to link the executable. (E.g. creating a library needed to link this)
xGraph_objs = main.o graph.o
xGraph_libs = # no libs to specify at link time. (E.g. -lm -lX11)
xGraph_ldfl = # no flags for the linker. (E.g.  -L/usr/local/lib)
toclean += $(xGraph_objs)

all: $(targets)
clean:
    $(RM) $(toclean)

xGraph: $(xGraph_deps) $(xGraph_objs)
    $(CC) $(LDFLAGS) $(xGraph_ldfl) $(xGraph_objs) -o $@ $(xGraph_libs)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2012-01-16
    • 1970-01-01
    • 2011-03-22
    • 2015-10-08
    • 1970-01-01
    相关资源
    最近更新 更多