Для ясности любому, кто ищет ответ в будущем, я публикую свой исправленный Makefile:
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
# execute `make D='-g'` to make with debug symbols
DEFS := $(D)
CC := gcc $(DEFS)
CFLAGS := -I$(INCLUDE) -std=c99 -Wall -Wextra
CXX := g++ $(DEFS)
CXXFLAGS := -I$(INCLUDE) -std=c++17 -Wall -Wextra
#LIBSOURCES := $(wildcard $(LIB)/*.cpp)
#LIBOBJECTS := $(LIBSOURCES:%.cpp=%.o)
#OBJECTS := $(subst $(LIB)/,,$(LIBOBJECTS))
SOURCES := $(wildcard $(SRC)/*.cpp)
OBJECTS := $(SOURCES:%.cpp=%.o)
EXECUTABLE := main
#
# Targets
#
.PHONY: clean all
all: $(BIN)/$(EXECUTABLE)
clean:
$(RM) $(BIN)/$(EXECUTABLE)
$(RM) $(OBJECTS)
run: all
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -L$(LIB) $^ -o $@
#
# Dependencies - must be at end of makefile
#
DEPDIR := $(SRC)/.d
$(shell mkdir -p $(DEPDIR) >/dev/null)
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td
POSTCOMPILE = @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@
%.o: %.c
%.o: %.c $(DEPDIR)/%.d
$(CC) -c -o $@ $(DEPFLAGS) $(CFLAGS) $<
$(POSTCOMPILE)
%.o: %.cpp
$(SRC)/%.o: $(SRC)/%.cpp $(DEPDIR)/%.d
$(CXX) -c -o $@ $(DEPFLAGS) $(CXXFLAGS) $<
$(POSTCOMPILE)
$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
include $(wildcard $(patsubst %,$(DEPDIR)/%.d,$(basename $(SOURCES))))
Чтобы уточнить мой комментарий к ответу выше, если я закомментирую цель переопределения(%.o: %.cpp
), вот вывод:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SRecord.o src/SRecord.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/SerialPort.o src/SerialPort.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/ShadowUpdate.o src/ShadowUpdate.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -c -o src/main.o src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main
Очевидно, что зависимости не создаются.Мое правило не было выполнено.
Но, с пустой целью %.o: %.cpp
, make работает, как и ожидалось:
$ make clean; make
rm -f bin/main
rm -f src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o
g++ -c -o src/SRecord.o -MT src/SRecord.o -MMD -MP -MF src/.d/SRecord.Td -Iinclude -std=c++17 -Wall -Wextra src/SRecord.cpp
g++ -c -o src/SerialPort.o -MT src/SerialPort.o -MMD -MP -MF src/.d/SerialPort.Td -Iinclude -std=c++17 -Wall -Wextra src/SerialPort.cpp
g++ -c -o src/ShadowUpdate.o -MT src/ShadowUpdate.o -MMD -MP -MF src/.d/ShadowUpdate.Td -Iinclude -std=c++17 -Wall -Wextra src/ShadowUpdate.cpp
g++ -c -o src/main.o -MT src/main.o -MMD -MP -MF src/.d/main.Td -Iinclude -std=c++17 -Wall -Wextra src/main.cpp
g++ -Iinclude -std=c++17 -Wall -Wextra -Llib src/SRecord.o src/SerialPort.o src/ShadowUpdate.o src/main.o -o bin/main