user2467929
user2467929

Reputation:

Makefile - Efficient Compiling

Let's say, compiling hello.c requires car.c and water.c. But main.c requires hello.c.

When I say requires, I mean that the compiled output would differ if the things it requires is modified in any way.

So, if car.c or water.c is changed, then hello.c would need recompiling.

Then, would this be the correct Makefile?

main: main hello.o

  gcc main.c hello.c -o main

hello.o: water.c, car.c

  gcc water.c car.c -o hello.o

Otherwise, if it's not correct, can someone explain to me why it is wrong and give me an example?

Thank you!

Upvotes: 1

Views: 415

Answers (4)

hayesti
hayesti

Reputation: 3073

What you're doing is a little strange, but I guess not incorrect. Don't have a recursive dependency on main and compile hello.o as an object file.

main: main.c hello.o
    gcc main.c hello.o -o main

hello.o: hello.c water.c car.c
    gcc hello.c water.c car.c -c hello.o

Upvotes: 1

Chris Dodd
Chris Dodd

Reputation: 126233

Let's say, compiling hello.c requires car.c and water.c. But main.c requires hello.c.

This statement doesn't make a lot of sense. The only thing it could mean is that either these aren't C or C++ source files, rather some other language that uses these names confusingly, or they contain #include directives that include those other files.

In that latter case (which is rare, and a poor design), there's no need to specify the included files on the command line, since gcc will include them for you. You just need to specify the dependencies in the Makefile:

main: main.c hello.c car.c water.c
        gcc -o main main.c

since main.c has #include "hello.c" and hello.c has #include "car.c" and #include "water.c", only the one compile gets everything.

If these are some other language, and you mean something completely different, its likely that gcc can't understand (or compile) them at all...

Upvotes: 3

Eugeniu Rosca
Eugeniu Rosca

Reputation: 5305

In your makefile there are entities of the following type:

  • final executable program: main
  • compiled objects (relocatable ELFs linked into the main executable). I can see hello.o, but I cannot find water.o, car.o and main.o (since each *.c compilation unit is generally converted by the compiler to a *.o compiled object).
  • the source files (compilations units): main.c, hello.c, water.c and car.c. These are used as inputs by the compiler to generate the corresponding *.o files.

So, based on the above, the appropriate Makefile would look like this (tested):

main.o:
        gcc -c main.c

hello.o:
        gcc -c hello.c

water.o:
        gcc -c water.c

car.o:
        gcc -c car.c

main: hello.o water.o car.o main.o
        gcc hello.o water.o car.o main.o -o main

The shortened versioned, using makefile text functions and automatic variables (tested):

%.o:
        gcc -c $(addsuffix .c, $(basename $@))

main: hello.o water.o car.o main.o
        gcc $^ -o main

Another approach (tested):

SRC := hello.c water.c car.c main.c
OBJ := $(addsuffix .o, $(basename $(SRC)))

main: $(OBJ)
        gcc $^ -o main

Upvotes: 0

foobarfuzzbizz
foobarfuzzbizz

Reputation: 58657

I would re-write it as:

SRC := hello.c main.c water.c
OBJS := $(patsubt %.c,%.o,$(SRC))

main: $(OBJS)
    $(CC) -o $@ $^

This makefile works because there is an implicit rule for compiling C files. This will mean that when $(OBJS) is expanded to hello.o, main.o, and water.o, each of those .o files will be built by "$(CC) -o hello.o -c hello.c".

Note that if you use the GCC -c flag to only compile the file, but not link it, you will not need to be worried that hello.c relies on car.c and water.c.

EDIT:

Note that in your original makefile, the line "main: main hello.o" is incorrect. A target cannot depend on itself.

In general, with Make, you want to specify dependencies, but not the implementation of making those dependencies, if you can help it. It is much cleaner to say "I need this" versus "do these steps". In a lot of cases, Make is smart enough that if you say "I need this," it will "do the right thing."

Upvotes: 0

Related Questions