move_slow_break_things
move_slow_break_things

Reputation: 847

Makefile query-C

This was on an exam of mine and I'm reviewing and can't figure out why I lost points on it. Too late to ask the professor now so I'm here. Have I just not understood the basics of makefile? This is the problem:

The file engine.c includes the file engine.h and engine.h includes the file temp.h. Write one or more makefile rules that generates the file engine.o."

This was my answer:

engine.o: engine.c engine.h
    gcc -c engine.c

The answer key says it should be:

engine.o: engine.c engine.h temp.h
    gcc -c engine.c 

But I don't get it. The object file for engine.c doesn't depend on temp.h does it? engine.h depends on it. And I would handle temp.h if I was writing another target for engine.h but I'm not. Strictly speaking about the target for engine.o, do I need temp.h?

Upvotes: 4

Views: 80

Answers (3)

copj
copj

Reputation: 11

engine.c depends on engine.h, and any change in engine.h can have significant change in engine.c

Similarly engine.h depends on temp.h, and any change in temp.h can have significant change in engine.h, which will indirectly have impact on engine.c

lets see this with an example:

in temp.h

#define ID 1

in engine.h

#define ENGINE_ID ID

in engine.c

engineId = ENGINE_ID;

if you modify ID, but in makefile rule is this:

engine.o: engine.c engine.h
gcc -c engine.c 

the file will not recompile. But with

engine.o: engine.c engine.h temp.h
gcc -c engine.c 

The file will get recompiled with new ID.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206567

Let's say the contents of temp.h are:

#pragma once

void temp_function(int x);

and the contents of engine.h are:

#pragma once
#include "temp.h"

void engine_function(int a, int b);

and the contents of engine.c are:

#include "engine.h"

void engine_function(int a, int b)
{
   temp_function(a+b);
}

Let's also say that for some reason the contents of temp.h are changed to:

#pragma once

void temp_function(int x, int y);

Let's assume that temp_function is implemented in another file.

If you don't re-compile eninge.c, then the object code in engine.o for temp_function does not match the object code for the function in the file in which it is implemented. As a result, you will see a link time error. If you re-compile engine.c, you will see a compile time error.

It is always better to catch errors at compile time than at link time.

The rule

engine.o: engine.c engine.h temp.h

makes sure that the command to build engine.o is executed when temp.h is changed, and the compile time error is caught.

Upvotes: 2

aghast
aghast

Reputation: 15300

To review:

The file engine.c includes the file engine.h and engine.h includes the file temp.h

So that's:

engine.c

#include "engine.h"

engine.h

#include "temp.h"

temp.h

/* nothing */

If you modify temp.h, then you need to rebuild engine.o from its parts, because one of its parts is (eventually) temp.h.

When all the including is done, the code effectively looks like this:

engine.c

/* #include "engine.h" */

engine.h

/* #include "temp.h" */

temp.h

/* end of temp.h */

...

/* end of engine.h */

...

/* end of engine.c */

In fact, if you use something like gcc -E engine.c > engine.i you can see this for yourself. The -E option stops after the preprocessing phase, translating C source into C source-without-preprocessor-directives.

Upvotes: 1

Related Questions