-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathMakefile.common
248 lines (198 loc) · 6.95 KB
/
Makefile.common
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#
# Common makefile for Phoenix-RTOS 3
#
# Copyright 2020 Phoenix Systems
#
# %LICENSE%
#
# set SIL to "" for verbose output
SIL ?= @
# function - returns the directory of the current Makefile
my-dir = $(dir $(lastword $(MAKEFILE_LIST)))
MAKES_PATH := $(abspath $(call my-dir))/makes
#
# setup basic variables
#
TARGET_FAMILY ?= $(firstword $(subst -, ,$(TARGET)-))
TARGET_SUBFAMILY ?= $(word 2,$(subst -, ,$(TARGET)-))
# reset env variables
CFLAGS := # flags related to C files compilation
CXXFLAGS := # flags related to C++ files compilation
CPPFLAGS := # flags for C preprocessor (C & C++)
LDFLAGS :=
LDFLAGS_PREFIX :=
# supported languages
LANGUAGE_EXTENSIONS := %.c %.cc %.cpp
# specific "-Ox" flag can be set globally for project by setting OLVL variable
ifneq ($(filter-out -O%,$(OLVL)),)
$(error OLVL set but does not provide optimisation flags)
endif
ifneq ($(DEBUG), 1)
CPPFLAGS += -DNDEBUG
WATCHDOG ?= 1
else
WATCHDOG ?= 0
endif
TOPDIR := $(CURDIR)
PREFIX_BUILD ?= ../_build/$(TARGET)
PREFIX_BUILD := $(abspath $(PREFIX_BUILD))
BUILD_DIR ?= $(PREFIX_BUILD)/$(notdir $(TOPDIR))
BUILD_DIR := $(abspath $(BUILD_DIR))
# build artifacts dir
CURR_SUFFIX := $(patsubst $(TOPDIR)/%,%,$(abspath $(CURDIR))/)
PREFIX_O := $(BUILD_DIR)/$(CURR_SUFFIX)
# target install paths, can be provided exterally
PREFIX_A ?= $(PREFIX_BUILD)/lib/
PREFIX_H ?= $(PREFIX_BUILD)/include/
PREFIX_PROG ?= $(PREFIX_BUILD)/prog/
PREFIX_PROG_STRIPPED ?= $(PREFIX_BUILD)/prog.stripped/
ALL_COMPONENTS :=
# default rootfs prefixes
PREFIX_FS ?= $(abspath $(CURDIR)/../_fs/$(TARGET))
PREFIX_ROOTFS ?= $(PREFIX_FS)/root/
# Check TARGET, set TARGET_SUFF and include target building options
include $(MAKES_PATH)/include-target.mk
# setup tools and sysroot
include $(MAKES_PATH)/setup-tools.mk
include $(MAKES_PATH)/setup-sysroot.mk
# add utility functions
include $(MAKES_PATH)/funcs.mk
# provide template files' paths to external makes
binary.mk := $(MAKES_PATH)/binary.mk
static-lib.mk := $(MAKES_PATH)/static-lib.mk
# default path for the programs to be installed in rootfs
DEFAULT_INSTALL_PATH := /bin
# do not clean and build in parallel
ifneq ($(filter %clean,$(MAKECMDGOALS)),)
$(info cleaning targets, make parallelism disabled)
.NOTPARALLEL:
endif
# Do not warn about RWX segments.
# binutils >= 2.39 required
LD_VERSION_MINOR := $(shell $(LD) $(LDFLAGS_PREFIX)--version 2> /dev/null | grep -Eo "\b2\.[0-9]*" | cut -d . -f 2)
ifeq ($(LD_VERSION_MINOR),)
$(error Can't parse LD version!)
else ifeq ($(shell expr $(LD_VERSION_MINOR) ">=" 39), 1)
LDFLAGS += $(LDFLAGS_PREFIX)--no-warn-rwx-segments
endif
#
# generic *FLAGS options
#
# common include/lib paths
LDFLAGS += -L$(PREFIX_A)
ifneq ($(KERNEL), 1)
CFLAGS += -I$(PREFIX_H)
CXXFLAGS += -I$(PREFIX_H)
endif
# make PROJECT_PATH the first search dir to allow project customizations/monkey-patching
ifneq ($(PROJECT_PATH),)
CFLAGS := -I$(PROJECT_PATH) $(CFLAGS)
CXXFLAGS := -I$(PROJECT_PATH) $(CXXFLAGS)
endif
ifeq ($(HAVE_MMU), n)
CPPFLAGS += -DNOMMU
endif
# remove local dev path from macros
CFLAGS += -fmacro-prefix-map=$(dir $(TOPDIR))=
CXXFLAGS += -fmacro-prefix-map=$(dir $(TOPDIR))=
# garbage-collect unused code/data
# NOTE: exported to ports also as it reduces binaries size greatly
CFLAGS += -ffunction-sections -fdata-sections
LDFLAGS_GC_SECTIONS ?= $(LDFLAGS_PREFIX)--gc-sections
LDFLAGS += $(LDFLAGS_GC_SECTIONS)
LDFLAGS_WHOLE_ARCHIVE_BEGIN ?= $(LDFLAGS_PREFIX)--whole-archive
LDFLAGS_WHOLE_ARCHIVE_END ?= $(LDFLAGS_PREFIX)--no-whole-archive
### right now we should have only target-necessary flags, save them for exporting (for building ports) ###
EXPORT_CFLAGS := $(CFLAGS)
EXPORT_CXXFLAGS := $(CXXFLAGS)
EXPORT_LDFLAGS := $(LDFLAGS)
# add our coding-style related options
CFLAGS += -Wall -Wstrict-prototypes -fno-common
CXXFLAGS += -Wall
LDFLAGS += -z noexecstack
# Messages are commonly type-punned - avoid GCC optimizations that might break if strict aliasing rules are not adhered to.
# TODO: Try to minimize surface of code breaking the strict aliasing.
CFLAGS += -fno-strict-aliasing
CXXFLAGS += -fno-strict-aliasing
# always produce binaries with debug information
CFLAGS += -ggdb3
CXXFLAGS += -ggdb3
# set optimization level (target/project-dependant)
CFLAGS += $(OLVL)
CXXFLAGS += $(OLVL)
# Distribute the __TARGET and __CPU defines
CPPFLAGS += -D__TARGET_$(call uppercase,$(TARGET_FAMILY))
CPPFLAGS += -D__CPU_$(call uppercase,$(TARGET_SUBFAMILY))
ifneq ($(WATCHDOG), 0)
CPPFLAGS += -DWATCHDOG
endif
# check if the final build environment is sane
ifeq ($(NOCHECKENV),)
include $(MAKES_PATH)/check-env.mk
endif
#
# Generic rules
#
.PHONY: help export-cflags export-cxxflags export-ldflags
export-cflags:
@echo $(EXPORT_CFLAGS)
export-cxxflags:
@echo $(EXPORT_CXXFLAGS)
export-ldflags:
@echo $(EXPORT_LDFLAGS)
export-strip:
@echo $(STRIP)
help:
$(info DEFAULT_COMPONENTS := $(DEFAULT_COMPONENTS))
$(info ALL_COMPONENTS := $(ALL_COMPONENTS))
@echo
@echo "available generic make targets:"
@echo " all build DEFAULT_COMPONENTS"
@echo " install install DEFAULT_COMPONENTS into PREFIX_ROOTFS"
@echo " clean clean ALL_COMPONENTS"
@echo " export-cflags outputs contents of CFLAGS variable"
@echo " export-cxxflags outputs contents of CXXFLAGS variable"
@echo " export-ldflags outputs contents of LDFLAGS variable"
@echo " export-strip outputs contents of STRIP variable"
@echo
@echo "available per-target make targets:"
@echo " <target> build <target>"
@echo " <target>-install install <target> into PREFIX_ROOTFS"
@echo " <target>-clean clean <target>"
@echo " <target>-headers install <target> headers into staging"
#
# Predefined and pattern rules
#
ARCH = $(SIL)@mkdir -p $(@D); \
printf "AR %-24s\n" "$(@F)"; \
$(AR) $(ARFLAGS) $@ $^ 2>/dev/null
# --whole-archive is needed for linker to always find constructors in .a files
LINK = $(SIL)mkdir -p $(@D); \
printf "LD %-24s\n" "$(@F)"; \
$(LD) $(CFLAGS) $(LDFLAGS) -o "$@" $(LDFLAGS_WHOLE_ARCHIVE_BEGIN) $^ $(LDFLAGS_WHOLE_ARCHIVE_END) $(LDLIBS)
HEADER = $(SIL)mkdir -p $(@D); \
printf "HEADER %-24s\n" "$<"; \
cp -pR "$<" "$@"
INSTALL_FS = $(SIL)printf "INSTALL %s\n" "$(@:$(PREFIX_ROOTFS)%=%)"; \
mkdir -p "$(@D)"; \
cp -pR "$<" "$(@D)"
$(PREFIX_O)%.o: %.c
@mkdir -p $(@D)
@printf "CC %-24s\n" "$<"
$(SIL)$(CC) -c $(CPPFLAGS) $(CFLAGS) "$(abspath $<)" -o "$@" -MD -MP -MF $(PREFIX_O)$*.c.d -MT "$@"
$(PREFIX_O)%.o: %.cc
@mkdir -p $(@D)
@printf "CXX %-24s\n" "$<"
$(SIL)$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) "$(abspath $<)" -o "$@" -MD -MP -MF $(PREFIX_O)$*.cc.d -MT "$@"
$(PREFIX_O)%.o: %.cpp
@mkdir -p $(@D)
@printf "CXX %-24s\n" "$<"
$(SIL)$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) "$(abspath $<)" -o "$@" -MD -MP -MF $(PREFIX_O)$*.cpp.d -MT "$@"
$(PREFIX_O)%.o: %.S
@mkdir -p $(@D)
@printf "ASM %-24s\n" "$<"
$(SIL)$(CC) -c $(CPPFLAGS) $(CFLAGS) "$(abspath $<)" -o "$@" -MD -MP -MF $(PREFIX_O)$*.S.d -MT "$@"
$(PREFIX_PROG_STRIPPED)%: $(PREFIX_PROG)%
@mkdir -p $(@D)
@printf "STR %-24s\n" "$(@F)"
$(SIL)$(STRIP) -o $@ $<