架构x86_64错误的Makefile重复符号?

时间:2017-10-12 23:34:26

标签: c makefile clang

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

function.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;
}

main.c中:

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

这是我的makefile:

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"

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

play.filters.enabled=[youDesiredFilter]

不确定我做错了什么。我可以分别编译每个代码和主要工作。我正在为我正在处理的另一个项目得到同样的错误,所以我尝试了一个只涉及这两个C文件的非常简单的案例,我得到了同样的问题。我是一个相当新的makefile,什么不是,如果我犯了一个愚蠢的错误,请耐心等待。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

预处理后文件会发生这种情况:

// 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个文件。 (我很难想象何时需要它。)