-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMakefile
114 lines (92 loc) · 2.6 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
CC ?= gcc
TARGET ?= ljc
CDIR ?= src/lovejoy
ODIR ?= o
DDIR ?= d
OBJS := $(patsubst $(CDIR)/%.c,$(ODIR)/%.o,$(wildcard $(CDIR)/*.c))
DEPS := $(patsubst $(CDIR)/%.c,$(DDIR)/%.d,$(wildcard $(CDIR)/*.c))
OPT ?= -O3
WARN := -Wall -Wpedantic -Wextra -Wshadow
LINKS :=
INCLUDES := -Isrc
OPTIONS := -funsigned-char -std=gnu11
DEPFLAGS = -MT $@ -MMD -MP -MF $(DDIR)/$(*F).d
CFLAGS += $(DEPFLAGS) $(WARN) $(OPTIONS) $(OPT) $(INCLUDES)
ifeq ($(CC),clang)
WARN += -Wno-gnu-zero-variadic-macro-arguments -Wno-language-extension-token
OPTIONS += -fms-extensions
endif
ifeq ($(CC),gcc)
OPTIONS += -fplan9-extensions
endif
ifeq ($(OPT),-O0)
OPTIONS += -finline-functions
endif
MAIN := $(ODIR)/bin.o
TESTS_MAIN := $(ODIR)/tests.o
NOW := $(shell date +%s.%N) # Eager.
END = $(shell date +%s.%N) # Lazy.
TIME = $(shell dc -e "20 k $(END) $(NOW) - 1000 * p")
ifeq ($(PREFIX),)
PREFIX := /usr/local
endif
bold := $(shell tput bold)
dim := $(shell tput dim)
r := $(shell tput sgr0)
begin_command := @printf "$(dim)> "
end_command := @printf "$(r)"
all: pre-build $(TARGET)
$(eval T := $(TIME))
@printf "$(bold)\nBuild success:$(r) \`$(TARGET)\`.\n"
@printf "$(bold)Took:$(r) %g ms.\n" "$(T)"
clean:
@echo "[~] Cleaning last build."
$(begin_command)
rm -f ./$(TARGET) ./$(TARGET)_test
$(end_command)
$(begin_command)
rm -fr ./$(ODIR)/ ./$(DDIR)/
$(end_command)
$(ODIR):
@mkdir $@
@echo "[~] Making object directory: $@/"
$(DDIR):
@mkdir $@
@echo "[~] Making dependency directory: $@/"
pre-build: $(ODIR) $(DDIR)
test: pre-build $(ODIR)/tests.o
$(eval T := $(TIME))
$(begin_command)
$(CC) $(OPT) -o $(TARGET)_test $(OBJS) $(TESTS_MAIN) $(LINKS)
$(end_command)
@printf "$(bold)\nBuild for tests succeeded:$(r) \`$(TARGET)_test\`.\n"
@printf "$(bold)Took:$(r) %g ms.\n" "$(T)"
$(TARGET): $(MAIN)
@echo "$(bold)Building target.$(r)"
$(begin_command)
$(CC) $(OPT) -o $(TARGET) $(OBJS) $(MAIN) $(LINKS)
$(end_command)
install: $(TARGET)
@echo "Installing to $(PREFIX)/bin/$(TARGET)."
$(begin_command)
install -d $(PREFIX)/bin
$(end_command)
$(begin_command)
install -m 755 $(TARGET) $(PREFIX)/bin
$(end_command)
$(MAIN): src/bin.c $(OBJS)
@echo "$(bold)Building main.$(r)"
$(begin_command)
$(CC) $(CFLAGS) -c src/bin.c -o $@ $(LINKS)
$(end_command)
$(ODIR)/tests.o: src/tests.c $(OBJS)
@echo "$(bold)Building tests.$(r)"
$(begin_command)
$(CC) $(CFLAGS) -c src/tests.c -o $@ $(LINKS)
$(end_command)
$(ODIR)/%.o: $(CDIR)/%.c $(DDIR)/%.d
@printf "$(bold)Building object file.$(r) %25s -> %13s\n" "$<" "$@"
@$(CC) $(CFLAGS) -c $< -o $@ $(LINKS)
$(DEPS):
include $(wildcard $(DEPS))
.PHONY: all test pre-build clean install