1 | # Preamble >> Make config |
2 | SHELL := bash |
3 | .ONESHELL: |
4 | .SHELLFLAGS := -eu -o pipefail -c |
5 | .DELETE_ON_ERROR: |
6 | MAKEFLAGS += --warn-undefined-variables |
7 | MAKEFLAGS += --no-builtin-rules |
8 |
|
9 | ifeq ($(origin .RECIPEPREFIX), undefined) |
10 | $(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later) |
11 | endif |
12 | .RECIPEPREFIX = > |
13 |
|
14 |
|
15 | # Compiler settings |
16 | CC := gcc -std=c11 |
17 | CFLAGS := -O3 |
18 | CWARNINGS := -Werror -Wall -Wextra -pedantic |
19 | CINCLUDES := -Isrc |
20 | CLIBS := -lncurses |
21 | CLINT := --syntax-only |
22 |
|
23 | SOURCE_DIR := src |
24 | BIN_DIR := bin |
25 | SOURCES := $(wildcard $(SOURCE_DIR)/*.c) |
26 | HEADERS := $(wildcard $(SOURCE_DIR)/*.h) |
27 | OBJECTS := $(patsubst %.c, $(BIN_DIR)/%.o, $(SOURCES)) |
28 | OUTFILE := $(BIN_DIR)/minesweeper |
29 |
|
30 | .PHONY: all lint clean |
31 | all: build |
32 |
|
33 |
|
34 | # Automatically create targets and gather their prerequisites |
35 | define create-ctarget |
36 | $1 |
37 | > @echo -en "\e[37m[\e[34m?\e[37m]\e[0m $$< \e[36m⇒\e[0m $$@" |
38 | > @mkdir -p $$(dir $$@) |
39 | > @sleep 1 |
40 | > @if $(CC) -o $$@ -c $(CFLAGS) $(CWARNINGS) $(CINCLUDES) $$<>/dev/null 2>&1; |
41 | > @then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m"; |
42 | > @else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m"; |
43 | > @$(CC) -o $$@ -c $(CFLAGS) $(CWARNINGS) $(CINCLUDES) $$<; |
44 | > @fi |
45 | endef |
46 |
|
47 | compile: precompile $(OBJECTS) postcompile |
48 | precompile: |
49 | > @echo -e "\e[1m\e[35mCOMPILING\e[0m" |
50 | postcompile: |
51 | > @echo -e "\e[94mDone compiling\e[0m\n" |
52 | $(foreach src,$(SOURCES),$(eval $(call create-ctarget,$(shell $(CC) -MM -MT $(patsubst %.c, $(BIN_DIR)/%.o, $(src)) $(src))))) |
53 |
|
54 |
|
55 | # Link and build outfile |
56 | build: compile $(OUTFILE) done |
57 | $(OUTFILE): $(OBJECTS) |
58 | > @echo -e "\e[1m\e[35mLINKING\e[0m" |
59 | > @echo -en "\e[37m[\e[34m?\e[37m]\e[0m $^ \e[36m⇒\e[0m $@" |
60 | > @sleep 1; |
61 | > @mkdir -p $(dir $@) |
62 | > @if $(CC) -o $@ $^ $(CLIBS)>/dev/null 2>&1; |
63 | > @then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m"; |
64 | > @else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m"; |
65 | > @$(CC) -o $@ $^ $(CLIBS); |
66 | > @fi |
67 | > @echo -e "\e[94mDone linking\e[0m\n" |
68 | done: |
69 | > @echo -e "\e[1m\e[48;5;28m\e[37mDone!\e[0m" |
70 |
|
71 |
|
72 | # Lint |
73 | lint: $(SOURCES) $(HEADERS) |
74 | > @echo -e "\e[1m\e[35mLINTING\e[0m" |
75 | > @$(foreach src,$^,echo -en "\e[37m[\e[34m?\e[37m]\e[0m $(src)";sleep 1;if $(CC) $(CLINT) $(CWARNINGS) $(CINCLUDES) $(src)>/dev/null 2>&1;then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m";else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m";$(CC) $(CLINT) $(CWARNINGS) $(CINCLUDES) $(src);fi;) |
76 | > @echo -e "\e[94mDone linting\e[0m\n" |
77 |
|
78 |
|
79 | # Clean |
80 | clean: |
81 | > @rm -r $(BIN_DIR) |
82 |
|