-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.mk
126 lines (87 loc) · 3.05 KB
/
build.mk
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
# All objects.
OBJECTS ?= \
src/main.o \
# more files
# Where to place object files and the final executable
BUILD_DIR ?= build
# Name of the executable, within $(BUILD_DIR)
EXE ?= main
# A list of packages passed to `pkg-config`. If empty, `pkg-config` will not be invoked.
PACKAGES ?= # openssl
# Include directory flags.
INCLUDES ?= # -Iinclude/
# `c2x` because everybody deserves separators within numeric literals
CSTANDARD ?= -std=c2x
CXXSTANDARD ?= -std=c++20
EXPORT_COMPILE_COMMANDS ?= yes
# Warnings.
WARNINGS ?= -Wall -Wextra -Wmissing-prototypes
# Optimization flags.
OPTFLAGS ?= -O0 -g # -O3
# Flags that need to be used during both compilation and linking.
CODEGENFLAGS ?= -fsanitize=undefined -fsanitize=address
# All flags passed to the C compiler to compile both C and C++ files.
CCFLAGS ?= -MMD
CCFLAGS += $(INCLUDES)
CCFLAGS += $(WARNINGS)
CCFLAGS += $(OPTFLAGS)
CCFLAGS += $(CODEGENFLAGS)
# Flags passed for C or C++ files, respectively.
CFLAGS += $(CCFLAGS)
CFLAGS += $(CSTANDARD)
CXXFLAGS += $(CCFLAGS)
CXXFLAGS += $(CXXSTANDARD)
# The C compiler used to link this project.
# Set this to $(CXX) if you're writing a C++ project.
CC_LINK ?= $(CC)
# Flags passed to the C compiler to link all object files together into the final executable.
LDFLAGS ?= # -L/usr/lib64/
LDFLAGS += $(CODEGENFLAGS)
ifneq ($(PACKAGES),)
CFLAGS += $(shell pkg-config --cflags $(PACKAGES))
CXXFLAGS += $(shell pkg-config --cflags $(PACKAGES))
LDFLAGS += $(shell pkg-config --libs $(PACKAGES))
endif
MKDIR_P ?= mkdir -p
OBJECTS := $(OBJECTS:%=$(BUILD_DIR)/%)
all: $(BUILD_DIR)/$(EXE) $(BUILD_DIR)/compile_commands.json
ifeq ($(EXPORT_COMPILE_COMMANDS),yes)
all: $(BUILD_DIR)/compile_commands.json
$(BUILD_DIR)/compile_commands.json: $(OBJECTS:%.o=%.compile_commands.json)
@printf "Exporting %s\n" "$@"
( echo "["; cat $^; echo "]" ) > $@
endif
$(BUILD_DIR)/$(EXE): $(OBJECTS)
@printf "Linking %s\n" "$@"
@$(MKDIR_P) $(@D)
$(CC_LINK) $^ -o $@ $(LDFLAGS)
# Note: leaves directory structure in place.
clean:
rm -f $(OBJECTS)
rm -f $(OBJECTS:%.o=%.d)
rm -f $(OBJECTS:%.o=%.compile_commands.json)
rm -f $(BUILD_DIR)/compile_commands.json
rm -f $(BUILD_DIR)/$(EXE)
.PHONY: clean
# Include all `.d` files, ignoring those that don't exist.
-include $(OBJECTS:%.o=%.d)
# Header files are added as prerequisites by the dependency files (included
# above), but if they don't exist Make looks for a rule to generate them. Add a
# dummy rule so that Make doesn't fail when it can't find those files.
%.h: ;
$(BUILD_DIR)/%.o $(BUILD_DIR)/%.compile_commands.json: %.c
@printf "Compiling %s\n" "$<"
@$(MKDIR_P) $(@D)
ifeq ($(EXPORT_COMPILE_COMMANDS),yes)
$(CC) -c $< -o $(BUILD_DIR)/$*.o $(CFLAGS) -MJ $(BUILD_DIR)/$*.compile_commands.json
else
$(CC) -c $< -o $(BUILD_DIR)/$*.o $(CFLAGS)
endif
$(BUILD_DIR)/%.o $(BUILD_DIR)/%.compile_commands.json: %.cpp
@printf "Compiling %s\n" "$<"
@$(MKDIR_P) $(@D)
ifeq ($(EXPORT_COMPILE_COMMANDS),yes)
$(CXX) -c $< -o $(BUILD_DIR)/$*.o $(CXXFLAGS) -MJ $(BUILD_DIR)/$*.compile_commands.json
else
$(CXX) -c $< -o $(BUILD_DIR)/$*.o $(CXXFLAGS)
endif