# levdist makefile v2.0
# Variables =====================================
# Compiler options
CC=mpicc
CXX=mpic++
FLAGS=-Wall -Wextra -pthread -std=gnu11 -fopenmp
CFLAGS=$(FLAGS)
CXXFLAGS=$(FLAGS)
LIBS=-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=corr
EXECUTABLE=$(BIN_DIR)/$(APP_NAME)
FILTER_MEMCHECK=| grep 'lost'
# 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_ARG=$(wildcard $(TEST_DIR)/*-arg.txt)
TESTS_OUT=$(TESTS_ARG:$(TEST_DIR)/%-arg.txt=$(TEST_OUT_DIR)/%-out.csv)
TESTS_ERR=$(TESTS_ARG:$(TEST_DIR)/%-arg.txt=$(TEST_OUT_DIR)/%-err.csv)
# 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 $@