-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathMakefile
333 lines (260 loc) · 7.16 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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
SHELL = /bin/bash -o nounset -o pipefail -o errexit
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
## Argument Variables ##
CPUS = $(shell nproc)
MEMORY = 10000
DISK = 300000
DEVICE =
BACKEND = local
CHANNEL = beta
FLAVOR = aosp
IMAGE = hashbang/aosp-build:latest
IMAGE_OPTIONS =
RUN_OPTIONS =
NAME = aosp-build-$(FLAVOR)-$(BACKEND)
REQUIRED_FREE_SPACE_IN_GIB = 120
-include $(PWD)/config/env/$(BACKEND).env
## Default Target ##
.DEFAULT_GOAL := default
.PHONY: default
default: machine image fetch tools keys build release
## Primary Targets ##
.PHONY: fetch
fetch:
$(contain) fetch
.PHONY: keys
keys:
$(contain-keys) keys
.PHONY: review
review:
$(contain) review
.PHONY: build
build: ensure-enough-free-disk-space
$(contain) build
.PHONY: release
release:
$(contain-keys) release
.PHONY: publish
publish:
$(contain) publish
.PHONY: clean
clean:
$(contain) clean
.PHONY: mrproper
mrproper: storage-delete machine-delete
rm -rf build
## Secondary Targets ##
config/container/Dockerfile: config/container/Dockerfile.j2 config/container/render_template
./config/container/render_template "$<" "{\"tags\":[]}" > "$@"
## Support for different Docker image variants.
config/container/Dockerfile-golang:
config/container/Dockerfile-latest:
config/container/Dockerfile-%: config/container/Dockerfile.j2 config/container/render_template
./config/container/render_template "$<" "{\"tags\":[\"$*\"]}" > "$@"
.PHONY: image
image: config/container/Dockerfile
$(docker) build \
--tag $(IMAGE) \
--file "$(PWD)/$<" \
$(IMAGE_OPTIONS) \
$(PWD)
.PHONY: image-%
image-golang:
image-latest:
image-%: config/container/Dockerfile-%
$(docker) build \
--tag $(IMAGE) \
--file "$(PWD)/$<" \
$(IMAGE_OPTIONS) \
$(PWD)
## Note that the `image-latest` target should be used for pinning.
.PHONY: config/container/packages-pinned.list
config/container/packages-pinned.list:
$(contain-no-tty) pin-packages > "$@"
.PHONY: tools
tools:
mkdir -p config/keys build/base release build/external
$(contain) tools
.PHONY: vendor
vendor:
$(contain) build-vendor
.PHONY: chromium
chromium:
$(contain) build-chromium
.PHONY: kernel
kernel:
$(contain) build-kernel
## Development ##
.PHONY: latest
latest: config submodule-latest fetch
.PHONY: config
config:
$(contain) bash -c "source <(environment) && config"
.PHONY: manifest
manifest:
$(contain) bash -c "source <(environment) && manifest"
.PHONY: test-repro
test-repro:
$(contain) test-repro
.PHONY: test
test: test-repro
.PHONY: patches
patches:
@$(contain) bash -c "cd build/base && repo diff --absolute"
.PHONY: shell
shell:
$(docker) exec --interactive --tty "$(NAME)" shell \
|| $(contain) shell
.PHONY: monitor
monitor:
$(docker) exec --interactive --tty "$(NAME)" htop
.PHONY: install
install: tools
@scripts/flash
## Source Management ##
.PHONY: submodule-update
submodule-update:
git submodule update --init --recursive
.PHONY: submodule-latest
submodule-latest:
git submodule foreach 'git checkout master && git pull'
## Storage Bootstrapping ##
# TODO: detect if plugin is already installed or not
# TODO: Hash lock rexray with sha256 digest to prevent tag clobbering
.PHONY: storage-digitalocean
storage-digitalocean:
$(docker) volume ls | grep $(NAME) \
||( $(docker) plugin install \
--grant-all-permissions \
rexray/dobs:0.11.4 \
DOBS_REGION=$(DIGITALOCEAN_REGION) \
DOBS_TOKEN=$(DIGITALOCEAN_TOKEN) \
; $(docker) volume create \
--driver rexray/dobs:0.11.4 \
--opt=size=$$(( $(DISK) / 1000 )) \
--name=$(NAME) \
)
.PHONY: storage-local
storage-local:
$(docker) volume ls | grep $(NAME) \
|| $(docker) volume create \
--driver local \
--opt type=none \
--opt o=bind \
--opt device=$(PWD)/build \
$(NAME)
.PHONY: storage-delete
storage-delete:
$(docker) volume rm -f $(NAME) || :
## VM Management ##
.PHONY: machine-start
machine-start: machine-create machine-date
$(docker_machine) status $(NAME) \
|| $(docker_machine) start $(NAME)
.PHONY: machine-sync
machine-sync:
$(docker_machine) scp -r -d config/ $(NAME):$(PWD)/config/
.PHONY: machine-shell
machine-shell:
$(docker_machine) ssh $(NAME)
.PHONY: machine-stop
machine-stop:
$(docker_machine) stop $(NAME)
.PHONY: machine-delete
machine-delete:
$(docker_machine) rm -f -y $(NAME)
.PHONY: machine-date
machine-date:
$(docker_machine) ssh $(NAME) \
"sudo date -s @$(shell date +%s)"
.PHONY: machine-create
machine-create:
$(docker_machine) status $(NAME) \
||( $(docker_machine) create \
--driver $(BACKEND) \
$(docker_machine_create_flags) \
$(NAME) \
)
## VM Bootstrapping ##
ifeq ($(BACKEND),local)
executables = docker
docker = docker
machine:
storage_flags = --volume $(PWD)/build/:/home/build/build/
else ifeq ($(BACKEND),virtualbox)
executables = docker-machine ssh virtualbox
docker = $(docker_machine) ssh $(NAME) -t docker
machine: machine-start storage-local
storage_flags = --volume $(NAME):/home/build/build/
docker_machine_create_flags = \
--virtualbox-share-folder="$(PWD):$(PWD)" \
--virtualbox-disk-size="$(DISK)" \
--virtualbox-memory="$(MEMORY)" \
--virtualbox-cpu-count="$(CPUS)"
else ifeq ($(BACKEND),digitalocean)
executables = docker-machine ssh
docker = $(docker_machine) ssh $(NAME) -t docker
machine: machine-start storage-digitalocean machine-sync
storage_flags = --volume $(NAME):/home/build/build/
docker_machine_create_flags = \
--digitalocean-access-token=$(DIGITALOCEAN_TOKEN) \
--digitalocean-region=$(DIGITALOCEAN_REGION) \
--digitalocean-image=$(DIGITALOCEAN_IMAGE) \
--digitalocean-size=$(DIGITALOCEAN_SIZE)
endif
userid = $(shell id -u)
groupid = $(shell id -g)
docker_machine = docker-machine --storage-path "${PWD}/build/machine"
# Can be used mount aosp-build directory to /opt/aosp-build to allow fast
# development without the need to rebuild the container image all the time.
# See HashbangMobile for example.
contain-base-extend =
contain-base = \
$(docker) run \
--rm \
--interactive \
--name "$(NAME)" \
--hostname "$(NAME)" \
--user $(userid):$(groupid) \
--env DEVICE=$(DEVICE) \
--privileged \
--security-opt seccomp=unconfined \
--volume $(PWD)/config:/home/build/config \
--volume $(PWD)/release:/home/build/release \
--volume $(PWD)/scripts:/home/build/scripts \
$(contain-base-extend) \
$(RUN_OPTIONS) \
--shm-size="1g" \
$(storage_flags)
contain-no-tty = \
$(contain-base) \
$(IMAGE)
contain-keys = \
$(contain-base) \
--tty \
--volume $(PWD)/keys:/home/build/keys \
$(IMAGE)
contain = \
$(contain-base) \
--tty \
$(IMAGE)
## Helpers ##
ensure-git-status-clean:
@if [ -z "$(shell git status --porcelain=v2)" ]; then \
echo "git status has no output. Working tree is clean."; \
else \
git status; \
echo "Working tree is not clean as required. Exiting."; \
exit 1; \
fi
ensure-enough-free-disk-space:
@free_space=$(shell df -k --output=avail "$$PWD" | tail -n1); \
needed_free_space=$$(( $(REQUIRED_FREE_SPACE_IN_GIB) * 1024 * 1024 )); \
if [[ $$free_space -lt $$needed_free_space ]]; then \
echo "Not enought free space. $(REQUIRED_FREE_SPACE_IN_GIB) GiB are required." 1>&2; \
exit 1; \
fi
## Required Binary Check ##
check_executables := $(foreach exec,$(executables),\$(if \
$(shell which $(exec)),some string,$(error "No $(exec) in PATH")))