diff --git a/Q6-cache/Makefile b/Q6-cache/Makefile index 54d8fc1..b957f78 100644 --- a/Q6-cache/Makefile +++ b/Q6-cache/Makefile @@ -1,32 +1,120 @@ -SHELL := /bin/bash +# +# Makefile +# +# Copyright (C) 2020 Christos Choutouridis +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see . +# -###################################################################### -### EXECUTABLES +# ========== Project settings ========== +TARGET := matmul +SRC_DIR := src +INC_DIR := +EXC_FILE := -CC = gcc -FLAGS = -O3 -Wall -std=gnu99 -RM = rm -rf -LINK = -lm +# build directories +BUILD_DIR := bin +OBJ_DIR := $(BUILD_DIR)/obj +DEP_DIR := $(BUILD_DIR)/.dep -###################################################################### -### TARGET FILES +# ========== Compiler settings ========== +CXX := gcc +CPP := gcc -E +CSIZE := size -MAIN = matmul +CFLAGS := -std=gnu99 -Wall -Wextra +DEB_FLAGS := -DDEBUG -g3 +REL_FLAGS := -O3 +LDFLAGS := -lm -###################################################################### -### CLEAN-UP FILES +PRE_DEFS := -FILES_CLEAN = $(MAIN) *~ +# +# =========== Main body and Patterns =========== +# +INC := $(foreach dir,$(INC_DIR),-I$(dir)) +DEF := $(foreach def,$(PRE_DEFS),-D$(def)) -###################################################################### -### COMMANDS -- ! DO NOT CHANGE BELOW ! +# source files +# recursive search into current and source directories +SRC := $(wildcard *.c) +SRC += $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c)) +SRC += $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/**/*.c)) +# exclude every file from the exclude file list +SRC := $(filter-out $(wildcard $(EXC_FILE)),$(SRC)) -all: $(MAIN) +OBJ := $(foreach file,$(SRC:%.c=%.o),$(OBJ_DIR)/$(file)) +DEP := $(foreach file,$(SRC:%.c=%.d),$(DEP_DIR)/$(file)) -$(MAIN): $(MAIN).c - $(CC) $(FLAGS) $(DEFS) $^ -o $@ $(LINK) +# Make Dependencies pattern. +# This little trick enables recompilation only when dependencies change +# and it does so for changes both in source AND header files ;) +# +# It is based on Tom Tromey's method. +# +# Invoke cpp to create makefile rules with dependencies for each source file +$(DEP_DIR)/%.d: %.c + @mkdir -p $(@D) + @$(CPP) $(CFLAGS) $(INC) $(DEF) -MM -MT $(OBJ_DIR)/$(<:.c=.o) -MF $@ $< + + +# objects depent on .c AND dependency files, which have an empty recipe +$(OBJ_DIR)/%.o: %.c $(DEP_DIR)/%.d + @mkdir -p $(@D) + $(CXX) -c $(CFLAGS) $(INC) $(DEF) -o $@ $< + +# empty recipe for dependency files. This prevents make errors +$(DEP): + +# now include all dependencies +# After all they are makefile dependency rules ;) +include $(wildcard $(DEP)) + +# main target rule +$(BUILD_DIR)/$(TARGET): $(OBJ) + @mkdir -p $(@D) + @echo Linking to target: $(TARGET) + @echo $(CXX) $(LDFLAGS) -o $(@D)/$(TARGET) '$$(OBJ)' + @$(CXX) $(LDFLAGS) -o $(@D)/$(TARGET) $(OBJ) + @echo + @echo Print size information + @$(CSIZE) $(@D)/$(TARGET) + @echo Done + + +.PHONY: clean clean: - $(RM) $(FILES_CLEAN) *.o *~ + @echo Cleaning build directories + @rm -rf $(OBJ_DIR) + @rm -rf $(DEP_DIR) + @rm -rf $(BUILD_DIR) + +# +# ============ User Rules ============= +# + +.PHONY: debug +debug: CFLAGS += $(DEB_FLAGS) +debug: $(BUILD_DIR)/$(TARGET) + + +.PHONY: release +release: CFLAGS += $(REL_FLAGS) +release: clean $(BUILD_DIR)/$(TARGET) + + +.PHONY: all +all: clean release -.PHONY: $(MAIN) diff --git a/Q6-cache/matmul.c b/Q6-cache/src/matmul.c similarity index 100% rename from Q6-cache/matmul.c rename to Q6-cache/src/matmul.c