tags:

views:

46

answers:

5

Hello,

gcc 4.4.4

I have the following Makefile

OBJECT_FILES = brd.o logger.o test_brd.o
CFLAGS = -m32 -ggdb -Wall -Wextra -D_REENTRANT -D_THREAD_SAFE -O0 -D_DEBUG

# Linker Run-time library path
LDFLAGS = -Wl,-rpath=/usr/NET/lib 

FLATFORM = -DLINUX
TARGET = dlg
CC = gcc -m32

LIBS_PATH = -L/usr/NET/lib
INC_PATH = -I/usr/NET/include

LIBS = -lnc -lnxx -lphread

$(TARGET): $(OBJECT_FILES)
    $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECT_FILES) $(FLATFORM) $(INC_PATH) $(LIBS_PATH) $(LIBS) -o $(TARGET)

test_brd.o: test_brd.c brd.c
    $(CC) -c $(CFLAGS) test_brd.c

brd.o: brd.c logger.c
    $(CC) -c $(CFLAGS) $(INC_PATH) brd.c

logger.o: logger.c
    $(CC) -c $(CFLAGS) $(INC_PATH) logger.c

clean: 
    rm -f $(TARGET) $(OBJECT_FILES)

However, the logger.c doesn't need to be built anymore. Is there a way to include it in the project without having to compile it each time. When I clean my project. It will re-compile it again, and it is a large file.

Many thanks for any suggestions,

+2  A: 

What your Makefile says is that logger.c should be recompiled if and only if it is newer than logger.o if that exists. What I think you probably want is

.PRECIOUS: logger.o

somewhere in your file to tell make that logger.o may be an intermediate file, but should not be removed whenever make thinks it's not going to need it any more. Maybe even

.PRECIOUS: $(OBJECT_FILES)

to extend the effect to all three object files.

Edit: Er, you do realize that there is usually no need to call make clean, right? Make is all about handling dependencies for you and only rebuild what is needed.

Christopher Creutzig
+1  A: 

It should be something like

SMALL_OBJECT_FILES = brd.o test_brd.o
OBJECT_FILES = $(OBJECT_FILES) logger.o

...

clean:
    rm -f $(TARGET) $(SMALL_OBJECT_FILES)
Vanya
+1  A: 

If you don't update the timestamp on logger.c, and don't remove logger.o, then the file will not get recompiled.

The issue is that your clean target is removing logger.o. Provided that logger.o is really used by your final binary, recompiling is unavoidable.

You must relax one of two constraints:

  • Having make clean actually remove all intermediate object files
  • Having logger.c get recompiled after each make clean; make
Borealid
+1  A: 

You could change:

OBJECT_FILES = brd.o logger.o test_brd.o

into:

OBJECT_FILES_EXCEPT_LOGGER = brd.o test_brd.o
OBJECT_FILES = $(OBJECT_FILES_EXCEPT_LOGGER) logger.o

and change your clean to:

clean: 
    rm -f $(TARGET) $(OBJECT_FILES_EXCEPT_LOGGER)

But the whole point to clean is to do a full rebuild. If you don't want a full rebuild, just use make on its own and it'll build only what it needs to. With a properly built makefile, you should almost never need to do a full rebuild (the only exception I can think of to that is when you change the makefile itself but I even bypass that by making all rules depend on the makefile as well).

By the way,

brd.o: brd.c logger.c

and

test_brd.o: test_brd.c brd.c

don't seem write to me - there's no dependency between brd.o and logger.c, nor between test_brd.o and brd.c (at least based on your compilation statements). The only way you would have a dependency is if you #include'd one C file within another, and that's rarely a good idea.

paxdiablo
+1  A: 

Have you tried removing logger.o from the Makefile like this:

OBJECT_FILES = brd.o test_brd.o

EDIT:

and of course:

$(TARGET): $(OBJECT_FILES)
    $(CC) $(CFLAGS) $(LDFLAGS) $(OBJECT_FILES) logger.o $(FLATFORM) $(INC_PATH) $(LIBS_PATH) $(LIBS) -o $(TARGET)
MattBianco