【问题标题】:Compile time error while running multiple c files运行多个c文件时编译时错误
【发布时间】:2020-06-28 11:55:22
【问题描述】:

#已编辑

我现在在 add.h 和 add.c 这两个简单的文件上进行了测试。

我制作了一个 Makefile 来编译我的程序。这是我的makefile。

# Make file for running the project
CC=gcc
CFLAGS= -Wall -g
LDFLAGS = -include
OBJFILES = add.o
LIB = add.h
TARGET = add

all: ${TARGET}

%.o: %.c
    ${CC} ${CFLAGS} -c -o $@ $<

${TARGET}: ${OBJFILES}
    ${CC} ${CFLAGS} -o ${TARGET} ${OBJFILES}

clean:
    rm -f $(OBJFILES) $(TARGET) *~

当我跑步时

make add

我收到以下错误:

gcc -Wall -g -c -o add.o add.c
gcc -Wall -g -o add add.o
Undefined symbols for architecture x86_64:
  "_b", referenced from:
      _main in add.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [add] Error 1

这是我的代码的 sn-ps

add.c

#include <stdio.h>
#include <stdlib.h>
#include "add.h"

int main(void) {
    int a = 10, b=20;
    add(a, b);
    return 0;
}

add.h

#ifndef __ADD_H_
#define __ADD_H_

extern int a,b;

int add(a,b)
{
    return a+b;
}

#endif // __ADD_H_

【问题讨论】:

  • 使用remake 调试您的Makefile,但请阅读GNU make 的文档并尝试make -p;另请阅读GCC 的文档
  • 1) 在测试之前不要写这么多代码。 2) 你给事物命名时是否带有前导下划线(例如_com_task)? 不要。 3) 阅读minimal complete examples上的页面。
  • @BasileStarynkevitch 将查看您提供的来源。谢谢
  • 另请阅读Modern Cn1570,C11 标准。见this C reference,学会使用GDB;在你的情况下没有理由有 3 个头文件。在github 上寻找一些程序的灵感
  • @Beta 实际上是的,我已经为我的所有函数命名,开始或包括 _com_tasks。你认为这可能是问题吗?

标签: c gcc makefile


【解决方案1】:

您缺少实际构建目标文件的规则。现在,一旦它们已经存在,您就只有一个可以将它们全部链接在一起。尝试添加:

%.o: %.c
    ${CC} ${CFLAGS} -c -o $@ $<

这告诉 make 如何从源文件构建目标文件。

【讨论】:

  • 我已经尝试添加和编译它,但它仍然显示相同的错误。
  • 您似乎在多个函数中使用_com_task,但您从未在任何地方定义它。是否有任何源文件中的实现?
  • com_task 是一个结构变量,我只在 stack.h 中使用过它,而在其他任何地方都没有。我需要在这里提供我的全部源代码吗?
  • 我已经在最简单的版本上编译了程序,正如您在编辑后的帖子中看到的那样。
【解决方案2】:

您误用了extern 关键字,失去了对变量的跟踪并使您的代码过于复杂。

让我们尝试一些非常简单的方法:

int main(void) {
  int a = 10; b=20;

  return 0;
}

这失败了。编译器抱怨声明 b=20;,因为它从未听说过 b。使这成为单独声明的分号要么是拼写错误,要么是由于在别处声明 extern int b 而导致的概念错误。 这里不需要extern,至少现在不需要。

这个:

int main(void) {
  int a=10, b=20;

  return 0;
}

有效。

现在是add 函数。

int add(int a, int b)
{
  return a+b;
}

int main(void) {
  int a = 10, b=20;

  add(a,b);

  return 0;
}

请注意,add 中的 abmain 中的 ab 不是同一个变量。这是至关重要的;在你理解之前不要继续。

现在添加add 函数的声明

int add(int a, int b);  // <- declaration

int add(int a, int b)   // <- definition
{
  return a+b;
}

声明可以移动到头文件中(add.h); 定义属于源文件 (add.c)。

最后,我建议你在 makefile 中添加一行:

add.o: add.h

【讨论】:

  • 哇哦,你解释的方式解决了我所有的问题。我读过博客,但你的解释回答了我所有的问题。
【解决方案3】:

你不是在最后一个头文件queue.h 的末尾缺少#endif 吗? 这肯定是编译时的一个问题。此外,您是否缺少 main_application.h 头文件,然后包含在 stack.h 中?

看看这个:https://medium.com/@m.muizzsuddin_25037/error-ld-symbol-not-found-for-architecture-x86-64-a5e5b648ffc 在这里似乎很有帮助,再次将我们的注意力指向头文件!..

【讨论】:

  • queue.h 有 #endif
  • 好的@owais,我很确定这一点,因此只需将它添加到上面编辑您的代码sn-p ;)
  • 我认为我在声明标题时可能犯了一些错误
  • @tsroe 所说的绝对正确!..关于“声明标题的错误”我想知道 main_application.c 文件是否应该命名为 main_application.h 或者只是错字?如果没有,你仍然需要一个头文件!
  • 其实我已经创建了一个 main_application.h 只是为了定义在队列和堆栈等其他文件中使用的变量。我尝试了@tsroe 提供的解决方案,但效果不佳。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
相关资源
最近更新 更多