# Mark the fence makefile v1.0 # Variables ===================================== # Compiler options CC=cc CXX=g++ FLAGS=-Wall -Wextra -std=gnu11 CFLAGS=$(FLAGS) CXXFLAGS=$(FLAGS) LIBS=-pthread -lm # Configure flags according to the target debug: FLAGS += -g release: FLAGS += -O3 -DNDEBUG # Directories BIN_DIR=bin BUILD_DIR=build DOC_DIR=doc SRC_DIR=src TEST_DIR=test TEST_OUT_DIR=$(BUILD_DIR)/$(TEST_DIR) INST_DIR=$(HOME)/bin # Project variables APP_NAME=fence EXECUTABLE=$(BIN_DIR)/$(APP_NAME) # Files and test cases HEADERS=$(wildcard $(SRC_DIR)/*.h) SOURCES=$(wildcard $(SRC_DIR)/*.c*) OBJECTS=$(SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) # Test cases input are arguments, not stdin TESTS_IN=$(wildcard $(TEST_DIR)/input*.txt) TESTS_OUT=$(TESTS_IN:$(TEST_DIR)/output%.txt=$(TEST_OUT_DIR)/output%.txt) # Building ====================================== # Default rule is debug target debug: $(EXECUTABLE) release: $(EXECUTABLE) # All targets all: debug doc test # Linker call $(EXECUTABLE): $(OBJECTS) | $(BIN_DIR) $(CXX) $(CFLAGS) -o $@ $^ $(LIBS) # Compile C source into .o object file $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(HEADERS) | $(BUILD_DIR) $(CC) -c $(CFLAGS) $< -o $@ # Compile C++ source into .o object file $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp $(HEADERS) | $(BUILD_DIR) $(CXX) -c $(CXXFLAGS) $< -o $@ # Documentation .PHONY: doc | $(DOC_DIR) doc: doxygen Doxyfile # Testing ======================================= # $(shell dirname `pwd`) # Function to test files args###.txt output###.csv error###.csv # 1 2 # $(call run_test, test000-arg.txt, test000-out.csv) run_test = cd $(TEST_DIR) ;\ ../$(EXECUTABLE) $(shell cat $(TEST_DIR)/$(1)) > ../$(TEST_OUT_DIR)/$(2) 2> ../$(TEST_OUT_DIR)/$(subst out,err,$(2)) || true ;\ cd .. ;\ $(HOME)/bin/icdiff $(TEST_DIR)/$(2) $(TEST_OUT_DIR)/$(2) || true ;\ $(HOME)/bin/icdiff $(TEST_DIR)/$(subst out,err,$(2)) $(TEST_OUT_DIR)/$(subst out,err,$(2)) || true ;\ rm -f $(TEST_OUT_DIR)/$(2) $(TEST_OUT_DIR)/$(subst out,err,$(2)) ;\ $(eval testcnt=$(shell echo $$(($(testcnt)+1)))) # Testing .PHONY: test test: debug $(TESTS_OUT) | $(TEST_OUT_DIR) @echo "$(testcnt) ascii cases tested" .PHONY: $(TEST_OUT_DIR)/%-out.csv $(TEST_OUT_DIR)/%-out.csv: $(TEST_DIR)/%-arg.txt | icdiff $(call run_test,$(shell basename $<),$(shell basename $@)) # Misc ========================================== # Remove output directories .PHONY: clean clean: rm -rf $(BIN_DIR) $(BUILD_DIR) $(DOC_DIR) # Install a copy of the executable in ~/bin install: release | $(INST_DIR) cp -p $(EXECUTABLE) $(INST_DIR) # Uninstall the copy of the executable in ~/bin .PHONY: uninstall uninstall: rm -f $(INST_DIR)/$(APP_NAME) # Directories =================================== # Rules for creating output directories $(BIN_DIR): mkdir -p $@ $(BUILD_DIR): mkdir -p $@ $(TEST_OUT_DIR): mkdir -p $@ $(TEST_U_OUT_DIR): mkdir -p $@ $(INST_DIR): mkdir -p $@ # 3rd party ===================================== icdiff: $(HOME)/bin/icdiff $(HOME)/bin/icdiff: mkdir -p $(HOME)/bin wget -q https://raw.githubusercontent.com/jeffkaufman/icdiff/release-1.9.2/icdiff -O $@ chmod +x $@