All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

GNUmakefile.in 15 KB
Newer Older
1
#
2
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
22
#
23 24
# Testbed Makefile
#
25 26 27 28 29
SRCDIR		= @srcdir@
OBJDIR		= .
SUBDIR		= 
TESTBED_SRCDIR  = @top_srcdir@
DISTCLEAN_FILES = @DISTCLEAN_FILES@ 
30
EVENTSYS	= @EVENTSYS@
31
PELABSUPPORT	= @PELABSUPPORT@
32
PGENISUPPORT    = @PROTOGENI_SUPPORT@
33
ISMAINSITE	= @TBMAINSITE@
34
SPEWFROMOPS	= @SPEWFROMOPS@
35 36
SYSTEM	       := $(shell uname -s)

37 38
include Makeconf

39 40 41
#
# Ordering here matters!
# Things with no dependencies go first: 
42
#   assign db lib www
43 44
# Things that may have dependencies go next:
#   @optional_subdirs@ (has event)
45
#   ipod os security sensors 
46
# Then things that only depend on stuff we've done:
47
#   pxe tbsetup tmcd utils backend www tip vis
48 49
# Then things that depend on stuff we just did:
#
50
ifeq ($(STANDALONE_CLEARINGHOUSE),0)
51 52 53
SUBDIRS = \
	clientside/lib \
	db assign www @optional_subdirs@ clientside ipod security sensors \
54
	pxe tbsetup account tmcd utils backend tip ipod vis \
55
	sensors os xmlrpc install/newnode_sshkeys mote tools/whol \
56
	tools/svn wiki bugdb collab node_usage install
57 58 59
ifeq ($(ISMAINSITE),1)
SUBDIRS += tools/rmanage
endif
60
ifeq ($(PGENISUPPORT),1)
61
SUBDIRS += protogeni apt
62
endif
63 64 65
else
SUBDIRS = db tbsetup account protogeni
endif
Christopher Alfeld's avatar
Christopher Alfeld committed
66

67
all:		all-subdirs just-builddirs 
68

69 70 71 72 73 74 75
#
# We used to statically link our event agents.  We no longer do this, but
# if you want "old style" agents, use this target.
#
all-static:
	@LDSTATIC=-static $(MAKE) all

76
ifeq ($(STANDALONE_CLEARINGHOUSE),0)
77
install:	
78 79
	@echo "Choose either boss-install, ops-install or fs-install"
	@echo "Choose opsfs-install instead of ops-install for a combined ops/fs machine"
80
	@echo "Choose tipserv-install for dedicated tip server machines."
81 82 83
else
install: clrhouse-install
endif
84 85

#
86
# For installation on boss node
87
# 
88 89
boss-install:	install-checks \
		install-subdirs install-mkdirs \
90
		install-setbuildinfo
91
	@echo "Boss node installed!"
92

93
# Same target, with the checks omitted
94
boss-install-force:	install-subdirs install-mkdirs install-setbuildinfo
95
	@echo "Boss node installed!"
96

97
# Skip only the schema checks, but do the other checks.
98 99 100 101 102 103 104 105
boss-install-noschemacheck: install-updatecheck \
		install-sitevarscheck install-dbfillcheck \
		install-genischemacheck install-subdirs install-mkdirs \
		install-setbuildinfo

# Skip the update check. 
boss-install-noupdatecheck: install-schemacheck \
		install-sitevarscheck install-dbfillcheck \
106 107 108
		install-genischemacheck install-subdirs install-mkdirs \
		install-setbuildinfo

109 110 111 112 113 114 115
# Only the checks:
install-checks: install-updatecheck \
		install-schemacheck \
		install-sitevarscheck \
		install-dbfillcheck install-genischemacheck
	@echo "Installation checks completed!"

116 117 118
clrhouse-install:	install-subdirs install-mkdirs
	@echo "CleaingHouse code installed!"

119
post-install:
120
	@$(MAKE) -C db post-install
Mike Hibler's avatar
Mike Hibler committed
121
	@$(MAKE) -C ipod post-install
122
	@$(MAKE) -C tbsetup post-install
123
	@$(MAKE) -C account post-install
124
	@$(MAKE) -C security post-install
125 126
	@$(MAKE) -C vis post-install
	@$(MAKE) -C www post-install
127
ifeq ($(EVENTSYS),1)
128
	@$(MAKE) -C event post-install
129
endif
130
	@$(MAKE) -C mote post-install
131
	@$(MAKE) -C tools post-install
132
	@$(MAKE) -C wiki post-install
133
	@$(MAKE) -C bugdb post-install
134
	@$(MAKE) -C collab post-install
135
	@$(MAKE) -C utils post-install
136 137 138
ifeq ($(NODE_USAGE_SUPPORT),1)
	@$(MAKE) -C node_usage post-install
endif
139

140
#
141
# For installation on the 'ops' or 'users' node (okay, plastic)
142
# 
143
ops-install:
144 145 146
	-mkdir -p $(INSTALL_TOPDIR)/log
	-mkdir -p $(INSTALL_TOPDIR)/log/mysql
	-chmod 770 $(INSTALL_TOPDIR)/log/mysql
147 148
	-chown mysql $(INSTALL_TOPDIR)/log/mysql
	-chgrp mysql $(INSTALL_TOPDIR)/log/mysql
149 150
	-mkdir -p $(INSTALL_TOPDIR)/log/logfiles
	-chmod 777 $(INSTALL_TOPDIR)/log/logfiles
151
	@$(MAKE) -C rc.d control-install
152 153
	@$(MAKE) -C tbsetup control-install
	@$(MAKE) -C security control-install
154 155
	@$(MAKE) -C tip control-install
	@$(MAKE) -C db control-install
Mac Newbold's avatar
Mac Newbold committed
156
	@$(MAKE) -C utils control-install
157
	@$(MAKE) -C clientside control-install
158
ifeq ($(EVENTSYS),1)
159
	@$(MAKE) -C event control-install
160
endif
161
	@$(MAKE) -C xmlrpc control-install
Leigh B. Stoller's avatar
Leigh B. Stoller committed
162
	@$(MAKE) -C account control-install
163 164 165
ifeq ($(PELABSUPPORT),1)
	@$(MAKE) -C pelab control-install
endif
166

167
fs-install:
168
	@$(MAKE) -C rc.d fs-install
169
	@$(MAKE) -C tbsetup fs-install
170
	@$(MAKE) -C clientside fs-install
Timothy Stack's avatar
 
Timothy Stack committed
171
	@$(MAKE) -C sensors fs-install
172 173 174 175

opsfs-install: ops-install fs-install
	@echo "Combined ops/fs install done."

176
install-mkdirs:
177
	-mkdir -p $(INSTALL_TOPDIR)/db
178 179
	-mkdir -p $(INSTALL_TOPDIR)/locks
	-mkdir -p $(INSTALL_TOPDIR)/log
180
	-mkdir -p $(INSTALL_TOPDIR)/log/mysql
181 182
	-mkdir -p $(INSTALL_TOPDIR)/etc
	-mkdir -p $(INSTALL_TOPDIR)/www
183
	-mkdir -p $(INSTALL_TOPDIR)/suidbin
184 185 186 187
	-mkdir -p $(INSTALL_TOPDIR)/ssl
	-chmod 770 $(INSTALL_TOPDIR)/ssl
ifeq ($(STANDALONE_CLEARINGHOUSE),0)
	-mkdir -p $(INSTALL_TOPDIR)/opsdir
188
	-mkdir -p $(INSTALL_TOPDIR)/log/exports
189
	-mkdir -p $(INSTALL_TOPDIR)/lists
190
	-mkdir -p $(INSTALL_TOPDIR)/backup
191
	-mkdir -p $(INSTALL_TOPDIR)/expwork
192 193
	-mkdir -p $(INSTALL_TOPDIR)/batch
	-chmod 777 $(INSTALL_TOPDIR)/batch
194 195
	-mkdir -p $(INSTALL_TOPDIR)/expinfo
	-chmod 777 $(INSTALL_TOPDIR)/expinfo
196 197
	-mkdir -p $(INSTALL_TOPDIR)/exparchive
	-chmod 777 $(INSTALL_TOPDIR)/exparchive
198 199
	-mkdir -p $(INSTALL_TOPDIR)/exparchive/Archive
	-chmod 777 $(INSTALL_TOPDIR)/exparchive/Archive
200 201
	-mkdir -p $(INSTALL_TOPDIR)/images
	-chmod 775 $(INSTALL_TOPDIR)/images
202
	-ln -sf /usr/testbed/bin/nse $(INSTALL_TOPDIR)/bin
203
endif
204

205 206 207 208
just-builddirs:
	@$(MAKE) -C rc.d all
	@$(MAKE) -C apache all

209 210
tipserv-install:
	-mkdir -p $(INSTALL_TOPDIR)/log/tiplogs
211
	-mkdir -p $(INSTALL_TOPDIR)/etc
212
	@$(MAKE) -C tip tipserv-install
213
	@$(MAKE) -C clientside/os/capture tipserv-install
214 215
	@$(MAKE) -C tbsetup tipserv-install

216 217
client-mkdirs:
	-mkdir -p $(DESTDIR)$(CLIENT_BINDIR)
218
	-mkdir -p $(DESTDIR)$(CLIENT_MANDIR)
219 220

client:
Leigh B Stoller's avatar
Leigh B Stoller committed
221
	@$(MAKE) -C clientside client
222
	@$(MAKE) -C os client
223
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
Timothy Stack's avatar
 
Timothy Stack committed
224
	@$(MAKE) -C tip client
225
endif
226 227

client-install: client client-mkdirs
Leigh B Stoller's avatar
Leigh B Stoller committed
228
	@$(MAKE) -C clientside client-install
229
	@$(MAKE) -C os client-install
230
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
Timothy Stack's avatar
 
Timothy Stack committed
231
	@$(MAKE) -C tip client-install
232
endif
233

234 235
subboss: 
	@$(MAKE) -C clientside subboss
236
	@$(MAKE) -C os subboss
237 238 239
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
	@$(MAKE) -C tip client
endif
Ryan Jackson's avatar
Ryan Jackson committed
240 241
	@$(MAKE) -C utils subboss

242
subboss-install: subboss
243 244
	@$(MAKE) -C clientside subboss-install
	@$(MAKE) -C os subboss-install
245 246 247
ifneq ($(SYSTEM),CYGWIN_NT-5.1)
	@$(MAKE) -C tip client-install
endif
Ryan Jackson's avatar
Ryan Jackson committed
248
	@$(MAKE) -C utils subboss-install
249 250
	@$(MAKE) -C db subboss-install
	@$(MAKE) -C rc.d subboss-install
251
	@$(MAKE) -C dhcpd subboss-install
252 253 254
	# Hack: this should probably be done by a subboss-install
	# script, but there isn't a huge need for that yet
	@rm -f $(INSTALL_RCDIR)/isc-dhcpd
Ryan Jackson's avatar
Ryan Jackson committed
255

256 257 258
TARBALLDESTDIR = /var/tmp/emulab-client

client-tarball:
259
	@$(MAKE) -C clientside client-tarball
260

261 262 263 264 265 266 267
client-src-tarball:
	@rm -f emulab-client-src.tar.gz
	tar clzf emulab-client-src.tar.gz -C clientside

# This is not finished yet.
client-shadow-rpm:
	-$(RM) -rf rpmbuild
268
	mkdir -p rpmbuild/SOURCES rpmbuild/SRPMS
269 270 271 272
	$(CP) emulab-client-src.tar.gz rpmbuild/SOURCES
	$(RPM) -v -bs --nodeps --define='_topdir $(TOPDIR)/rpmbuild' \
		clientside/shadow.spec

273 274 275 276
destdircheck:
	@if [ -z "$(DESTDIR)" ]; then \
	    echo "You must define DESTDIR for this target!"; \
	    false; \
277 278 279 280
	fi
	@if [ "$(DESTDIR)" = "/" ]; then \
	    echo "DESTDIR is '/', really really bad idea!"; \
	    false; \
281 282
	fi

283 284
mfsoscheck:
	@if [ `uname -s` != "FreeBSD" ]; then \
Mike Hibler's avatar
Mike Hibler committed
285
	    echo "Must build CDROM/MFS files on a FreeBSD system!"; \
286 287 288 289
	    false; \
	fi

mfs: mfsoscheck
290
	@$(MAKE) -C os mfs
Leigh B Stoller's avatar
Leigh B Stoller committed
291
	@$(MAKE) -C clientside mfs
292

Mike Hibler's avatar
Mike Hibler committed
293 294
mfs-nostatic: mfsoscheck
	@NOSTATIC=1 $(MAKE) -C os mfs
Leigh B Stoller's avatar
Leigh B Stoller committed
295
	@NOSTATIC=1 $(MAKE) -C clientside mfs
Mike Hibler's avatar
Mike Hibler committed
296

297
mfs-install: destdircheck mfs client-mkdirs
298
	@$(MAKE) -C os mfs-install
Leigh B Stoller's avatar
Leigh B Stoller committed
299
	@$(MAKE) -C clientside mfs-install
300

Mike Hibler's avatar
Mike Hibler committed
301 302
mfs-nostatic-install: destdircheck mfs-nostatic client-mkdirs
	@$(MAKE) -C os mfs-install
Leigh B Stoller's avatar
Leigh B Stoller committed
303
	@$(MAKE) -C clientside mfs-install
Mike Hibler's avatar
Mike Hibler committed
304

305 306 307
frisbee-mfs: mfsoscheck
	@$(MAKE) -C cdrom/groklilo client
	@$(MAKE) -C os frisbee-mfs
Leigh B Stoller's avatar
Leigh B Stoller committed
308
	@$(MAKE) -C clientside frisbee-mfs
309

Mike Hibler's avatar
Mike Hibler committed
310 311 312
frisbee-mfs-nostatic: mfsoscheck
	@NOSTATIC=1 $(MAKE) -C cdrom/groklilo client
	@NOSTATIC=1 $(MAKE) -C os frisbee-mfs
Leigh B Stoller's avatar
Leigh B Stoller committed
313
	@NOSTATIC=1 $(MAKE) -C clientside frisbee-mfs
Mike Hibler's avatar
Mike Hibler committed
314

315 316 317
frisbee-mfs-install: destdircheck frisbee-mfs
	@CLIENT_BINDIR=/etc/testbed $(MAKE) -e -C cdrom/groklilo client-install
	@$(MAKE) -C os frisbee-mfs-install
Leigh B Stoller's avatar
Leigh B Stoller committed
318
	@$(MAKE) -C clientside frisbee-mfs-install
319

Mike Hibler's avatar
Mike Hibler committed
320 321 322
frisbee-mfs-nostatic-install: destdircheck frisbee-mfs-nostatic
	@CLIENT_BINDIR=/etc/testbed $(MAKE) -e -C cdrom/groklilo client-install
	@$(MAKE) -C os frisbee-mfs-install
Leigh B Stoller's avatar
Leigh B Stoller committed
323
	@$(MAKE) -C clientside frisbee-mfs-install
Mike Hibler's avatar
Mike Hibler committed
324

325 326 327 328 329 330 331 332 333 334 335 336
newnode-mfs: mfsoscheck
	@$(MAKE) -C clientside newnode-mfs

newnode-mfs-nostatic: mfsoscheck
	@NOSTATIC=1 $(MAKE) -C clientside newnode-mfs

newnode-mfs-install: destdircheck newnode-mfs client-mkdirs
	@$(MAKE) -C clientside newnode-mfs-install

newnode-mfs-nostatic-install: destdircheck newnode-mfs-nostatic client-mkdirs
	@$(MAKE) -C clientside newnode-mfs-install

Mike Hibler's avatar
Mike Hibler committed
337 338 339 340 341
cdboot: mfsoscheck client
	@echo "CD/Dongle files built"

cdboot-install: destdircheck cdboot
	@$(MAKE) -C cdrom client-install
Leigh B Stoller's avatar
Leigh B Stoller committed
342
	@$(MAKE) -C clientside/tmcc/freebsd6 cdboot-install
Mike Hibler's avatar
Mike Hibler committed
343

344 345 346 347
flashboot: mfsoscheck client
	@echo "Flash dongle files built"

flashboot-install: destdircheck flashboot
Leigh B Stoller's avatar
Leigh B Stoller committed
348
	@$(MAKE) -C clientside/tmcc/freebsd6 cdboot-install
349 350
	@$(MAKE) -C os frisbee-mfs-install
	@$(MAKE) -C flash client-install
Leigh B Stoller's avatar
Leigh B Stoller committed
351
	@$(MAKE) -C clientside frisbee-mfs-install
352

353 354 355 356
#
# A check to see if this is a 'real' install. Kinda hacky, but as far as I can
# tell, you can't put ifeq()'s inside of targets
#
357 358 359 360 361
ifeq ($(TBROOT),/usr/testbed)
UPDATETESTBED= @cd $(OBJDIR)/install && perl update-testbed
else
UPDATETESTBED= @echo "Skipping update check, since prefix isn't /usr/testbed"
endif
362 363 364 365 366 367 368
ifeq ($(ISMAINSITE),1)
update-testbed: update-testbed-nostop
else
update-testbed:	update-testbed-install
endif

update-testbed-install:
369 370 371
	@echo "Updating the testbed ..."
	$(UPDATETESTBED) -i -s

372 373 374 375 376 377 378 379
update-testbed-noinstall:
	@echo "Updating the testbed ..."
	$(UPDATETESTBED)

update-testbed-nostop:
	@echo "Updating the testbed ..."
	$(UPDATETESTBED) -i

380 381 382 383 384 385 386 387 388 389 390 391 392
update-testbed-force:
	@echo "Updating the testbed in force mode ..."
	$(UPDATETESTBED) -f

ifeq ($(TBROOT),/usr/testbed)
UPDATECHECK= @cd $(OBJDIR)/install && perl update-testbed -v
else
UPDATECHECK= @echo "Skipping update checks, since prefix isn't /usr/testbed"
endif
install-updatecheck:
	@echo "Checking to see if updates need to be run"
	$(UPDATECHECK)

393
ifeq ($(TBROOT),/usr/testbed)
394
SCHEMACHECK= cd $(OBJDIR)/db && perl schemacheck
395 396 397 398 399 400 401
else
SCHEMACHECK= @echo "Skipping schema check, since prefix isn't /usr/testbed"
endif
install-schemacheck:
	@echo "Checking DB schema..."
	$(SCHEMACHECK)

Chad Barb's avatar
 
Chad Barb committed
402 403 404 405 406 407 408 409 410
ifeq ($(TBROOT),/usr/testbed)
SITEVARSCHECK= cd $(OBJDIR)/db && perl sitevarscheck
else
SITEVARSCHECK= @echo "Skipping sitevars check, since prefix isn't /usr/testbed"
endif
install-sitevarscheck:
	@echo "Checking Site variables..."
	$(SITEVARSCHECK)

411 412 413 414 415 416 417 418 419
ifeq ($(TBROOT),/usr/testbed)
DBFILLCHECK= cd $(OBJDIR)/db && perl dbfillcheck
else
DBFILLCHECK= @echo "Skipping DB fill check, since prefix isn't /usr/testbed"
endif
install-dbfillcheck:
	@echo "Checking Initial DB Fill ..."
	$(DBFILLCHECK)

420 421 422 423 424 425 426 427 428
ifeq ($(TBROOT),/usr/testbed)
SETBUILDINFO= cd $(OBJDIR)/utils && perl setbuildinfo
else
SETBUILDINFO= @echo "Skipping setbuildinfo, since prefix isn't /usr/testbed"
endif
install-setbuildinfo:
	@echo "Setting the Build and Version info"
	$(SETBUILDINFO)

429
install-genischemacheck:
430
ifeq ($(PGENISUPPORT),1)
431
	@$(MAKE) -C protogeni install-genischemacheck
432
endif
Leigh B. Stoller's avatar
Leigh B. Stoller committed
433
	@echo "Done"
434

435 436 437
# We use separate src and obj trees in Emulab, so the traditional distclean to
# clean "made" files from a mingled source-and-obj tree is unnecessary.
# However, this may be useful if you mistakenly configure and make a src tree.
438 439
clean:		clean-subdirs
distclean:	distclean-subdirs
Mike Hibler's avatar
Mike Hibler committed
440
	rm -f Makeconf GNUmakefile config.h config.status config.cache config.log
441
	rm -f $(DISTCLEAN_FILES)
442 443 444 445 446 447 448 449 450 451 452 453 454 455 456

#
# Be careful, do not run these unless you are updating your installation
# with a new IP subnet or domain name. 
#
boss-updateip-clean:	clean
	@$(MAKE) -C rc.d clean
	@$(MAKE) -C apache clean
	@$(MAKE) -C named clean
	@$(MAKE) -C dhcpd clean

ops-updateip-clean:	clean
	@$(MAKE) -C rc.d clean
	@$(MAKE) -C apache clean

457 458 459 460
update-rcd:
	@$(MAKE) -C rc.d all
	@$(MAKE) -C rc.d install

461 462 463 464
#
# Here's a different approch to recover from just configure problems.  It cleans
# all files from an obj tree that have a corresponding .in file in the src tree.
undo-configure:
465
	find $SRCDIR -name '*.in' -a -not -name configure.in | \
466
	    sed -e "s;$SRCDIR;$OBJDIR;" -e 's;[.]in$;;' | xargs rm -f
467

468 469 470 471 472 473
#
# XXX a "temporary" hack for scripts that were evolving fast.
# We didn't want to have to remake the client image whenever we changed these.
# They are copied over to the embryonic boss and ops during setup.
#
elabinelab-scripts:
474
	mkdir -p $(INSTALL_TOPDIR)/etc
475 476
	cp -f $(SRCDIR)/clientside/tmcc/freebsd/mkextrafs.pl $(INSTALL_TOPDIR)/etc/
	cp -f $(SRCDIR)/clientside/tmcc/common/config/rc.mkelab $(INSTALL_TOPDIR)/etc/
477

478
ifeq ($(SPEWFROMOPS),1)
479
elabinelab-nogit: elabinelab-scripts
480 481 482 483
	-mkdir -p /share/emulab
	rm -f /share/emulab/emulab-src.tar.gz
	tar czf /share/emulab/emulab-src.tar.gz -C $(SRCDIR) --exclude=.git .

484
elabinelab-git: elabinelab-scripts
485 486
	-mkdir -p /share/emulab
	rm -f /share/emulab/emulab-src.tar.gz
487
	(cd $(SRCDIR); \
488 489 490 491
	 git archive HEAD > /share/emulab/emulab-src.tar)
	tar rf /share/emulab/emulab-src.tar -C $(SRCDIR) \
	 --exclude=.git protogeni/rspec-geni
	gzip /share/emulab/emulab-src.tar
492
else
493
elabinelab-nogit: elabinelab-scripts
494 495
	-mkdir -p $(INSTALL_TOPDIR)/src
	rm -f $(INSTALL_TOPDIR)/src/emulab-src.tar.gz
496
	tar czf $(INSTALL_TOPDIR)/src/emulab-src.tar.gz -C $(SRCDIR) --exclude=.git .
497

498
elabinelab-git: elabinelab-scripts
499 500
	-mkdir -p $(INSTALL_TOPDIR)/src
	rm -f $(INSTALL_TOPDIR)/src/emulab-src.tar.gz
501
	(cd $(SRCDIR); \
502 503 504 505
	 git archive HEAD > $(INSTALL_TOPDIR)/src/emulab-src.tar)
	tar rf $(INSTALL_TOPDIR)/src/emulab-src.tar -C $(SRCDIR) \
	 --exclude=.git protogeni/rspec-geni
	gzip $(INSTALL_TOPDIR)/src/emulab-src.tar
506
endif
507

508 509 510 511 512
# How to recursively descend into subdirectories to make general
# targets such as `all'.
%.MAKE:
	@$(MAKE) -C $(dir $@) $(basename $(notdir $@))
%-subdirs: $(addsuffix /%.MAKE,$(SUBDIRS)) ;
513

514 515
# By default, make any target by descending into subdirectories.
%: %-subdirs ;
516

517 518
.PHONY: post-install install-mkdirs clrhouse-install install \
	boss-install-noupdatecheck boss-install-noschemacheck \
519 520
	boss-install-force update-testbed update-testbed-install \
	update-testbed-noinstall update-testbed-nostop
521 522 523

# Get rid of a bunch of nasty built-in implicit rules.
.SUFFIXES: