-
Notifications
You must be signed in to change notification settings - Fork 3
/
Makefile
127 lines (115 loc) · 2.7 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
115
116
117
118
119
120
121
122
123
124
125
126
127
# Variables from config.mk:
# TARGET: compilation target
#
# TOOLCHAIN: prefix for toolchain: TOOLCHAIN=aarch64-linux-gnu-
# COMPILER: what compiler to use
# default: $(CC) for EXT=.c, $(CXX) for EXT=.cc
#
# FILES: list of input files
# default: all files with extension $(EXT) in $(SRC)
# EXT: file extension
# default: .c
# SRC: directory with source files (only applies if you don't specify FILES)
# default: src
#
# FLAGS: general flags
# FLAGS_DBG: flags included only when running $(TARGET)-debug
# default: -g -o0 -DDEBUG
# FLAGS_NDBG: flags included only when not running $(TARGET)-debug
#
# WARN: warning flags
# default: all pedantic
# LINK: libraries to dynamically link with
# INCLUDE: include directories
# LIBS: libraries to statically link with: libfoo.a
#
# DEPS: additional targets to run before the $(TARGET) step
# JUNK: additional files to be cleaned by the clean target
include config.mk
#
# Defaults
#
ifeq ($(WARN),)
WARN=all pedantic
endif
ifeq ($(FLAGS_DBG),)
FLAGS_DBG=-g -o0 -DDEBUG
endif
ifeq ($(EXT),)
EXT=.c
endif
ifeq ($(SRC),)
SRC=src
endif
ifeq ($(FILES),)
FILES=$(shell find $(SRC) -name '*$(EXT)' | sed 's/^.\///')
endif
ifeq ($(COMPILER),)
ifeq ($(EXT),.cc)
COMPILER=$(CXX)
else
COMPILER=$(CC)
endif
endif
COMPILER:=$(TOOLCHAIN)$(COMPILER)
#
# Find .o and .d files
#
OFILES=$(patsubst %$(EXT),obj/$(TARGET)/%.o,$(FILES))
DFILES=$(patsubst %$(EXT),dep/$(TARGET)/%.d,$(FILES))
#
# Create FLAGS based on a bunch of variables
#
FLAGS:=$(FLAGS) \
$(patsubst %,-W%,$(WARN)) \
$(patsubst %,-I%,$(INCLUDE))
ifeq ($(EXT),.cc)
FLAGS:=$(FLAGS) $(CXXFLAGS)
else
FLAGS:=$(FLAGS) $(CFLAGS)
endif
ifeq ($(DEBUG),1)
FLAGS:=$(FLAGS) $(FLAGS_DBG)
else
FLAGS:=$(FLAGS) $(FLAGS_NDBG)
endif
FLAGS:=$(strip $(FLAGS))
LINK:=$(patsubst %,-l%,$(LINK))
#
# Compile the binary
#
$(TARGET): $(LIBS) $(OFILES)
$(COMPILER) -o $(TARGET) $(OFILES) $(LIBS) $(FLAGS) $(LINK)
#
# Cleanup
#
clean:
echo cleaning
rm -rf obj dep
rm -f $(TARGET) $(JUNK)
#
# Create .d files
#
dep/$(TARGET)/%.d: %$(EXT)
@mkdir -p $(@D)
@printf $(dir obj/$(TARGET)/$*) > $@
@# Generate deps and write to file. If creating deps fails
@# ((e.g an #include which refers to a file which doesn't exist),
@# remove the dep file. The `&& break` is to make the build still
@# fail; `rm $@` returns exit code 0.
@$(COMPILER) $(FLAGS) -MM $< -o - >> $@ || rm -f "$@" && break
#
# Include .d files if we're not in make clean
# We're not using a single make.dep file, because we only know the
# source files, not the headers.
#
ifneq ($(MAKECMDGOALS),clean)
-include $(DFILES)
endif
#
# Create .o files
#
obj/$(TARGET)/%.o: %$(EXT) dep/$(TARGET)/%.d
@mkdir -p $(@D)
$(COMPILER) $(FLAGS) -o $@ -c $<
.PHONY: clean