~lutostag/ubuntu/trusty/maas/1.5.2+packagefix

1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
1
python := python2.7
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
2
3
# Network activity can be suppressed by setting offline=true (or any
4
# non-empty string) at the command-line.
5
ifeq ($(offline),)
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
6
buildout := bin/buildout
7
virtualenv := virtualenv
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
8
else
9
buildout := bin/buildout buildout:offline=true
10
virtualenv := virtualenv --never-download
11
endif
12
13
# If offline has been selected, attempt to further block HTTP/HTTPS
14
# activity by setting bogus proxies in the environment.
15
ifneq ($(offline),)
16
export http_proxy := broken
17
export https_proxy := broken
18
endif
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
19
20
# Python enum modules.
21
py_enums := $(wildcard src/*/enum.py)
22
# JavaScript enum module (not modules).
23
js_enums := src/maasserver/static/js/enums.js
24
25
# Prefix commands with this when they need access to the database.
26
# Remember to add a dependency on bin/database from the targets in
27
# which those commands appear.
28
dbrun := bin/database --preserve run --
29
30
# For things that care, postgresfixture for example, we always want to
31
# use the "maas" databases.
32
export PGDATABASE := maas
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
33
34
build: \
35
    bin/buildout \
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
36
    bin/database \
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
37
    bin/maas-region-admin bin/test.maas \
38
    bin/maas bin/test.maascli \
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
39
    bin/test.maastesting \
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
40
    bin/twistd.pserv bin/test.pserv \
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
41
    bin/test.config \
1.2.17 by Andres Rodriguez
Import upstream version 1.4+bzr1789+dfsg
42
    bin/maas-probe-dhcp \
1.1.3 by Andres Rodriguez
Import upstream version 0.1+bzr295+dfsg
43
    bin/twistd.txlongpoll \
1.2.18 by Andres Rodriguez
Import upstream version 1.4+bzr1817+dfsg
44
    bin/celeryd.cluster bin/celeryd.region \
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
45
    bin/py bin/ipy \
46
    $(js_enums)
47
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
48
all: build doc
49
1.1.17 by Andres Rodriguez
Import upstream version 0.1+bzr971+dfsg
50
# Install all packages required for MAAS development & operation on
51
# the system. This may prompt for a password.
52
install-dependencies:
53
	sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
1.2.14 by Andres Rodriguez
Import upstream version 1.4+bzr1655+dfsg
54
	    --no-install-recommends install $(shell sort -u \
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
55
	        $(addprefix required-packages/,base build dev doc))
56
	sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
57
	    purge $(shell sort -u required-packages/forbidden)
1.1.17 by Andres Rodriguez
Import upstream version 0.1+bzr971+dfsg
58
1.2.20 by Dustin Kirkland
Import upstream version 1.4+bzr1853+dfsg
59
bin/python:
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
60
	$(virtualenv) --python=$(python) --system-site-packages $(CURDIR)
61
1.2.20 by Dustin Kirkland
Import upstream version 1.4+bzr1853+dfsg
62
bin/buildout: bin/python bootstrap/zc.buildout-1.5.2.tar.gz
63
	bin/python -m pip --quiet install --ignore-installed \
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
64
	    --no-dependencies bootstrap/zc.buildout-1.5.2.tar.gz
65
	$(RM) -f README.txt  # zc.buildout installs an annoying README.txt.
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
66
	@touch --no-create $@  # Ensure it's newer than its dependencies.
67
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
68
bin/database: bin/buildout buildout.cfg versions.cfg setup.py
69
	$(buildout) install database
70
	@touch --no-create $@
71
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
72
bin/maas-region-admin bin/celeryd.region: \
1.2.18 by Andres Rodriguez
Import upstream version 1.4+bzr1817+dfsg
73
    bin/buildout buildout.cfg versions.cfg setup.py $(js_enums)
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
74
	$(buildout) install maas
75
	@touch --no-create $@
76
77
bin/test.maas: bin/buildout buildout.cfg versions.cfg setup.py $(js_enums)
78
	$(buildout) install maas-test
79
	@touch --no-create $@
80
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
81
bin/maas: bin/buildout buildout.cfg versions.cfg setup.py
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
82
	$(buildout) install maascli
83
	@touch --no-create $@
84
85
bin/test.maascli: bin/buildout buildout.cfg versions.cfg setup.py
86
	$(buildout) install maascli-test
87
	@touch --no-create $@
88
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
89
bin/test.maastesting: bin/buildout buildout.cfg versions.cfg setup.py
90
	$(buildout) install maastesting-test
91
	@touch --no-create $@
92
1.2.18 by Andres Rodriguez
Import upstream version 1.4+bzr1817+dfsg
93
bin/maas-provision bin/twistd.pserv bin/celeryd.cluster: \
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
94
    bin/buildout buildout.cfg versions.cfg setup.py
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
95
	$(buildout) install pserv
96
	@touch --no-create $@
97
98
bin/test.pserv: bin/buildout buildout.cfg versions.cfg setup.py
99
	$(buildout) install pserv-test
100
	@touch --no-create $@
101
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
102
bin/test.config: bin/buildout buildout.cfg versions.cfg setup.py
103
	$(buildout) install config-test
104
	@touch --no-create $@
105
1.2.17 by Andres Rodriguez
Import upstream version 1.4+bzr1789+dfsg
106
bin/maas-probe-dhcp: bin/buildout buildout.cfg versions.cfg setup.py
107
	$(buildout) install maas-probe-dhcp
108
	@touch --no-create $@
109
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
110
bin/twistd.txlongpoll: bin/buildout buildout.cfg versions.cfg setup.py
111
	$(buildout) install txlongpoll
112
	@touch --no-create $@
113
114
bin/flake8: bin/buildout buildout.cfg versions.cfg setup.py
115
	$(buildout) install flake8
116
	@touch --no-create $@
117
1.2.2 by Andres Rodriguez
Import upstream version 1.2+bzr1349+dfsg
118
bin/sphinx bin/sphinx-build: bin/buildout buildout.cfg versions.cfg setup.py
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
119
	$(buildout) install sphinx
120
	@touch --no-create $@
121
122
bin/py bin/ipy: bin/buildout buildout.cfg versions.cfg setup.py
123
	$(buildout) install repl
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
124
	@touch --no-create bin/py bin/ipy
125
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
126
test: build
1.1.16 by Andres Rodriguez
Import upstream version 0.1+bzr777+dfsg
127
	echo $(wildcard bin/test.*) | xargs -n1 env
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
128
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
129
lint: lint-py lint-js lint-doc
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
130
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
131
pocketlint = $(call available,pocketlint,python-pocket-lint)
132
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
133
# XXX jtv 2014-02-25: Clean up this lint, then make it part of "make lint".
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
134
lint-css: sources = src/maasserver/static/css
135
lint-css:
136
	@find $(sources) -type f \
137
	    -print0 | xargs -r0 $(pocketlint) --max-length=120
138
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
139
lint-py: sources = $(wildcard *.py contrib/*.py) src templates twisted utilities etc
140
lint-py: bin/flake8
141
	@find $(sources) -name '*.py' ! -path '*/migrations/*' \
142
	    -print0 | xargs -r0 bin/flake8 --ignore=E123 --config=/dev/null
143
144
lint-doc:
145
	@./utilities/doc-lint
146
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
147
lint-js: sources = src/maasserver/static/js
148
lint-js:
149
	@find $(sources) -type f -print0 | xargs -r0 $(pocketlint)
150
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
151
# Apply automated formatting to all Python files.
152
format: sources = $(wildcard *.py contrib/*.py) src templates twisted utilities etc
153
format:
154
	@find $(sources) -name '*.py' -print0 | xargs -r0 ./utilities/format-imports
155
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
156
check: clean test
157
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
158
docs/api.rst: bin/maas-region-admin src/maasserver/api.py syncdb
159
	bin/maas-region-admin generate_api_doc > $@
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
160
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
161
sampledata: bin/maas-region-admin bin/database syncdb
162
	$(dbrun) bin/maas-region-admin loaddata src/maasserver/fixtures/dev_fixture.yaml
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
163
164
doc: bin/sphinx docs/api.rst
165
	bin/sphinx
166
1.2.31 by Andres Rodriguez
Import upstream version 1.5+bzr2267
167
doc-with-versions: bin/sphinx docs/api.rst
1.2.28 by Andres Rodriguez
Import upstream version 1.5+bzr2230
168
	cd docs/_build; make SPHINXOPTS="-A add_version_switcher=true" html
169
1.2.2 by Andres Rodriguez
Import upstream version 1.2+bzr1349+dfsg
170
man: $(patsubst docs/man/%.rst,man/%,$(wildcard docs/man/*.rst))
171
172
man/%: docs/man/%.rst | bin/sphinx-build
173
	bin/sphinx-build -b man docs man $^
174
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
175
enums: $(js_enums)
176
177
$(js_enums): bin/py src/maasserver/utils/jsenums.py $(py_enums)
178
	 bin/py -m src/maasserver/utils/jsenums $(py_enums) > $@
179
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
180
clean:
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
181
	$(MAKE) -C acceptance $@
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
182
	find . -type f -name '*.py[co]' -print0 | xargs -r0 $(RM)
183
	find . -type f -name '*~' -print0 | xargs -r0 $(RM)
1.2.5 by Andres Rodriguez
Import upstream version 1.3+bzr1452+dfsg
184
	find . -type f -name dropin.cache -print0 | xargs -r0 $(RM)
1.1.3 by Andres Rodriguez
Import upstream version 0.1+bzr295+dfsg
185
	$(RM) -r media/demo/* media/development
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
186
	$(RM) $(js_enums)
187
	$(RM) *.log
188
	$(RM) docs/api.rst
1.2.5 by Andres Rodriguez
Import upstream version 1.3+bzr1452+dfsg
189
	$(RM) -r docs/_autosummary docs/_build
1.2.2 by Andres Rodriguez
Import upstream version 1.2+bzr1349+dfsg
190
	$(RM) -r man/.doctrees
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
191
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
192
distclean: clean stop
193
	$(RM) -r bin include lib local
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
194
	$(RM) -r eggs develop-eggs
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
195
	$(RM) -r build dist logs/* parts
1 by Julian Edwards
Import upstream version 0.1~bzr146+dfsg
196
	$(RM) tags TAGS .installed.cfg
197
	$(RM) -r *.egg *.egg-info src/*.egg-info
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
198
	$(RM) -r run/* services/*/supervise
199
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
200
harness: bin/maas-region-admin bin/database
201
	$(dbrun) bin/maas-region-admin shell --settings=maas.demo
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
202
203
dbharness: bin/database
204
	bin/database --preserve shell
205
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
206
syncdb: bin/maas-region-admin bin/database
207
	$(dbrun) bin/maas-region-admin syncdb --noinput
208
	$(dbrun) bin/maas-region-admin migrate maasserver --noinput
209
	$(dbrun) bin/maas-region-admin migrate metadataserver --noinput
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
210
211
define phony_targets
212
  build
213
  check
214
  clean
215
  dbharness
216
  distclean
217
  doc
218
  enums
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
219
  format
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
220
  harness
1.1.17 by Andres Rodriguez
Import upstream version 0.1+bzr971+dfsg
221
  install-dependencies
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
222
  lint
223
  lint-css
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
224
  lint-doc
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
225
  lint-js
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
226
  lint-py
1.2.2 by Andres Rodriguez
Import upstream version 1.2+bzr1349+dfsg
227
  man
1.2.24 by Andres Rodriguez
Import upstream version 1.5+bzr1976
228
  package
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
229
  sampledata
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
230
  source_package
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
231
  syncdb
232
  test
233
endef
234
235
#
236
# Development services.
237
#
238
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
239
service_names_region := database dns region-worker reloader txlongpoll web webapp
240
service_names_cluster := cluster-worker pserv reloader
241
service_names_all := $(service_names_region) $(service_names_cluster)
242
243
# The following template is intended to be used with `call`, and it
244
# accepts a single argument: a target name. The target name must
245
# correspond to a service action (see "Pseudo-magic targets" below).
246
# A region- and cluster-specific variant of the target will be
247
# created, in addition to the target itself. These can be used to
248
# apply the service action to the region services, the cluster
249
# services, or all services, at the same time.
250
define service_template
251
$(1)-region: $(patsubst %,services/%/@$(1),$(service_names_region))
252
$(1)-cluster: $(patsubst %,services/%/@$(1),$(service_names_cluster))
253
$(1): $(1)-region $(1)-cluster
254
phony_services_targets += $(1)-region $(1)-cluster $(1)
255
endef
256
257
# Expand out aggregate service targets using `service_template`.
258
$(eval $(call service_template,pause))
259
$(eval $(call service_template,restart))
260
$(eval $(call service_template,start))
261
$(eval $(call service_template,status))
262
$(eval $(call service_template,stop))
263
$(eval $(call service_template,supervise))
264
265
# The `run` targets do not fit into the mould of the others.
266
run-region:
267
	@services/run $(service_names_region)
268
run-cluster:
269
	@services/run $(service_names_cluster)
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
270
run:
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
271
	@services/run $(service_names_all)
272
273
phony_services_targets += run-region run-cluster run
274
275
# This one's for the rapper, yo.
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
276
run+webapp:
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
277
	@services/run $(service_names_region) +webapp
278
279
phony_services_targets += run+webapp
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
280
281
# Convenient variables and functions for service control.
282
283
setlock = $(call available,setlock,daemontools)
284
supervise = $(call available,supervise,daemontools)
285
svc = $(call available,svc,daemontools)
286
svok = $(call available,svok,daemontools)
287
svstat = $(call available,svstat,daemontools)
288
289
service_lock = $(setlock) -n /run/lock/maas.dev.$(firstword $(1))
290
291
# Pseudo-magic targets for controlling individual services.
292
293
services/%/@run: services/%/@stop services/%/@deps
294
	@$(call service_lock, $*) services/$*/run
295
296
services/%/@start: services/%/@supervise
297
	@$(svc) -u $(@D)
298
299
services/%/@pause: services/%/@supervise
300
	@$(svc) -d $(@D)
301
302
services/%/@status:
303
	@$(svstat) $(@D)
304
305
services/%/@restart: services/%/@supervise
306
	@$(svc) -du $(@D)
307
308
services/%/@stop:
309
	@if $(svok) $(@D); then $(svc) -dx $(@D); fi
310
	@while $(svok) $(@D); do sleep 0.1; done
311
312
services/%/@supervise: services/%/@deps
313
	@mkdir -p logs/$*
314
	@touch $(@D)/down
315
	@if ! $(svok) $(@D); then \
316
	    logdir=$(CURDIR)/logs/$* \
317
	        $(call service_lock, $*) $(supervise) $(@D) & fi
318
	@while ! $(svok) $(@D); do sleep 0.1; done
319
320
# Dependencies for individual services.
321
1.1.14 by Andres Rodriguez
Import upstream version 0.1+bzr740+dfsg
322
services/dns/@deps: bin/py
323
1.2.18 by Andres Rodriguez
Import upstream version 1.4+bzr1817+dfsg
324
services/cluster-worker/@deps: bin/celeryd.cluster
1.1.18 by Andres Rodriguez
Import upstream version 0.1+bzr1223+dfsg
325
1.2.18 by Andres Rodriguez
Import upstream version 1.4+bzr1817+dfsg
326
services/region-worker/@deps: bin/celeryd.region
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
327
328
services/database/@deps: bin/database
329
330
services/pserv/@deps: bin/twistd.pserv
331
332
services/reloader/@deps:
333
334
services/txlongpoll/@deps: bin/twistd.txlongpoll
335
336
services/web/@deps:
337
1.2.22 by Andres Rodriguez
Import upstream version 1.5+bzr1948
338
services/webapp/@deps: bin/maas-region-admin
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
339
340
#
1.2.24 by Andres Rodriguez
Import upstream version 1.5+bzr1976
341
# Package building
342
#
343
# This ought to be as simple as using bzr builddeb --export-upstream but it
344
# has a bug and always considers apt-source tarballs before the specified
345
# branch.  So instead, export to a local tarball which is always found.
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
346
# Make sure debhelper and dh-apport packages are installed before using this.
1.2.33 by Greg Lutostanski
Import upstream version 1.5.2+bzr2282
347
PACKAGING := $(CURDIR)/../packaging.trusty
348
PACKAGING_BRANCH := lp:~maas-maintainers/maas/packaging.trusty
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
349
350
package_branch:
351
	@echo Downloading/refreshing packaging branch...
352
	@if [ ! -d $(PACKAGING) ]; then \
353
		bzr branch $(PACKAGING_BRANCH) $(PACKAGING); \
354
		else bzr pull -d $(PACKAGING); fi
355
356
# Make sure an orig tarball generated from the current branch is placed in the
357
# build area.
358
package_export: VER = $(shell dpkg-parsechangelog -l$(PACKAGING)/debian/changelog | sed -rne 's,^Version: ([^-]+).*,\1,p')
359
package_export: TARBALL = maas_$(VER).orig.tar.gz
360
package_export: package_branch
361
	@$(RM) -f ../build-area/$(TARBALL)
362
	@mkdir -p ../build-area
363
	@bzr export --root=maas-$(VER).orig ../build-area/$(TARBALL) $(CURDIR)
364
365
package: package_export
1.2.33 by Greg Lutostanski
Import upstream version 1.5.2+bzr2282
366
	bzr bd --merge $(PACKAGING) --result-dir=../build-area -- -uc -us
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
367
	@echo Binary packages built, see parent directory.
368
369
source_package: package_export
1.2.33 by Greg Lutostanski
Import upstream version 1.5.2+bzr2282
370
	bzr bd --merge $(PACKAGING) --result-dir=../build-area -- -S -uc -us
1.2.26 by Andres Rodriguez
Import upstream version 1.5+bzr2204
371
	@echo Source package built, see parent directory.
1.2.24 by Andres Rodriguez
Import upstream version 1.5+bzr1976
372
373
#
1.1.13 by Andres Rodriguez
Import upstream version 0.1+bzr709+dfsg
374
# Phony stuff.
375
#
376
377
define phony
378
  $(phony_services_targets)
379
  $(phony_targets)
380
endef
381
382
phony := $(sort $(strip $(phony)))
383
384
.PHONY: $(phony)
385
386
#
387
# Functions.
388
#
389
390
# Check if a command is found on PATH. Raise an error if not, citing
391
# the package to install. Return the command otherwise.
392
# Usage: $(call available,<command>,<package>)
393
define available
394
  $(if $(shell which $(1)),$(1),$(error $(1) not found; \
395
    install it with 'sudo apt-get install $(2)'))
396
endef