1

I am attempting to create a makefile for a simple program which relies on a simple file and a function stored in a c file. Here are the files:

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

And here is my makefile:

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

Whenever I try type make, I get the following error:

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"

Not sure what I am doing wrong. I can compile each code separately and main works. I was getting the same error for another project I was working on, so I tried with a very simple case involving only these 2 C files, and I get the same issues. I am fairly new to makefiles and what not, so bear with me if I am making a stupid mistake.

2 Answers 2

1

You should read about difference between definition and declaration in C. As you're including function.c into your main.c, your function random_func is defined two times. Linker can't decide for you which one to use, so it errors out. For your use case you should declare random_func in main.c or additional header file.

Sign up to request clarification or add additional context in comments.

2 Comments

Not sure what you mean by this, but for the purpose of this assignment, I am required to create function.c and use that in main.c, and create a makefile with the two files.
I'm pretty sure you're not required to both use function.c in main.c and create a Makefile with both files, because that ends exactly as OP issue. As already stated, read about difference between definition and declaration in C, and fix your code so that there is only one declaration of random_func.
1

This is what happens with your files after preprocessing:

// 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;
}

It means that now you have the same function in two separate files. When you compile both of them the linker sees two valid functions random_fun, it simply does not know which one to use.


There two ways to solve this problem.

Using header

In this case, you would need to create another file, e.g. function.h:

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

Then, in main.cyou include the header instead of .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;
}

This way you will have only one random_fun function across two files, the linker would not be confused.

Using extern keyword

In your main.c you can define the random_fun function as external. It basically says to a compiler that the function exists somewhere and it will be resolved later by a linker.

#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;
}

Again, in this case, you will have just one random_fun function across two files and the linker would not be confused.


As a rule of thumb, I would say you never include .c files unless you absolutely need to. (I can hardly imagine when it may be needed.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.