Download Makefile source code

# 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 $@