Reputation: 2605
I have a small project for testing and I want to link different implementations of a solution to test.
So, I create makefile that looks like this
CC=g++
FLAGS=-Wall -O2
CFLAGS=-c $(FLAGS)
I_PATH=implementation1.cpp
all: instance
instance: instance.cpp .implementation.o
$(CC) $(FLAGS) instance.cpp .implementation.o -o $@
.implementation.o: $(I_PATH)
$(CC) $(CFLAGS) $(I_PATH) -o $@
clean:
-rm .implementation*
-rm instance
Here, I_PATH
is a path to solution implementation. And I want to test different solution passing different implementation via command line arguments: make I_PATH=implementation2.cpp
.
But, because of all my implementations compiled to the same object file .implementation.o
, make
can't understand that something changes and doesn't rebuild project.
Of course, I can call make clean
before run make
for a specific implementation. But this increase build time (I can run tests for one implementation many times) and not very comfortable.
I can fix this makefile to something like this:
CC=g++
FLAGS=-Wall -O2
CFLAGS=-c $(FLAGS)
I_PATH=implementation1.cpp
C_PATH := $(shell echo -n $(I_PATH) | md5sum | awk '{print ".implementation_" substr($$1, 0, 10) ".o";}')
all: force instance
force_relink:
touch -c $(C_PATH)
instance: instance.cpp $(C_PATH)
$(CC) $(FLAGS) instance.cpp $(C_PATH) -o $@
$(C_PATH): $(I_PATH)
$(CC) $(CFLAGS) $< -o $@
clean:
-rm .implementation*
-rm instance
Here I create I_PATH
dependent object file(take hash of path to implementation) and in addition force re-linking instance.cpp
with object file every time make
runs.
But maybe there is some mechanism in make
to fix this behavior? Or I can achieve the same goal with different approaches?
Upvotes: 0
Views: 585
Reputation: 189307
Wouldn't it make more sense to give each compiled .o
file a distinct name, and simply link to the compiled .o
file you want?
instance: instance.cpp $(IMPL_O)
$(CC) $(FLAGS) $^ -o $@ # propably no need to override default rule
Use make IMPL_O=implementation2.o
to generate the example in your question.
This way, the name of each file truly reveals its identity, and you don't have to keep track of anything explicitly.
(Obviously, you could refactor the .o
extension into the Makefile itself so you can just say IMPL=implementation2
or whatever.)
Upvotes: 1