Reputation: 95
I have the following Makefile
. For some reason when I do make
it always rebuilds the target test_phantom_types.o
even when I haven't modified the files.
GTEST_HEADERS = ${GTEST_DIR}/include/gtest/*.h \
${GTEST_DIR}/include/gtest/internal/*.h
BASE_DIR = ..
BUILD_DIR = build
USER_DIR = $(BASE_DIR)/tests/src
CPPFLAGS += -isystem $(GTEST_DIR)/include
CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11
TESTS = test_phantom_types
all : $(TESTS)
clean :
cd $(BUILD_DIR); \
rm -rf $(BUILD_DIR)/*.o; \
cd ../
test_phantom_types.o : $(USER_DIR)/test_phantom_types.cpp \
$(BASE_DIR) $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -I$(BASE_DIR) -c $(USER_DIR)/test_phantom_types.cpp -o $(BUILD_DIR)/$@
test_phantom_types : test_phantom_types.o
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $(addprefix $(BUILD_DIR)/,$^) ${GTEST_DIR}/libgtest.a ${GTEST_DIR}/libgtest_main.a -o $(addprefix $(BUILD_DIR)/, $@)
check : $(TESTS)
./$(addprefix $(BUILD_DIR)/,$^)
.PHONY : clean
Upvotes: 0
Views: 25
Reputation: 80931
make is very literal.
You told it you have a target called test_phantom_types.o
so it expects that target to generate that file.
In your case, however, it doesn't. It generates $(BUILD_DIR)/$@
(from -o $(BUILD_DIR)/$@
) and that's not the same thing.
So when you run make
and make determines (from the all
-> test_phantom_types
-> test_phantom_types.o
sequence) that it needs to check if it needs to build the test_phantom_types.o
file it goes to look for it, can't find it and rebuilds it.
You can see this in the output from make -d
if you try it.
That's why the second Rule of Makefiles is
2.Every non-.PHONY rule must update a file with the exact name of its target.
Make sure every command script touches the file “$@“–not “../$@“, or “$(notdir $@)“, but exactly $@. That way you and GNU make always agree.
Upvotes: 2