Index

ncurses-minesweeper / master

Terminal game of Minesweeper, implemented in C with ncurses.

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
1112 Sep 2020 16:186caccaaFix issue with Make incorrectly parsing gcc -MMJosh Stockin152G

Blob @ ncurses-minesweeper / Makefile

text/plain3424 bytesdownload raw
1# Preamble >> Make config
2SHELL := bash
3.ONESHELL:
4.SHELLFLAGS := -eu -o pipefail -c
5.DELETE_ON_ERROR:
6MAKEFLAGS += --warn-undefined-variables
7MAKEFLAGS += --no-builtin-rules
8
9ifeq ($(origin .RECIPEPREFIX), undefined)
10 $(error This Make does not support .RECIPEPREFIX. Please use GNU Make 4.0 or later)
11endif
12.RECIPEPREFIX = >
13
14
15# Custom Make settings
16PROJECT_NAME := minesweeper
17
18CC := gcc -std=c11
19CFLAGS := -O3
20CWARNINGS := -Werror -Wall -Wextra -pedantic
21CINCLUDES := -Isrc
22CLIBS := -lncurses
23
24CFORMAT := clang-format -i
25CTIDY := clang-tidy --checks=-*,clang-analyzer-*,-clang-analyzer-cplusplus-*
26
27SOURCE_DIR := src
28BIN_DIR := bin
29
30# Inputs and outputs
31SOURCES := $(shell find $(SOURCE_DIR) -name *.c)
32HEADERS := $(shell find $(SOURCE_DIR) -name *.h)
33OBJECTS := $(patsubst %.c, $(BIN_DIR)/%.o, $(SOURCES))
34OUTFILE := $(BIN_DIR)/$(PROJECT_NAME)
35
36
37# Make target config
38.PHONY: all prelint postlint lint precompile postcompile compile prebuild postbuild build clean run done
39all: lint compile build run done
40
41
42# Automatically create targets and gather their prerequisites
43define create-ctarget
44$1
45> @echo -en "\e[37m[\e[34m?\e[37m]\e[0m $$< \e[36m⇒\e[0m $$@"
46> @mkdir -p $$(dir $$@)
47> @if $(CC) -o $$@ -c $(CFLAGS) $(CWARNINGS) $(CINCLUDES) $$<>/dev/null 2>&1;
48> @then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m";
49> @else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m";
50> @$(CC) -o $$@ -c $(CFLAGS) $(CWARNINGS) $(CINCLUDES) $$<;
51> @fi
52endef
53
54compile: precompile $(OBJECTS) postcompile
55precompile:
56> @echo -e "\e[1m\e[35mCOMPILING\e[0m"
57postcompile:
58> @echo -e "\e[94mDone compiling\e[0m\n"
59_MM_BACKSLASH := $\\
60$(foreach src,$(SOURCES),$(eval $(call create-ctarget,$(filter-out ${_MM_BACKSLASH},$(shell $(CC) -MM -MT $(patsubst %.c, $(BIN_DIR)/%.o, $(src)) $(src))))))
61
62
63# Link and build outfile
64build: prebuild $(OUTFILE) postbuild
65prebuild:
66> @echo -e "\e[1m\e[35mLINKING\e[0m"
67postbuild:
68> @echo -e "\e[94mDone linking\e[0m\n"
69$(OUTFILE): $(OBJECTS)
70> @echo -en "\e[37m[\e[34m?\e[37m]\e[0m $^ \e[36m⇒\e[0m $@"
71> @mkdir -p $(dir $@)
72> @if $(CC) -o $@ $^ $(CLIBS)>/dev/null 2>&1;
73> @then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m";
74> @else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m";
75> @$(CC) -o $@ $^ $(CLIBS);
76> @fi
77
78done:
79> @echo -e "\e[1m\e[48;5;28m\e[37mDone!\e[0m"
80
81
82# Run outfile
83run: $(OUTFILE)
84> @echo -e "\e[1m\e[93m=== [ PROGRAM OUTPUT ] ===\e[0m"
85> $(OUTFILE)
86> @echo -e "\e[1m\e[93m==========================\e[0m\n"
87
88
89# Create linter targets for source and header files
90define create-linttarget
91$1
92> @echo -en "\e[37m[\e[34m?\e[37m]\e[0m $$<"
93> @if ! $(CFORMAT) $$<>/dev/null 2>&1;
94> @then echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m";
95> @$(CFORMAT) $$<;
96> @fi;
97> @if $(CTIDY) $$<>/dev/null 2>&1;
98> @then echo -e "\r\e[37m[\e[32m✓\e[37m]\e[0m";
99> @else echo -e "\r\e[37m[\e[31m✗\e[37m]\e[0m";
100> @$(CTIDY) $$<;
101> @fi;
102> @mkdir -p $$(dir $$@)
103> @touch $$@
104endef
105
106# Translate %.(c|h) to bin/%.(c|h)l and create targets for their sources
107$(foreach src,$(SOURCES),$(eval $(call create-linttarget,$(patsubst %.c, $(BIN_DIR)/%.cl, $(src)): $(src))))
108$(foreach header,$(HEADERS),$(eval $(call create-linttarget,$(patsubst %.h, $(BIN_DIR)/%.hl, $(header)): $(header))))
109
110lint: prelint $(patsubst %.h, $(BIN_DIR)/%.hl, $(HEADERS)) $(patsubst %.c, $(BIN_DIR)/%.cl, $(SOURCES)) postlint
111prelint:
112> @echo -e "\e[1m\e[35mLINTING\e[0m"
113postlint:
114> @echo -e "\e[94mDone linting\e[0m\n"
115
116
117# Clean target
118clean:
119> @rm -r $(BIN_DIR)
120