Trying to learn makefile. Correct me if I’m understanding it wrong.
CXX_SOURCES = $(wildcard $(SOURCE_DIR)/*.cc)
CXX_OBJECTS = $(patsubst $(SOURCE_DIR)/%.cc, $(BUILD_DIR)/%.o, $(CXX_SOURCES))
Here patsubst will find all patterns with $(SOURCE_DIR)/%.cc
replace them with $(BUILD_DIR)/%.o
and input is $(CXX_SOURCES)
BUT patsubst will only do the renaming. It will not actually compile .cc files into .o files.
So to do that we create a target
$(BUILD_DIR)/%.o
Which is same as the replacement parameter in patsubst.
So when patsubst statement executes, it comes to this target and compiles the file.
I tried commenting out
$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.cc
$(CXX_COMPILER_CALL) -c $< -o $@
But then I get the error
mingw32-make: *** No rule to make target ‘build/my_lib.o’, needed by ‘build’. Stop.
Why is it not simply renaming the files?
DEBUG = 1
INCLUDE_DIR = include
SOURCE_DIR = src
BUILD_DIR = build
CXX_STANDARD = c++17
CXX_WARNINGS = -Wall -Wextra -Wpedantic
CXX = g++
CXXFLAGS = $(CXX_WARNINGS) -std=$(CXX_STANDARD)
CPPFLAGS = -I $(INCLUDE_DIR)
LDFLAGS =
ifeq ($(DEBUG), 1)
CXXFLAGS += -g -O0
EXECUTABLE_NAME = mainDebug
else
CXXFLAGS += -O3
EXECUTABLE_NAME = mainRelease
endif
CXX_COMPILER_CALL = $(CXX) $(CXXFLAGS) $(CPPFLAGS)
CXX_SOURCES = $(wildcard $(SOURCE_DIR)/*.cc)
CXX_OBJECTS = $(patsubst $(SOURCE_DIR)/%.cc, $(BUILD_DIR)/%.o, $(CXX_SOURCES))
##############
## TARGETS ##
##############
create:
@mkdir -p build
build: $(CXX_OBJECTS)
@echo $(CXX_OBJECTS) Hi
$(CXX_COMPILER_CALL) $(CXX_OBJECTS) $(LDFLAGS) -o $(BUILD_DIR)/$(EXECUTABLE_NAME)
execute:
./$(BUILD_DIR)/$(EXECUTABLE_NAME)
clean:
rm -f $(BUILD_DIR)/*.o
rm -f $(BUILD_DIR)/$(EXECUTABLE_NAME)
##############
## PATTERNS ##
##############
#$(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.cc
# $(CXX_COMPILER_CALL) -c $< -o $@
2