| Index: tools/build.py
|
| diff --git a/tools/build.py b/tools/build.py
|
| index 1d1b8c805eb612d53389e92c512eeb5369442e54..07eeb2074afa0a572459ca1d5d51009bdf0ecbb8 100755
|
| --- a/tools/build.py
|
| +++ b/tools/build.py
|
| @@ -15,6 +15,9 @@ import utils
|
| HOST_OS = utils.GuessOS()
|
| HOST_CPUS = utils.GuessCpus()
|
| armcompilerlocation = '/opt/codesourcery/arm-2009q1'
|
| +SCRIPT_DIR = os.path.dirname(sys.argv[0])
|
| +DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
|
| +THIRD_PARTY_ROOT = os.path.join(DART_ROOT, 'third_party')
|
|
|
| def BuildOptions():
|
| result = optparse.OptionParser()
|
| @@ -29,6 +32,10 @@ def BuildOptions():
|
| help='Target architectures (comma-separated).',
|
| metavar='[all,ia32,x64,simarm,arm]',
|
| default=utils.GuessArchitecture())
|
| + result.add_option("--os",
|
| + help='Target OSs (comma-separated).',
|
| + metavar='[all,host,android]',
|
| + default='host')
|
| result.add_option("-j",
|
| help='The number of parallel jobs to run.',
|
| metavar=HOST_CPUS,
|
| @@ -39,13 +46,22 @@ def BuildOptions():
|
| return result
|
|
|
|
|
| -def ProcessOptions(options):
|
| +def ProcessOsOption(os):
|
| + if os == 'host':
|
| + return HOST_OS
|
| + return os
|
| +
|
| +
|
| +def ProcessOptions(options, args):
|
| if options.arch == 'all':
|
| options.arch = 'ia32,x64'
|
| if options.mode == 'all':
|
| options.mode = 'release,debug'
|
| + if options.os == 'all':
|
| + options.os = 'host,android'
|
| options.mode = options.mode.split(',')
|
| options.arch = options.arch.split(',')
|
| + options.os = options.os.split(',')
|
| for mode in options.mode:
|
| if not mode in ['debug', 'release']:
|
| print "Unknown mode %s" % mode
|
| @@ -54,39 +70,159 @@ def ProcessOptions(options):
|
| if not arch in ['ia32', 'x64', 'simarm', 'arm']:
|
| print "Unknown arch %s" % arch
|
| return False
|
| + options.os = [ProcessOsOption(os) for os in options.os]
|
| + for os in options.os:
|
| + if not os in ['android', 'freebsd', 'linux', 'macos', 'win32']:
|
| + print "Unknown os %s" % os
|
| + return False
|
| + if os != HOST_OS:
|
| + if os != 'android':
|
| + print "Unsupported target os %s" % os
|
| + return False
|
| + if not HOST_OS in ['linux']:
|
| + print ("Cross-compilation to %s is not supported on host os %s."
|
| + % (os, HOST_OS))
|
| + return False
|
| + if not arch in ['ia32']:
|
| + print ("Cross-compilation to %s is not supported for architecture %s."
|
| + % (os, arch))
|
| + return False
|
| + # We have not yet tweaked the v8 dart build to work with the Android
|
| + # NDK/SDK, so don't try to build it.
|
| + if args == []:
|
| + print "For android builds you must specify a target, such as 'dart'."
|
| + return False
|
| + if 'v8' in args:
|
| + print "The v8 target is not supported for android builds."
|
| + return False
|
| return True
|
|
|
|
|
| -def setTools(arch):
|
| - if arch == 'arm':
|
| +def SetTools(arch, toolchainprefix):
|
| + toolsOverride = None
|
| + if arch == 'arm' and toolchainprefix == None:
|
| + toolchainprefix = armcompilerlocation + "/bin/arm-none-linux-gnueabi"
|
| + if toolchainprefix:
|
| toolsOverride = {
|
| - "CC" : armcompilerlocation + "/bin/arm-none-linux-gnueabi-gcc",
|
| - "CXX" : armcompilerlocation + "/bin/arm-none-linux-gnueabi-g++",
|
| - "AR" : armcompilerlocation + "/bin/arm-none-linux-gnueabi-ar",
|
| - "LINK": armcompilerlocation + "/bin/arm-none-linux-gnueabi-g++",
|
| - "NM" : armcompilerlocation + "/bin/arm-none-linux-gnueabi-nm",
|
| + "CC" : toolchainprefix + "-gcc",
|
| + "CXX" : toolchainprefix + "-g++",
|
| + "AR" : toolchainprefix + "-ar",
|
| + "LINK": toolchainprefix + "-g++",
|
| + "NM" : toolchainprefix + "-nm",
|
| }
|
| - return toolsOverride
|
| + return toolsOverride
|
| +
|
| +
|
| +def CheckDirExists(path, docstring):
|
| + if not os.path.isdir(path):
|
| + raise Exception('Could not find %s directory %s'
|
| + % (docstring, path))
|
| +
|
| +
|
| +def SetCrossCompilationEnvironment(host_os, target_os, target_arch, old_path):
|
| + global THIRD_PARTY_ROOT
|
| + if host_os not in ['linux']:
|
| + raise Exception('Unsupported host os %s' % host_os)
|
| + if target_os not in ['android']:
|
| + raise Exception('Unsupported target os %s' % target_os)
|
| + if target_arch not in ['ia32']:
|
| + raise Exception('Unsupported target architecture %s' % target_arch)
|
| +
|
| + CheckDirExists(THIRD_PARTY_ROOT, 'third party tools');
|
| + android_tools = os.path.join(THIRD_PARTY_ROOT, 'android_tools')
|
| + CheckDirExists(android_tools, 'Android tools')
|
| + android_ndk_root = os.path.join(android_tools, 'ndk')
|
| + CheckDirExists(android_ndk_root, 'Android NDK')
|
| + android_sdk_root = os.path.join(android_tools, 'sdk')
|
| + CheckDirExists(android_sdk_root, 'Android SDK')
|
| +
|
| + os.environ['ANDROID_NDK_ROOT'] = android_ndk_root
|
| + os.environ['ANDROID_SDK_ROOT'] = android_sdk_root
|
| +
|
| + toolchain_arch = 'x86-4.4.3'
|
| + toolchain_dir = 'linux-x86'
|
| + android_toolchain = os.path.join(android_ndk_root,
|
| + 'toolchains', toolchain_arch,
|
| + 'prebuilt', toolchain_dir, 'bin')
|
| + CheckDirExists(android_toolchain, 'Android toolchain')
|
| +
|
| + os.environ['ANDROID_TOOLCHAIN'] = android_toolchain
|
| +
|
| + android_sdk_version = 9
|
| +
|
| + android_sdk_tools = os.path.join(android_sdk_root, 'tools')
|
| + CheckDirExists(android_sdk_tools, 'Android SDK tools')
|
| +
|
| + android_sdk_platform_tools = os.path.join(android_sdk_root, 'platform-tools')
|
| + CheckDirExists(android_sdk_platform_tools, 'Android SDK platform tools')
|
| +
|
| + pathList = [old_path,
|
| + android_ndk_root,
|
| + android_sdk_tools,
|
| + android_sdk_platform_tools,
|
| + # for Ninja - maybe don't need?
|
| + android_toolchain
|
| + ]
|
| + os.environ['PATH'] = ':'.join(pathList)
|
| +
|
| + gypDefinesList = [
|
| + 'target_arch=ia32',
|
| + 'OS=%s' % target_os,
|
| + 'android_build_type=0',
|
| + 'host_os=%s' % host_os,
|
| + 'linux_fpic=1',
|
| + 'release_optimize=s',
|
| + 'linux_use_tcmalloc=0',
|
| + 'android_sdk=%s', os.path.join(android_sdk_root, 'platforms',
|
| + 'android-%d' % android_sdk_version),
|
| + 'android_sdk_tools=%s' % android_sdk_platform_tools
|
| + ]
|
| +
|
| + os.environ['GYP_DEFINES'] = ' '.join(gypDefinesList)
|
|
|
|
|
| def Execute(args):
|
| - print "#" + ' '.join(args)
|
| process = subprocess.Popen(args)
|
| process.wait()
|
| if process.returncode != 0:
|
| raise Error(args[0] + " failed")
|
|
|
|
|
| +def GClientRunHooks():
|
| + Execute(['gclient', 'runhooks'])
|
| +
|
| +
|
| +def RunhooksIfNeeded(host_os, mode, arch, target_os):
|
| + build_root = utils.GetBuildRoot(host_os)
|
| + build_cookie_path = os.path.join(build_root, 'lastHooksTargetOS.txt')
|
| +
|
| + old_target_os = None
|
| + try:
|
| + with open(build_cookie_path) as f:
|
| + old_target_os = f.read(1024)
|
| + except IOError as e:
|
| + pass
|
| + if target_os != old_target_os:
|
| + try:
|
| + os.mkdir(build_root)
|
| + except OSError as e:
|
| + pass
|
| + with open(build_cookie_path, 'w') as f:
|
| + f.write(target_os)
|
| + GClientRunHooks()
|
| +
|
| +
|
| def CurrentDirectoryBaseName():
|
| """Returns the name of the current directory"""
|
| return os.path.relpath(os.curdir, start=os.pardir)
|
|
|
| +
|
| def Main():
|
| utils.ConfigureJava()
|
| # Parse the options.
|
| parser = BuildOptions()
|
| (options, args) = parser.parse_args()
|
| - if not ProcessOptions(options):
|
| + if not ProcessOptions(options, args):
|
| parser.print_help()
|
| return 1
|
| # Determine which targets to build. By default we build the "all" target.
|
| @@ -97,70 +233,88 @@ def Main():
|
| target = 'all'
|
| else:
|
| target = args[0]
|
| +
|
| + # Remember path
|
| + old_path = os.environ['PATH']
|
| # Build the targets for each requested configuration.
|
| - for mode in options.mode:
|
| - for arch in options.arch:
|
| - build_config = utils.GetBuildConf(mode, arch)
|
| - if HOST_OS == 'macos':
|
| - project_file = 'dart.xcodeproj'
|
| - if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
|
| - project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
|
| - args = ['xcodebuild',
|
| - '-project',
|
| - project_file,
|
| - '-target',
|
| - target,
|
| - '-parallelizeTargets',
|
| - '-configuration',
|
| - build_config,
|
| - 'SYMROOT=%s' % os.path.abspath('xcodebuild')
|
| - ]
|
| - elif HOST_OS == 'win32':
|
| - project_file = 'dart.sln'
|
| - if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
|
| - project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
|
| - if target == 'all':
|
| - args = [options.devenv + os.sep + 'devenv.com',
|
| - '/build',
|
| + for target_os in options.os:
|
| + for mode in options.mode:
|
| + for arch in options.arch:
|
| + build_config = utils.GetBuildConf(mode, arch)
|
| + if HOST_OS == 'macos':
|
| + project_file = 'dart.xcodeproj'
|
| + if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
|
| + project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
|
| + args = ['xcodebuild',
|
| + '-project',
|
| + project_file,
|
| + '-target',
|
| + target,
|
| + '-parallelizeTargets',
|
| + '-configuration',
|
| build_config,
|
| - project_file
|
| - ]
|
| + 'SYMROOT=%s' % os.path.abspath('xcodebuild')
|
| + ]
|
| + elif HOST_OS == 'win32':
|
| + project_file = 'dart.sln'
|
| + if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
|
| + project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
|
| + if target == 'all':
|
| + args = [options.devenv + os.sep + 'devenv.com',
|
| + '/build',
|
| + build_config,
|
| + project_file
|
| + ]
|
| + else:
|
| + args = [options.devenv + os.sep + 'devenv.com',
|
| + '/build',
|
| + build_config,
|
| + '/project',
|
| + target,
|
| + project_file
|
| + ]
|
| else:
|
| - args = [options.devenv + os.sep + 'devenv.com',
|
| - '/build',
|
| - build_config,
|
| - '/project',
|
| - target,
|
| - project_file
|
| - ]
|
| - else:
|
| - make = 'make'
|
| - if HOST_OS == 'freebsd':
|
| - make = 'gmake'
|
| - # work around lack of flock
|
| - os.environ['LINK'] = '$(CXX)'
|
| - args = [make,
|
| - '-j',
|
| - options.j,
|
| - 'BUILDTYPE=' + build_config,
|
| - ]
|
| - if options.verbose:
|
| - args += ['V=1']
|
| -
|
| - args += [target]
|
| -
|
| - toolsOverride = setTools(arch)
|
| - if toolsOverride:
|
| - for k, v in toolsOverride.iteritems():
|
| - args.append( k + "=" + v)
|
| - print k + " = " + v
|
| -
|
| - print ' '.join(args)
|
| - process = subprocess.Popen(args)
|
| - process.wait()
|
| - if process.returncode != 0:
|
| - print "BUILD FAILED"
|
| - return 1
|
| + make = 'make'
|
| + if HOST_OS == 'freebsd':
|
| + make = 'gmake'
|
| + # work around lack of flock
|
| + os.environ['LINK'] = '$(CXX)'
|
| + args = [make,
|
| + '-j',
|
| + options.j,
|
| + 'BUILDTYPE=' + build_config,
|
| + ]
|
| + if target_os != HOST_OS:
|
| + args += ['builddir_name=' + utils.GetBuildDir(HOST_OS, target_os)]
|
| + if options.verbose:
|
| + args += ['V=1']
|
| +
|
| + args += [target]
|
| +
|
| + if target_os != HOST_OS:
|
| + SetCrossCompilationEnvironment(
|
| + HOST_OS, target_os, arch, old_path)
|
| +
|
| + RunhooksIfNeeded(HOST_OS, mode, arch, target_os)
|
| +
|
| + toolchainprefix = None
|
| + if target_os == 'android':
|
| + toolchainprefix = ('%s/i686-linux-android'
|
| + % os.environ['ANDROID_TOOLCHAIN'])
|
| + toolsOverride = SetTools(arch, toolchainprefix)
|
| + if toolsOverride:
|
| + printToolOverrides = target_os != 'android'
|
| + for k, v in toolsOverride.iteritems():
|
| + args.append( k + "=" + v)
|
| + if printToolOverrides:
|
| + print k + " = " + v
|
| +
|
| + print ' '.join(args)
|
| + process = subprocess.Popen(args)
|
| + process.wait()
|
| + if process.returncode != 0:
|
| + print "BUILD FAILED"
|
| + return 1
|
|
|
| return 0
|
|
|
|
|