asaelr
asaelr

Reputation: 5456

How to tell make to not recompile if I delete object files?

As a hobby, I wrote a simple compiler, and I wrote some test files to check that it works fine. I also added some lines in my makefile, so I can, by one command, to compile my compiler, compile (using it) the test files, assemble them and link them. The problem is, that if I remove the object files (which the compiler was linked from) and tell make to run the test, it's recompile my compiler, although that the binary file is still exist. How can I tell make to not do that? (But I still want the option to tell make to recompile changed source files, and relink my compiler).

some lines from my makefile:

OBJS=asm.o main.o type.o var.o ...
SAMPLES=arr.out sample.out ...
SAMPASM=arr.asm sample.asm ...

all: myc

myc: ${OBJS}
    ${CC} ${LDFLAGS} -o myc ${OBJS}

%.o: src/%.c src/myc.h
    $(CC) $(CFLAGS) $< -o $@

test: ${SAMPLES} ${SAMPASM}

%.out: %.aso asm/com.aso
    ld $< asm/com.aso -o $@

%.aso: %.asm
    nasm -f elf64 $< -o $@

%.asm: samples/%.myc myc
    ./myc $< -o $@

clean:
    rm -f *.o *.out *.asm myc

Upvotes: 1

Views: 362

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 753970

Recommendation:

  • Separate your tests from your compiler build directory

(That is, you should do your testing in a separate directory, so you don't run into the problem.)

I've not tinkered with GNU Make and .INTERMEDIATE or .SECONDARY files; I don't know if that will do the job for you.

The alternative option I see for you is to rebuild the entire compiler each time any of its source files or headers changes:

FILES.c = src/main.c src/type.c src/var.c ...
FILES.s = src/asm.s
FILES.h = src/myc.h ...

PROGRAM = myC

all: ${PROGRAM} test

${PROGRAM}: ${FILES.c} ${FILES.s} ${FILES.h}
    ${CC} ${CFLAGS} -o $@ ${FILES.c} ${FILES.s} ${LDFLAGS} ${LDLIBS}

While the compiler is small enough for this not to be painful, it will work. It does, however, completely eliminate the benefits of object files for the compiler itself; it means everything is always recompiled. But you can get rid of the object files at any time because the compiler is not documented to depend on them.

I'm moderately convinced this is the wrong approach, although it will 'work'. You should use separate directories for building the compiler and running tests on the compiler.

Upvotes: 0

Andres
Andres

Reputation: 5187

You can use .SECONDARY or .INTERMEDIATE

From http://theory.uwinnipeg.ca/localfiles/infofiles/make/make_36.html

.INTERMEDIATE The targets which .INTERMEDIATE depends on are treated as intermediate files. See section Chains of Implicit Rules. .INTERMEDIATE with no dependencies marks all file targets mentioned in the makefile as intermediate.

.SECONDARY The targets which .SECONDARY depends on are treated as intermediate files, except that they are never automatically deleted. See section Chains of Implicit Rules. .SECONDARY with no dependencies marks all file targets mentioned in the makefile as secondary.

Generally, if you want to have your .o files deleted automatically, then use

.INTERMEDIATE: $(OBJS)

If you want make to just not care if the o files are there or not, use

.SECONDARY: $(OBJS)

Upvotes: 4

Related Questions