3

I just started learning about makefiles: i created a simple tutorial by myself but it seems I am mistaken somewhere and i don't know where; my mini-tutorial is formed by a main.c script that recalls a function named kernel.c; within this last function 2 more functions are called: add.c (which adds 2 numbers together) and mul.c (which multiplies the result of the previous sum); i then created the headers kernel.h and functions.h which contain the prototypes of the functions defined above; this two header are contained in a folder created within the same one of the main.c script: common/inc

Here are the files:

//main
#include <stdio.h>
#include <stdlib.h>
#include "kernel.h"

int main(){
int a = 5, b = 4, c = 0;
int *pa, *pb, *pc;
pa = &a; pb = &b; pc = &c;

kernel(pa, pb, pc);

printf("c = %d\n", c);

return 0;
}

here is kernel.c

#include "kernel.h"
#include "functions.h"

void kernel(int* a, int*b, int* c){
 int x = add(*a,*b);
 *c = mul(x);
}

here is add.c

#include "functions.h"

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

here is mul.c

#include "functions.h"

int mul(int a){
return a*2;
}

here is kernel.h

void kernel(int* a, int*b, int* c);

here is functions.h

int add(int a, int b);
int mul(int a);

The make file i wrote looks like this:

#===========================Makefile================================#

CC=gcc
IDIR = common/inc
CFLAGS=-c -Wall -I$(IDIR)

all: eseguibile

eseguibile: main.o  
    $(CC) $(CFLAGS) main.o -o eseguibile

main.o: main.c kernel.o
    $(CC) $(CFLAGS) main.c kernel.o

kernel.o: kernel.c add.o mul.o
    $(CC) $(CFLAGS) kernel.c add.o mul.o

add.o: add.c 
    $(CC) $(CFLAGS) add.c

mul.o: mul.c 
    $(CC) $(CFLAGS) mul.c

clean:
    rm -rf *o eseguibile

I know the program works because if i type gcc main.c kernel.c add.c mul.c -I common/inc/ in the terminal everything works fine.

Can anyone tell me what I a doing wrong?`

The error that i get is this:

gcc -c -Wall -Icommon/inc add.c
gcc -c -Wall -Icommon/inc mul.c
gcc -c -Wall -Icommon/inc kernel.c add.o mul.o
gcc: warning: add.o: linker input file unused because linking not done
gcc: warning: mul.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.c kernel.o
gcc: warning: kernel.o: linker input file unused because linking not done
gcc -c -Wall -Icommon/inc main.o -o eseguibile
gcc: warning: main.o: linker input file unused because linking not done
Federico Gentile
  • 5,650
  • 10
  • 47
  • 102

1 Answers1

8

I prefer to build the objects separately, and then combine them all at the end. I think the problem is that you are including a -c flag on the final executable. Try this:

#===========================Makefile================================#

CC=gcc
IDIR = common/inc
CFLAGS=-Wall -I$(IDIR)
OBJS = main.o kernel.o add.o mul.o

all: eseguibile

eseguibile: $(OBJS)
    $(CC) $(CFLAGS) $^ -o eseguibile

main.o: main.c kernel.h
    $(CC) -c $(CFLAGS) main.c

kernel.o: kernel.c kernel.h functions.h
    $(CC) -c $(CFLAGS) kernel.c

add.o: add.c functions.h
    $(CC) -c $(CFLAGS) add.c

mul.o: mul.c functions.h
    $(CC) -c $(CFLAGS) mul.c

clean:
    rm -rf *.o eseguibile
Gillespie
  • 5,780
  • 3
  • 32
  • 54
  • It worked!!! I had to slightly modify it by removing kernel.h which is included into the common/inc folder; besides that it works... thank you very much!! – Federico Gentile Dec 12 '14 at 22:52
  • 2
    Keep in mind that right now the targets (`main.o`, `kernel.o`, etc.) are only dependent on one file each, so if you modify `kernel.h`, for example, the makefile won't know what targets need re-building. So, you may want to add the `.h` files as dependencies to the targets that use them. Otherwise you'll find yourself doing `make clean; make` a lot. – Gillespie Dec 12 '14 at 22:56
  • I updated the makefile I posted to include the `.h` dependencies you listed above, just to give you an idea of what it should look like. Basically, all a dependency does is tell make "if the timestamp on this file changes, rebuild the target" – Gillespie Dec 12 '14 at 23:00
  • I was going to ask you why you added `kernel.h`, cause I didn't know that, and in fact I've always had to do a lot of `make clean` to compile my code when I make some changes, nice. – Patricio Sard Dec 12 '14 at 23:02
  • `make clean` is a good sanity check, but if you are doing it alot it probably means some of your targets are missing dependencies. If your project starts getting larger, compilers can auto-generate the dependencies for you, too - http://scottmcpeak.com/autodepend/autodepend.html and http://stackoverflow.com/questions/2394609/makefile-header-dependencies – Gillespie Dec 12 '14 at 23:06
  • For anyone who wants a deeper dive, here's a link to the make manual that I managed to find online: https://www.gnu.org/software/make/manual/make.pdf. Just in case anyone else is looking for it. – Zach Feb 19 '23 at 19:36