Created
April 28, 2019 02:12
-
-
Save charmoniumQ/a2b2df12caa767ca79f028f00069996a to your computer and use it in GitHub Desktop.
Epic makefile that automatically detects dependencies and only recompiles when one of them changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Project-specific | |
| # location to create for binaries | |
| BUILD_DIR := build | |
| # location of source code | |
| SOURCE_DIR := source | |
| # name of main executable in $(SOURCE_DIR) without .c | |
| EXECUTABLE := main | |
| # Space-separated pkg-config libraries used by this project | |
| LIBS := gmp gmpxx | |
| # source ext. Some people use .cxx, .cc, .cpp | |
| SOURCE_EXT := cpp | |
| DEBUG := t | |
| # Flags | |
| ifeq ($(DEBUG),t) | |
| CXXOPTIMIZATION := -Og | |
| CXXDEBUG := -g -fsanitize=address | |
| CXXWARNINGS := #-Wall -Wextra #-Werror | |
| else | |
| CXXOPTIMIZATION := -O3 | |
| CXXDEBUG := | |
| CXXWARNINGS := #-Wall | |
| CXXFLAGS += -DNDEBUG | |
| endif | |
| CXXVERSION := -std=c++11 | |
| CXXLIBS := $(if $(LIBS),$(shell pkg-config --cflags $(LIBS))) | |
| CXXFLAGS += $(CXXDEBUG) $(CXXVERSION) $(CXXWARNINGS) $(CXXOPTIMIZATION) $(CXXVERSION) $(CXXLIBS) | |
| LDLIBS := $(if $(LIBS),$(shell pkg-config --libs $(LIBS))) | |
| LDFLAGS += $(LDLIBS) $(CXXDEBUG) -lstdc++ | |
| # sane env | |
| SHELL := /bin/sh | |
| MKDIR := mkdir | |
| # `find` recurses into subdirectories to get all your source files | |
| SOURCE_FILES := $(shell find $(SOURCE_DIR)/ -name '*'.$(SOURCE_EXT)) | |
| # rename them to .o for the object files and put them in build/ | |
| OBJECT_FILES := $(patsubst $(SOURCE_DIR)/%.$(SOURCE_EXT),$(BUILD_DIR)/%.o,$(SOURCE_FILES)) | |
| # DEPENDENCY_FILES will be for dependnecy mapping | |
| DEPENDENCY_FILES := $(patsubst $(SOURCE_DIR)/%.$(SOURCE_EXT),$(BUILD_DIR)/%.d,$(SOURCE_FILES)) | |
| # See GCC's -M option. | |
| # The compiler will parse the file, but not compile. | |
| # It looks for the included files and writes a Make rule. | |
| # This way, I know that if included_file.h changes, we need to recompile file.o | |
| # file.o: included_file.h included_file2.h file.cc | |
| $(BUILD_DIR)/%.d: $(SOURCE_DIR)/%.$(SOURCE_EXT) | |
| $(MKDIR) -p $$(dirname $@) && \ | |
| $(CXX) -MT $(BUILD_DIR)/$*.o -MM $< > $@ | |
| -include $(DEPENDENCY_FILES) | |
| # Compile object files | |
| # This way big projects don't have to recompile every file; only what changed | |
| $(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.$(SOURCE_EXT) | |
| @$(START_TIME) | |
| $(CXX) -c $(CXXFLAGS) $< -o $@ | |
| @$(END_TIME) | |
| # Link executable from object files | |
| $(BUILD_DIR)/$(EXECUTABLE): $(OBJECT_FILES) | |
| $(CXX) $(LDFLAGS) $^ -o $@ | |
| all: $(BUILD_DIR)/$(EXECUTABLE) | |
| run: $(BUILD_DIR)/$(EXECUTABLE) | |
| ./$(BUILD_DIR)/$(EXECUTABLE) | |
| clean: | |
| $(RM) -rf $(BUILD_DIR)/ | |
| .PHONY: clean all run |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment