【问题标题】:Makefile duplicate symbol for architecture x86_64 error?架构 x86_64 错误的 Makefile 重复符号?
【发布时间】:2017-10-12 23:34:26
【问题描述】:

我正在尝试为依赖于简单文件和存储在 c 文件中的函数的简单程序创建生成文件。以下是文件:

function.c:

int random_fun(int n, int m)
{  int g;
   n = n+m;
   m=n/3;
   g=n*m;
   return g;
}

main.c:

#include <stdio.h>
#include "function.c"
int main()
{
   int a, b;
   printf("Enter numbers a, and b: ");
   scanf("%d %d", &a, &b);
   printf("Here is ur answer: %d", random_fun(a, b));
   return 0;
}

这是我的makefile:

OBJS = main.o function.o
program: $(OBJS)
    $(CC) -o $@ $?
clean:
    rm $(OBJS) program

每当我尝试输入 make 时,都会收到以下错误:

duplicate symbol _random_fun in:
    main.o
    function.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see 
invocation)
make: *** [program] Error 1"

不知道我做错了什么。我可以分别编译每个代码和主要工作。对于我正在处理的另一个项目,我遇到了同样的错误,所以我尝试了一个非常简单的案例,只涉及这两个 C 文件,我遇到了同样的问题。我对 makefile 还很陌生,如果我犯了一个愚蠢的错误,请多多包涵。

【问题讨论】:

    标签: c makefile clang


    【解决方案1】:

    您应该阅读 C 中定义和声明之间的区别。 当您将function.c 包含到您的main.c 中时,您的函数random_func 被定义了两次。链接器无法为您决定使用哪一个,因此会出错。 对于您的用例,您应该在 main.c 或其他头文件中声明 random_func。

    【讨论】:

    • 不知道你的意思,但是为了这个任务,我需要创建function.c并在main.c中使用它,并用这两个文件创建一个makefile。
    • 我很确定你不需要both在main.c 中使用function.c 并为这两个文件创建一个Makefile,因为这完全一样操作问题。如前所述,请阅读 C 中定义和声明之间的区别,并修复您的代码,以便只有一个 random_func 声明。
    【解决方案2】:

    这是您的文件在预处理后会发生的情况:

    // function.c
    int random_fun(int n, int m)
    {  int g;
       n = n+m;
       m=n/3;
       g=n*m;
       return g;
    }
    

    -

    // main.c
    // contents of stdio.h goes first. I omit it for brevity
    int random_fun(int n, int m)
    {  int g;
       n = n+m;
       m=n/3;
       g=n*m;
       return g;
    }
    
    int main()
    {
       int a, b;
       printf("Enter numbers a, and b: ");
       scanf("%d %d", &a, &b);
       printf("Here is ur answer: %d", random_fun(a, b));
       return 0;
    }
    

    这意味着现在您在两个单独的文件中拥有相同的功能。当你编译它们时,链接器会看到两个有效的函数random_fun,它根本不知道使用哪一个。


    有两种方法可以解决这个问题。

    使用标题

    在这种情况下,您需要创建另一个文件,例如function.h:

    // random.h
    int random_fun(int n, int m);
    

    然后,在main.c中包含标题而不是.c:

    #include <stdio.h>
    #include "function.h" // <-- .h, not .c
    
    int main()
    {
       int a, b;
       printf("Enter numbers a, and b: ");
       scanf("%d %d", &a, &b);
       printf("Here is ur answer: %d", random_fun(a, b));
       return 0;
    }
    

    这样你将在两个文件中只有一个random_fun 函数,链接器不会被混淆。

    使用 extern 关键字

    在您的main.c 中,您可以将random_fun 函数定义为外部函数。它基本上告诉编译器该函数存在于某处,稍后将由链接器解析。

    #include <stdio.h>
    extern int random_fun(int n, int m);
    int main()
    {
       int a, b;
       printf("Enter numbers a, and b: ");
       scanf("%d %d", &a, &b);
       printf("Here is ur answer: %d", random_fun(a, b));
       return 0;
    }
    

    同样,在这种情况下,您将只有一个 random_fun 函数跨两个文件,链接器不会混淆。


    根据经验,我会说你永远不要包含.c 文件,除非你绝对需要。 (我很难想象什么时候可能需要它。)

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 2021-03-16
      • 2015-12-08
      • 2015-01-22
      • 2022-06-13
      • 2023-04-04
      • 2016-07-13
      • 1970-01-01
      相关资源
      最近更新 更多