-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
301 lines (259 loc) · 10 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
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#########################
#### Custom Options: ####
#########################
# GLUON_RELEASE - customize full release name
# BUILD_NUMBER - customize only the build number of the release name
#########################
# GLUON_TARGETS - choose which targets to build (delimited by spaces) e.g. "ath79-generic ramips-mt7621"
# GLUON_DEVICES - choose which devices to build (delimited by spaces) e.g. "avm-fritz-box-4020 tp-link-tl-wdr4300-v1", moves images to devices/ instead of output/, no packages are copied to the devices/ folder
# BROKEN - set to 0 to disable building devices marked as broken
#########################
# GLUON_PRIORITY - set update priority (integer)
# GLUON_AUTOUPDATER_ENABLED - set to 0 to disable the autoupdater
# GLUON_LANGS - set to subset of (en de fr) to include less languages
#########################
# JOBS - set number of threads manually
# GLUON_DEBUG set to 1 to include debug symbols (requires at least 16MB of flash, advice: also set GLUON_DEVICES, run 'make clean' before executing if you care for all packages to be rebuilt with debug symbols)
# GLUON_MINIFY set to 0 to disable minification of scripts (lua etc.)
#########################
# SECRET_KEY_FILE - Path to your ECDSA signing key
# OPKG_KEY_FOLDER - Path to your OpenWrt package signing key
#########################
## Setup Build environment variables
include release.mk
include targets.mk
GLUON_BUILD_DIR := gluon-build
export GLUON_SITEDIR := ..
PATCH_DIR := patches
SECRET_KEY_FILE ?= $(HOME)/.gluon-secret-key
OPKG_KEY_FOLDER ?= $(HOME)/.key-build
## Create version scheme
EXP_FALLBACK = $(shell date '+%Y%m%d')
BUILD_NUMBER ?= $(EXP_FALLBACK)
GIT_TAG := $(shell git describe --tags 2>/dev/null)
ifeq (,$(GIT_TAG))
ifndef GLUON_RELEASE
$(error Set GLUON_RELEASE or create a git tag)
endif
endif
ifneq (,$(shell git describe --exact-match --tags 2>/dev/null))
GLUON_RELEASE ?= $(GIT_TAG)
else
GLUON_RELEASE ?= $(GIT_TAG)~exp$(BUILD_NUMBER)
endif
export GLUON_RELEASE
## Setup MAKE
JOBS ?= $(shell cat /proc/cpuinfo | grep -c ^processor)
MAKEFLAGS += -j$(JOBS)
MAKEFLAGS += --no-print-directory
MAKEFLAGS += --output-sync
GLUON_MAKE = $(MAKE) -C $(GLUON_BUILD_DIR)
GLUON_GIT = git -C $(GLUON_BUILD_DIR)
## Build strings for INFO
define newline
endef
ifneq (,$(filter GLUON_TARGETS%,$(MAKEOVERRIDES)))
TARGETS_INFO := $(newline)\# for target(s) '$(GLUON_TARGETS)'
endif
ifneq (,$(filter GLUON_DEVICES%,$(MAKEOVERRIDES)))
DEVICE_INFO := $(newline)\# for device(s) '$(GLUON_DEVICES)'
endif
## Info section
define INFO :=
#########################
# FFAC Firmware build
# building release '$(GLUON_RELEASE)'$(TARGETS_INFO)$(DEVICE_INFO)
#########################
# MAKEFLAGS:
# $(MAKEFLAGS)
#########################
# git url: $(GLUON_GIT_URL)
# git ref: $(GLUON_GIT_REF)
#########################
# Found $(shell ls -1 $(PATCH_DIR) 2>/dev/null | wc -l) patches
#########################
endef
# show info section for all make calls except the filtered ones
ifneq (,$(filter-out gluon-clean output-clean clean,$(MAKECMDGOALS)))
$(info $(INFO))
endif
## Prepare folders
$(GLUON_BUILD_DIR):
mkdir -p $(GLUON_BUILD_DIR)
@echo
# Note: "|" means "order only", e.g. "do not care about folder timestamps"
# In other words: call requirement when file/folder doesn't exist instead of when it is outdated.
# e.g. after running gluon-clean but not on every run.
# https://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Prerequisite-Types.html
$(GLUON_BUILD_DIR)/.git: | $(GLUON_BUILD_DIR)
@git init $(GLUON_BUILD_DIR) -b master
@$(GLUON_GIT) remote add origin $(GLUON_GIT_URL)
gluon-update: | $(GLUON_BUILD_DIR)/.git
@$(GLUON_GIT) remote set-url origin $(GLUON_GIT_URL)
@$(GLUON_GIT) fetch --tags origin $(GLUON_GIT_REF)
@$(GLUON_GIT) checkout master >/dev/null 2>&1 || exit 0
@$(GLUON_GIT) reset --hard FETCH_HEAD
@$(GLUON_GIT) clean -fd
@echo
## Build rules
all: manifest
sign: manifest | $(SECRET_KEY_FILE)
ifdef DEVICE_INFO
@echo
@echo "make sign hasn't been designed to work while GLUON_DEVICES is set."
@exit 1
endif
@for branch in experimental beta stable; do \
echo ''; \
echo ''Signing $$branch.manifest''; \
$(GLUON_BUILD_DIR)/contrib/sign.sh $(SECRET_KEY_FILE) output/images/sysupgrade/$$branch.manifest; \
done
# Note: $(GLUON_MAKE) is a recursive variable so it doesn't count as a $(MAKE).
# "+" tells MAKE that there is another $(MAKE) in the following shell script.
# This allows communication of MAKEFLAGS like -j to submake.
# https://stackoverflow.com/a/60706372/2721478
manifest: build
+@for branch in experimental beta stable; do \
echo ''; \
echo ''Creating $$branch manifest''; \
$(GLUON_MAKE) manifest GLUON_AUTOUPDATER_BRANCH=$$branch; \
done
build: gluon-prepare output-clean
+@for target in $(GLUON_TARGETS); do \
echo ''; \
echo ''Building target $$target''; \
$(GLUON_MAKE) download all GLUON_TARGET=$$target CONFIG_JSON_ADD_IMAGE_INFO=1; \
done
@if [ ! -f "$(OPKG_KEY_FOLDER)/key-build" ] && [ -f "$(GLUON_BUILD_DIR)/openwrt/key-build" ]; then \
echo 'Copying new opkg keys to $(OPKG_KEY_FOLDER)'; \
mkdir -p $(OPKG_KEY_FOLDER); \
cp $(GLUON_BUILD_DIR)/openwrt/key-build* $(OPKG_KEY_FOLDER)/; \
fi
ifndef GLUON_DEVICES
cat $(GLUON_BUILD_DIR)/openwrt/bin/targets/*/*/profiles.json | jq -s > output/devices.json
$(eval PACKAGES_BRANCH := $(subst OPENWRT_BRANCH=openwrt,packages,$(shell cat $(GLUON_BUILD_DIR)/modules | grep OPENWRT_BRANCH)))
mkdir -p output/packages/$(PACKAGES_BRANCH)
rsync -a --exclude '*/base' --exclude '*/luci' --exclude '*/packages' --exclude '*/routing' --exclude '*/telephony' $(GLUON_BUILD_DIR)/openwrt/bin/packages/ output/packages/$(PACKAGES_BRANCH)/
endif
gluon-prepare: gluon-update ffac-patch | .modules
PATCH_FILES = $(shell find $(PATCH_DIR)/ -type f -name '*.patch')
ffac-patch: gluon-update
@echo 'Applying patches…'
@if [ `$(GLUON_GIT) branch --list patched` ]; then \
$(GLUON_GIT) branch -D patched; \
fi
@$(GLUON_GIT) checkout -B patching
@if [ -d "$(PATCH_DIR)" -a "$(PATCH_DIR)/*.patch" ]; then \
(git apply --directory=$(GLUON_BUILD_DIR) --ignore-space-change --ignore-whitespace --whitespace=nowarn --verbose $(PATCH_FILES)) || ( \
$(GLUON_GIT) clean -fd; \
$(GLUON_GIT) checkout -B patched; \
$(GLUON_GIT) branch -D patching; \
exit 1 \
) \
fi
@$(GLUON_GIT) branch -M patched
.cmp-git-head: FORCE | ffac-patch
@$(GLUON_GIT) rev-parse @{0} | cmp -s '$@' || $(GLUON_GIT) rev-parse @{0} > '$@'
.modules: release.mk modules .cmp-git-head $(PATCH_DIR) $(PATCH_FILES) | ffac-patch
@echo
@echo Updating Gluon modules…
@rm -f .modules
+$(GLUON_MAKE) update
@if [ -f "$(OPKG_KEY_FOLDER)/key-build" ] && [ ! -f "$(GLUON_BUILD_DIR)/openwrt/key-build" ]; then \
echo 'Installing your opkg keys'; \
cp $(OPKG_KEY_FOLDER)/key-build* $(GLUON_BUILD_DIR)/openwrt/; \
fi
@touch .modules
## Patch system
patch-prepare: gluon-update
@echo 'Updating Gluon modules…'
@rm -f .modules
+@$(GLUON_MAKE) update >/dev/null 2>&1
patch:
@echo
@echo 'Creating a new patch from all changes found in $(GLUON_BUILD_DIR)'
@echo "Note: This will only create a correct patch, if you ran 'make patch-prepare' or 'make edit-patch' before you applied those changes."
@echo
@echo 'What should your new .patch file be called?'
+@$(GLUON_MAKE) update-patches >/dev/null 2>&1
@if [ `$(GLUON_GIT) status -s patches | head -c1 | grep -E '.'` ]; then \
echo 'Found changes in Gluon modules and created new .patch files for them.'; \
fi
@$(GLUON_GIT) add --all
@read file; \
echo ''Creating $$file.patch containing these changes:''; \
$(GLUON_GIT) status -s; \
$(GLUON_GIT) diff --staged > $(PATCH_DIR)/$$file.patch; \
$(GLUON_GIT) commit --no-edit -m "$$file.patch" -q
edit-patch: patch-prepare
@echo
@echo 'Available patches:'
@ls -1 $(PATCH_DIR) | grep -E '\.patch$'' | sed -e 's/\.patch$///'
@echo
@echo Which one do you want to edit?
+@read file; \
if [ ! -f "patches/$$file.patch" ]; then \
echo ''Couldn\'t find file: $$file.patch''; \
exit 1; \
else \
git apply --directory=$(GLUON_BUILD_DIR) --ignore-space-change --ignore-whitespace --whitespace=nowarn --verbose $(PATCH_DIR)/$$file.patch; \
if [ `$(GLUON_GIT) status -s patches | head -c1 | grep -E '.'` ]; then \
echo 'Patch contained patches for Gluon modules. Applying said patches…'; \
$(GLUON_MAKE) refresh-patches >/dev/null; \
fi; \
echo "You may edit $(GLUON_BUILD_DIR) now. Run 'make patch' once you are finished."; \
fi
update-patches: patch-prepare
@echo
@echo 'Updating our patches…'
@if [ `$(GLUON_GIT) branch --list refresh` ]; then \
$(GLUON_GIT) branch -D refresh; \
fi
@$(GLUON_GIT) checkout -B refreshing
@$(GLUON_GIT) commit --allow-empty -m "Patches" -q
+@for file in $(PATCH_FILES); do \
echo ''; \
(git apply --directory=$(GLUON_BUILD_DIR) --ignore-space-change --ignore-whitespace --whitespace=nowarn --verbose $$file) && true;\
EXIT_CODE=$$?; \
if [ $$EXIT_CODE -ne 0 ]; then \
echo ''Error applying patch $$file''; \
$(GLUON_GIT) clean -fdq; \
$(GLUON_GIT) checkout -B refresh; \
$(GLUON_GIT) branch -D refreshing; \
break; \
else \
if [ `$(GLUON_GIT) status -s patches | head -c1 | grep -E '.'` ]; then \
for file_rename in `$(GLUON_GIT) status -s -u patches | cut -c4-`; do \
mv ''$(GLUON_BUILD_DIR)/$$file_rename'' ''$(GLUON_BUILD_DIR)/$$(dirname "$$file_rename")/x$$(basename "$$file_rename")''; \
done; \
echo 'Refreshing Gluon patches…'; \
$(GLUON_MAKE) refresh-patches >/dev/null; \
fi; \
echo ''Refreshing $$file''; \
$(GLUON_GIT) add --all; \
$(GLUON_GIT) diff --staged > $$file; \
$(GLUON_GIT) commit --amend --no-edit -q; \
fi; \
done; exit $$EXIT_CODE
@$(GLUON_GIT) branch -M refresh
## Cleanup rules
devices-clean:
mkdir -p devices/
rm -rf devices/*
gluon-clean:
rm -f .modules
rm -rf $(GLUON_BUILD_DIR)
@echo
output-clean:
ifdef GLUON_DEVICES
mkdir -p devices/
else
mkdir -p output/
rm -rf output/*
endif
@echo
clean: gluon-clean output-clean devices-clean
Makefile: ;
FORCE: ;
.SUFFIXES: ;
.PHONY: all gluon-update sign manifest build gluon-prepare ffac-patch patch-prepare patch edit-patches update-patches gluon-clean output-clean