1# -*- coding: utf-8 -*-
2#
3# Copyright 2013-2014 Haiku, Inc.
4# Distributed under the terms of the MIT License.
5
6# -- Modules ------------------------------------------------------------------
7
8import os
9import platform
10import shutil
11import sys
12import time
13from subprocess import check_output
14
15from .Configuration import Configuration
16from .DependencyResolver import DependencyResolver
17from .Options import getOption
18from .PackageInfo import PackageInfo
19from .RecipeTypes import Architectures, MachineArchitecture
20from .Utils import info, sysExit
21
22buildPlatform = None
23
24
25# -- BuildPlatform class ------------------------------------------------------
26
27class BuildPlatform(object):
28	def __init__(self):
29		pass
30
31	def init(self, treePath, outputDirectory, packagesPath, architecture,
32			machineTriple):
33		self.architecture = architecture
34		self.machineTriple = machineTriple
35		self.treePath = treePath
36		self.outputDirectory = outputDirectory
37		self.packagesPath = packagesPath
38
39		self.targetArchitecture = Configuration.getTargetArchitecture()
40		if not self.targetArchitecture:
41			self.targetArchitecture = self.architecture
42
43		self.crossSysrootDir = '/boot/cross-sysroot/' + self.targetArchitecture
44
45	@property
46	def name(self):
47		return platform.system()
48
49	def getLicensesDirectory(self):
50		directory = Configuration.getLicensesDirectory()
51		if not directory:
52			directory = (self.findDirectory('B_SYSTEM_DIRECTORY')
53				+ '/data/licenses')
54		return directory
55
56	def getSystemMimeDbDirectory(self):
57		directory = Configuration.getSystemMimeDbDirectory()
58		if not directory:
59			directory = (self.findDirectory('B_SYSTEM_DIRECTORY')
60				+ '/data/mime_db')
61		return directory
62
63	def getCrossSysrootDirectory(self, workDir):
64		if not workDir:
65			return self.crossSysrootDir
66		return workDir + self.crossSysrootDir
67
68	def resolveDependencies(self, dependencyInfoFiles, requiresTypes,
69							repositories, **kwargs):
70		if not dependencyInfoFiles:
71			return
72		resolver = DependencyResolver(self, requiresTypes, repositories,
73									  **kwargs)
74		return resolver.determineRequiredPackagesFor(dependencyInfoFiles)
75
76
77# -- BuildPlatformHaiku class -------------------------------------------------
78
79class BuildPlatformHaiku(BuildPlatform):
80	def __init__(self):
81		super(BuildPlatformHaiku, self).__init__()
82
83	def init(self, treePath, outputDirectory, packagesPath,
84			shallowInitIsEnough=False):
85		if not os.path.exists('/packages'):
86			sysExit('haikuporter needs a version of Haiku with package '
87					'management support')
88
89		self.findDirectoryCache = {}
90
91		# get system haiku package version and architecture
92		systemPackageName = None
93		packagesDir = None
94		if not getOption('noSystemPackages'):
95			packagesDir = self.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY')
96		else:
97			packagesDir = packagesPath
98
99		for entry in os.listdir(packagesDir):
100			if (entry == 'haiku.hpkg'
101				or (entry.startswith('haiku-') and entry.endswith('.hpkg'))):
102				systemPackageName = entry
103				break
104		if systemPackageName is None:
105			sysExit('Failed to find Haiku system package')
106
107		haikuPackageInfo = PackageInfo(
108			os.path.join(packagesDir, systemPackageName))
109		machine = MachineArchitecture.getTripleFor(
110			haikuPackageInfo.architecture)
111		if not machine:
112			sysExit('Unsupported Haiku build platform architecture %s'
113					% haikuPackageInfo.architecture)
114
115		super(BuildPlatformHaiku, self).init(treePath, outputDirectory,
116			packagesPath, haikuPackageInfo.architecture, machine)
117
118	@property
119	def isHaiku(self):
120		return True
121
122	def usesChroot(self):
123		return getOption('chroot')
124
125	def findDirectory(self, which):
126		"""wraps invocation of 'finddir', uses caching"""
127		if which not in self.findDirectoryCache:
128			self.findDirectoryCache[which] \
129				= check_output(['/bin/finddir', which]).decode('utf-8').rstrip()  # drop newline
130		return self.findDirectoryCache[which]
131
132	def resolveDependencies(self, dependencyInfoFiles, requiresTypes,
133							repositories, **kwargs):
134
135		if not getOption('noSystemPackages'):
136			systemPackagesDir \
137				= buildPlatform.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY')
138			if systemPackagesDir not in repositories:
139				repositories.append(systemPackagesDir)
140
141		return super(BuildPlatformHaiku, self).resolveDependencies(
142			dependencyInfoFiles, requiresTypes, repositories, **kwargs)
143
144	def isSystemPackage(self, packagePath):
145		return packagePath.startswith(
146			self.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY'))
147
148	def activateBuildPackage(self, workDir, packagePath, revisionedName):
149		# activate the build package
150		packagesDir = buildPlatform.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY')
151		activeBuildPackage = packagesDir + '/' + os.path.basename(packagePath)
152		self.deactivateBuildPackage(workDir, activeBuildPackage,
153									revisionedName)
154
155		if not buildPlatform.usesChroot():
156			# may have to cross devices, so better use a symlink
157			os.symlink(packagePath, activeBuildPackage)
158		else:
159			# symlinking a package won't work in chroot, but in this
160			# case we are sure that the move won't cross devices
161			os.rename(packagePath, activeBuildPackage)
162		self._waitForPackageSelfLink(revisionedName, True)
163		return activeBuildPackage
164
165	def deactivateBuildPackage(self, workDir, activeBuildPackage,
166							   revisionedName):
167		if os.path.exists(activeBuildPackage):
168			os.remove(activeBuildPackage)
169		self._waitForPackageSelfLink(revisionedName, False)
170
171	def getCrossToolsBasePrefix(self, workDir):
172		return ''
173
174	def getCrossToolsBinPaths(self, workDir):
175		return ['/boot/system/develop/tools/bin']
176
177	def getInstallDestDir(self, workDir):
178		return None
179
180	def getImplicitProvides(self, forBuildHost):
181		return []
182
183	def setupNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
184			requiredPackages):
185		sysExit('setupNonChrootBuildEnvironment() not supported on Haiku')
186
187	def cleanNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
188			buildOK):
189		sysExit('cleanNonChrootBuildEnvironment() not supported on Haiku')
190
191	def _waitForPackageSelfLink(self, revisionedName, activated):
192		while True:
193			try:
194				time.sleep(0.5)
195				linkTarget = os.readlink('/packages/%s/.self'
196										 % revisionedName)
197				packagingFolder = revisionedName.split('-')[0]
198				linkTargetIsPackagingFolder \
199					= os.path.basename(linkTarget) == packagingFolder
200				if linkTargetIsPackagingFolder == activated:
201					return
202			except OSError:
203				if not activated:
204					return
205			info('waiting for build package %s to be %s'
206				% (revisionedName, 'activated' if activated else 'deactivated'))
207			time.sleep(1)
208
209# -- BuildPlatformUnix class --------------------------------------------------
210
211class BuildPlatformUnix(BuildPlatform):
212	def __init__(self):
213		super(BuildPlatformUnix, self).__init__()
214
215	def init(self, treePath, outputDirectory, packagesPath,
216			shallowInitIsEnough=False):
217		# get the machine triple from gcc
218		machine = check_output('gcc -dumpmachine', shell=True).decode('utf-8').strip()
219
220		# When building in a linux32 environment gcc still says "x86_64", so we
221		# replace the architecture part of the machine triple with what uname()
222		# says.
223		machineArchitecture = os.uname()[4].lower()
224		machine = machineArchitecture + '-' + machine[machine.find('-') + 1:]
225
226		# compute/guess architecture from the machine
227		architecture = MachineArchitecture.findMatch(machineArchitecture)
228		if not architecture:
229			architecture = Architectures.ANY
230
231		super(BuildPlatformUnix, self).init(treePath, outputDirectory,
232			packagesPath, architecture, machine)
233
234		self.secondaryTargetArchitectures \
235			= Configuration.getSecondaryTargetArchitectures()
236
237		if not shallowInitIsEnough:
238			if Configuration.getPackageCommand() is None:
239				sysExit('--command-package must be specified on this build '
240					'platform!')
241			if Configuration.getMimesetCommand() == 'mimeset':
242				sysExit('--command-mimeset must be specified on this build '
243					'platform!')
244			if not Configuration.getSystemMimeDbDirectory():
245				sysExit('--system-mimedb must be specified on this build '
246					'platform!')
247
248			if not Configuration.getCrossToolsDirectory():
249				sysExit('--cross-tools must be specified on this build '
250					'platform!')
251			self.originalCrossToolsDir = Configuration.getCrossToolsDirectory()
252
253			self.secondaryTargetMachineTriples = {}
254			if self.secondaryTargetArchitectures:
255				if not Configuration.getSecondaryCrossToolsDirectory(
256						self.secondaryTargetArchitectures[0]):
257					sysExit('The cross-tools directories for all secondary '
258						'architectures must be specified on this build '
259						'platform!')
260
261				for secondaryArchitecture in self.secondaryTargetArchitectures:
262					self.secondaryTargetMachineTriples[secondaryArchitecture] \
263						= MachineArchitecture.getTripleFor(
264							secondaryArchitecture)
265
266				if not Configuration.getSecondaryCrossDevelPackage(
267						self.secondaryTargetArchitectures[0]):
268					sysExit('The Haiku cross devel package for all secondary '
269						'architectures must be specified on this build '
270						'platform!')
271
272		self.findDirectoryMap = {
273			'B_PACKAGE_LINKS_DIRECTORY': '/packages',
274			'B_SYSTEM_DIRECTORY': '/boot/system',
275			'B_SYSTEM_PACKAGES_DIRECTORY': '/boot/system/packages',
276			}
277
278		self.crossDevelPackage = Configuration.getCrossDevelPackage()
279		targetArchitecture = Configuration.getTargetArchitecture()
280		if targetArchitecture is None:
281			sysExit('TARGET_ARCHITECTURE must be set in configuration on this '
282				'build platform!')
283		self.targetMachineTriple \
284			= MachineArchitecture.getTripleFor(targetArchitecture)
285		targetMachineAsName = self.targetMachineTriple.replace('-', '_')
286
287		self.implicitBuildHostProvides = set([
288			'haiku',
289			'haiku_devel',
290			'binutils_cross_' + targetArchitecture,
291			'gcc_cross_' + targetArchitecture,
292			'coreutils',
293			'diffutils',
294			'cmd:aclocal',
295			'cmd:autoconf',
296			'cmd:autoheader',
297			'cmd:automake',
298			'cmd:autoreconf',
299			'cmd:awk',
300			'cmd:bash',
301			'cmd:cat',
302			'cmd:cmake',
303			'cmd:cmp',
304			'cmd:find',
305			'cmd:flex',
306			'cmd:gcc',
307			'cmd:git',
308			'cmd:grep',
309			'cmd:gunzip',
310			'cmd:ld',
311			'cmd:libtool',
312			'cmd:libtoolize',
313			'cmd:login',
314			'cmd:m4',
315			'cmd:make',
316			'cmd:makeinfo',
317			'cmd:nm',
318			'cmd:objcopy',
319			'cmd:passwd',
320			'cmd:perl',
321			'cmd:python3',
322			'cmd:ranlib',
323			'cmd:readelf',
324			'cmd:sed',
325			'cmd:strip',
326			'cmd:tar',
327			'cmd:which',
328			'cmd:xargs',
329			'cmd:xres',
330			'cmd:zcat',
331			'cmd:' + targetMachineAsName + '_objcopy',
332			'cmd:' + targetMachineAsName + '_readelf',
333			'cmd:' + targetMachineAsName + '_strip',
334			])
335
336		# TODO: We might instead want to support passing the package infos for
337		# the system packages to haikuporter, so we could get the actual
338		# provides.
339		self.implicitBuildTargetProvides = set([
340			'haiku',
341			'haiku_devel',
342			'coreutils',
343			'diffutils',
344			'cmd:awk',
345			'cmd:cat',
346			'cmd:cmp',
347			'cmd:gunzip',
348			'cmd:less',
349			'cmd:login',
350			'cmd:passwd',
351			'cmd:bash',
352			'cmd:zcat'
353		])
354
355		for secondaryArchitecture in self.secondaryTargetArchitectures:
356			self.implicitBuildTargetProvides |= set([
357				'haiku_' + secondaryArchitecture,
358				'haiku_' + secondaryArchitecture + '_devel',
359				])
360			self.implicitBuildHostProvides |= set([
361				'haiku_' + secondaryArchitecture,
362				'haiku_' + secondaryArchitecture + '_devel',
363				'binutils_cross_' + secondaryArchitecture,
364				'gcc_cross_' + secondaryArchitecture,
365				])
366
367	@property
368	def isHaiku(self):
369		return False
370
371	def usesChroot(self):
372		return False
373
374	def findDirectory(self, which):
375		if which == 'B_SYSTEM_PACKAGES_DIRECTORY':
376			systemPackagesDirectory = getOption('systemPackagesDirectory')
377			if systemPackagesDirectory:
378				return systemPackagesDirectory
379
380		if which not in self.findDirectoryMap:
381			sysExit('Unsupported findDirectory() constant "%s"' % which)
382		return self.findDirectoryMap[which]
383
384	def isSystemPackage(self, packagePath):
385		return packagePath.startswith(
386			self.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY'))
387
388	def activateBuildPackage(self, workDir, packagePath, revisionedName):
389		return self._activatePackage(packagePath,
390			self._getPackageInstallRoot(workDir, packagePath), None, True)
391
392	def deactivateBuildPackage(self, workDir, activeBuildPackage,
393							   revisionedName):
394		if os.path.exists(activeBuildPackage):
395			shutil.rmtree(activeBuildPackage)
396
397	def getCrossToolsBasePrefix(self, workDir):
398		return self.outputDirectory + '/cross_tools'
399
400	def getCrossToolsBinPaths(self, workDir):
401		return [
402			self._getCrossToolsPath(workDir) + '/bin',
403			self.getCrossToolsBasePrefix(workDir) + '/boot/system/bin'
404			]
405
406	def getInstallDestDir(self, workDir):
407		return self.getCrossSysrootDirectory(workDir)
408
409	def getImplicitProvides(self, forBuildHost):
410		if forBuildHost:
411			return self.implicitBuildHostProvides
412		return self.implicitBuildTargetProvides
413
414	def setupNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
415			requiredPackages):
416		# init the build platform tree
417		crossToolsInstallPrefix = self.getCrossToolsBasePrefix(workDir)
418		if os.path.exists(crossToolsInstallPrefix):
419			shutil.rmtree(crossToolsInstallPrefix)
420		os.makedirs(crossToolsInstallPrefix + '/boot/system')
421
422		# init the sysroot dir
423		sysrootDir = self.getCrossSysrootDirectory(workDir)
424		if os.path.exists(sysrootDir):
425			shutil.rmtree(sysrootDir)
426		os.makedirs(sysrootDir)
427
428		print('Setting up sysroot for non-chroot build: ' + sysrootDir)
429
430		os.mkdir(sysrootDir + '/packages')
431		os.mkdir(sysrootDir + '/boot')
432		os.mkdir(sysrootDir + '/boot/system')
433
434		self._activateCrossTools(workDir, sysrootDir, secondaryArchitecture)
435
436		# extract the haiku_cross_devel_sysroot package
437		crossDevelPackage = self._getCrossDevelPackage(secondaryArchitecture)
438		print('Activating haiku_cross_devel_sysroot package: ' + crossDevelPackage)
439		self._activatePackage(crossDevelPackage, sysrootDir, '/boot/system')
440
441		# extract the required packages
442		for package in requiredPackages:
443			self._activatePackage(package,
444				self._getPackageInstallRoot(workDir, package), '/boot/system')
445
446	def cleanNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
447			buildOK):
448		# remove the symlinks we created in the cross tools tree
449		sysrootDir = self.getCrossSysrootDirectory(workDir)
450		targetArchitecture = secondaryArchitecture \
451			if secondaryArchitecture else self.targetArchitecture
452		toolsMachineTriple = self._getTargetMachineTriple(
453			secondaryArchitecture)
454
455		if targetArchitecture == 'x86_gcc2':
456			# gcc 2: uses 'sys-include' and 'lib' in the target machine dir
457			toolsMachineDir = (
458				self._getOriginalCrossToolsDir(secondaryArchitecture) + '/'
459				+ toolsMachineTriple)
460
461			toolsIncludeDir = toolsMachineDir + '/sys-include'
462			if os.path.lexists(toolsIncludeDir):
463				os.remove(toolsIncludeDir)
464
465			toolsLibDir = toolsMachineDir + '/lib'
466			if os.path.lexists(toolsLibDir):
467				os.remove(toolsLibDir)
468				# rename back the original lib dir
469				originalToolsLibDir = toolsLibDir + '.orig'
470				if os.path.lexists(originalToolsLibDir):
471					os.rename(originalToolsLibDir, toolsLibDir)
472		else:
473			# gcc 4: has a separate sysroot dir -- remove it completely
474			toolsSysrootDir = (
475				self._getOriginalCrossToolsDir(secondaryArchitecture)
476				+ '/sysroot')
477			if os.path.exists(toolsSysrootDir):
478				shutil.rmtree(toolsSysrootDir)
479
480		# If the the build went fine, clean up.
481		if buildOK:
482			crossToolsDir = self._getCrossToolsPath(workDir)
483			if os.path.exists(crossToolsDir):
484				shutil.rmtree(crossToolsDir)
485			if os.path.exists(sysrootDir):
486				shutil.rmtree(sysrootDir)
487
488	def _activateCrossTools(self, workDir, sysrootDir, secondaryArchitecture):
489		crossToolsDir = self._getCrossToolsPath(workDir)
490		os.mkdir(crossToolsDir)
491
492		targetArchitecture = secondaryArchitecture \
493			if secondaryArchitecture else self.targetArchitecture
494		toolsMachineTriple = self._getTargetMachineTriple(
495			secondaryArchitecture)
496
497		# prepare the system include and library directories
498		includeDir = crossToolsDir + '/include'
499		os.symlink(sysrootDir + '/boot/system/develop/headers', includeDir)
500
501		libDir = crossToolsDir + '/lib'
502		os.symlink(sysrootDir + '/boot/system/develop/lib', libDir)
503
504		# Prepare the bin dir -- it will be added to PATH and must contain the
505		# tools with the expected machine triple prefix.
506		toolsBinDir = (self._getOriginalCrossToolsDir(secondaryArchitecture)
507			+ '/bin')
508		binDir = crossToolsDir + '/bin'
509		os.symlink(toolsBinDir, binDir)
510
511		# Symlink the include and lib dirs back to the cross-tools tree such
512		# they match the paths that are built into the tools.
513		if targetArchitecture == 'x86_gcc2':
514			# gcc 2: uses 'sys-include' and 'lib' in the target machine dir
515			toolsMachineDir = (
516				self._getOriginalCrossToolsDir(secondaryArchitecture) + '/'
517				+ toolsMachineTriple)
518			toolsIncludeDir = toolsMachineDir + '/sys-include'
519			toolsLibDir = toolsMachineDir + '/lib'
520			# The cross-compiler doesn't have the subdirectory in the search
521			# path, so refer to that directly.
522			if secondaryArchitecture:
523				libDir += '/' + secondaryArchitecture
524		else:
525			# gcc 4: has a separate sysroot dir
526			toolsDevelopDir = (
527				self._getOriginalCrossToolsDir(secondaryArchitecture)
528				+ '/sysroot/boot/system/develop')
529			if os.path.exists(toolsDevelopDir):
530				shutil.rmtree(toolsDevelopDir)
531			os.makedirs(toolsDevelopDir)
532			toolsIncludeDir = toolsDevelopDir + '/headers'
533			toolsLibDir = toolsDevelopDir + '/lib'
534
535		if os.path.lexists(toolsIncludeDir):
536			os.remove(toolsIncludeDir)
537		os.symlink(includeDir, toolsIncludeDir)
538
539		if os.path.lexists(toolsLibDir):
540			if os.path.isdir(toolsLibDir):
541				# That's the original lib dir -- rename it.
542				os.rename(toolsLibDir, toolsLibDir + '.orig')
543			else:
544				os.remove(toolsLibDir)
545		os.symlink(libDir, toolsLibDir)
546
547	def _getTargetMachineTriple(self, secondaryArchitecture):
548		return (self.secondaryTargetMachineTriples[secondaryArchitecture]
549			if secondaryArchitecture
550			else self.targetMachineTriple)
551
552	def _getOriginalCrossToolsDir(self, secondaryArchitecture):
553		if not secondaryArchitecture:
554			return self.originalCrossToolsDir
555		return Configuration.getSecondaryCrossToolsDirectory(
556			secondaryArchitecture)
557
558	def _getCrossDevelPackage(self, secondaryArchitecture):
559		if not secondaryArchitecture:
560			return self.crossDevelPackage
561		return Configuration.getSecondaryCrossDevelPackage(
562			secondaryArchitecture)
563
564	def _getCrossToolsPath(self, workDir):
565		return self.getCrossToolsBasePrefix(workDir) + '/boot/cross-tools'
566
567	def _getPackageInstallRoot(self, workDir, package):
568		package = os.path.basename(package)
569		if '_cross_' in package:
570			return self.getCrossToolsBasePrefix(workDir)
571		return self.getCrossSysrootDirectory(workDir)
572
573	def _activatePackage(self, package, installRoot, installationLocation,
574			isBuildPackage=False):
575		# get the package info
576		packageInfo = PackageInfo(package)
577
578		# extract the package, unless it is a build package
579		if not isBuildPackage:
580			installPath = installRoot + '/' + installationLocation
581			args = [Configuration.getPackageCommand(), 'extract', '-C',
582				installPath, package]
583			output = check_output(args).decode('utf-8')
584			info(output)
585		else:
586			installPath = packageInfo.installPath
587			if not installPath:
588				sysExit('Build package "%s" doesn\'t have an install path'
589					% package)
590
591		# create the package links directory for the package and the .self
592		# symlink
593		packageLinksDir = (installRoot + '/packages/'
594						   + packageInfo.versionedName)
595		if os.path.exists(packageLinksDir):
596			shutil.rmtree(packageLinksDir)
597		os.makedirs(packageLinksDir)
598		os.symlink(installPath, packageLinksDir + '/.self')
599
600		return packageLinksDir
601
602
603# -- BuildPlatformBuildMaster class -------------------------------------------
604
605class BuildPlatformBuildMaster(BuildPlatform):
606	def __init__(self):
607		super(BuildPlatformBuildMaster, self).__init__()
608
609	def init(self, treePath, outputDirectory, packagesPath,
610			shallowInitIsEnough=False):
611
612		if Configuration.getTargetArchitecture() is None:
613			sysExit('TARGET_ARCHITECTURE must be set in configuration for '
614				+ 'build master mode!')
615		if Configuration.getPackageCommand() is None:
616			sysExit('--command-package must be specified for build master '
617				+ 'mode!')
618
619		super(BuildPlatformBuildMaster, self).init(treePath, outputDirectory,
620			packagesPath, Architectures.ANY, 'BuildMaster')
621
622	@property
623	def isHaiku(self):
624		return False
625
626	def usesChroot(self):
627		return False
628
629	def findDirectory(self, which):
630		if which == 'B_SYSTEM_PACKAGES_DIRECTORY':
631			systemPackagesDirectory = getOption('systemPackagesDirectory')
632			if systemPackagesDirectory:
633				return systemPackagesDirectory
634		return 'stub'
635
636	def isSystemPackage(self, packagePath):
637		return packagePath.startswith(
638			self.findDirectory('B_SYSTEM_PACKAGES_DIRECTORY'))
639
640	def activateBuildPackage(self, workDir, packagePath, revisionedName):
641		sysExit('activateBuildPackage() unsupported')
642
643	def deactivateBuildPackage(self, workDir, activeBuildPackage,
644			revisionedName):
645		sysExit('deactivateBuildPackage() unsupported')
646
647	def getCrossToolsBasePrefix(self, workDir):
648		sysExit('getCrossToolsBasePrefix() unsupported')
649
650	def getCrossToolsBinPaths(self, workDir):
651		sysExit('getCrossToolsBinPaths() unsupported')
652
653	def getInstallDestDir(self, workDir):
654		sysExit('getInstallDestDir() unsupported')
655
656	def getImplicitProvides(self, forBuildHost):
657		return set()
658
659	def setupNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
660			requiredPackages):
661		sysExit('setupNonChrootBuildEnvironment() unsupported')
662
663	def cleanNonChrootBuildEnvironment(self, workDir, secondaryArchitecture,
664			buildOK):
665		sysExit('cleanNonChrootBuildEnvironment() unsupported')
666
667# -----------------------------------------------------------------------------
668
669# init buildPlatform
670if platform.system() == 'Haiku':
671	buildPlatform = BuildPlatformHaiku()
672elif '--build-master' in sys.argv or '--list-dependencies' in sys.argv:
673	# can't use parsed options here as we're imported from it
674	buildPlatform = BuildPlatformBuildMaster()
675else:
676	buildPlatform = BuildPlatformUnix()
677