A question about Makefile run by GNU make

Hello everybody,

Currently I'm learning how to build projects (C programming) with GNU make. I have a problem with one Makefile and I would appreciate if you could kindly give me a hand. Here is the environment:

  • OS: Redhat linux 5
  • compiler: gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
  • make: GNU Make 3.81

I have one header file (.h) and two .c files. All of the files are in the same directory. here is my Makefile:

Makefile:

CCFLAGS=-c -Wall
CC=gcc
.PHONY:clean

file1:mathfun1.o mathfun1.h
    $(CC) file1.c $^ -o $@

mathfun1.o:mathfun1.c mathfun1.h
    $(CC) $(CCFLAGS) mathfun1.c

clean:
    rm *.o file1

This works pretty well. But there is a problem. The file named file1.c is the principal file, that is, the file that includes the main function. As you can see in the first entry, among the prerequisites of the target file1, I just included mathfun1.o and mathfun1.h. As a result, if the source file "file1.c" is modified the target file1 is not updated because 'file1.c' is not in the list of the prerequisited of the target file1. Now, the problem is that if I add this file to the list of the preequisites I receive an error message.

I mean, if in the Makefile, instead of

file1:mathfun1.o mathfun1.h
    $(CC) file1.c $^ -o $@

I write

file1:mathfun1.o mathfun1.h file1.c
    $(CC) file1.c $^ -o $@

I receive the following error message:

$ make
gcc file1.c mathfun1.o file1.c -o file1
/tmp/ccYLTgKK.o: In function `main':
file1.c:(.text+0x0): multiple definition of `main'
/tmp/ccC0ZVY7.o:file1.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [file1] Error 1
$

Any idea? why I get this error message?

Thanks in advance,

Kind Regards,
Dariyoosh

In the case where it may be helpful, here are the complete definitions of other files. As I said earlier, all files are in the same directory.

mathfun1.h

#include <stdio.h>

int max(int n1, int n2);
int min(int n1, int n2);

mathfun1.c

#include "mathfun1.h"

int max(int n1, int n2)
{
    return ((n1 >= n2)?n1:n2);
}


int min(int n1, int n2)
{
    return ((n1 <= n2)?n1:n2);
}

file1.c

int main(int argc, char *argv[])
{
    int n1 = 0;
    int n2 = 0;

    printf("enter two integers: ");

    scanf("%d%d",&n1, &n2);
    printf("\n");

    printf("max(%d,%d) = %d\n", n1, n2, max(n1,n2));

    return 0;
}

In simple words the error means there are two main functions since you have included file1.c twice here

gcc file1.c mathfun1.o file1.c -o file1

What you can do to solve your problem is build two object files mathfun1.o and file1.o and build the executable "file1" including both these object files. Your makefile would look something like this

CCFLAGS=-c -Wall
CC=gcc

file1:mathfun1.o file1.o
        $(CC) $^ -o $@

file1.o:file1.c
        $(CC) $(CCFLAGS) file1.c
mathfun1.o:mathfun1.c
        $(CC) $(CCFLAGS) mathfun1.c

clean:
        rm *.o file1

Regards,
Harish J

1 Like

Hello there,

Thank you very much for your attention to my question. In fact this was the source of the problem. Here is therefore the new version of Makefile

CCFLAGS=-c -Wall
CC=gcc
.PHONY:clean

file1:mathfun1.o file1.o mathfun1.h
    $(CC) $^ -o $@

file1.o:mathfun1.h file1.c
    $(CC) $(CCFLAGS) file1.c

mathfun1.o:mathfun1.c mathfun1.h
    $(CC) $(CCFLAGS) mathfun1.c

clean:
    rm *.o file1

And everything works pretty well now.

Thank you very much!

Kind Regards,
Dariyoosh
:smiley: