2011-10-05 05:34:19 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
#
|
2012-11-12 12:55:02 +00:00
|
|
|
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
2011-10-05 05:34:19 +00:00
|
|
|
# for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
# BSD-style license that can be found in the LICENSE file.
|
|
|
|
#
|
|
|
|
|
|
|
|
import optparse
|
|
|
|
import os
|
|
|
|
import shutil
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import utils
|
|
|
|
|
|
|
|
HOST_OS = utils.GuessOS()
|
|
|
|
HOST_CPUS = utils.GuessCpus()
|
|
|
|
armcompilerlocation = '/opt/codesourcery/arm-2009q1'
|
2012-08-29 20:42:28 +00:00
|
|
|
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')
|
2011-10-05 05:34:19 +00:00
|
|
|
|
|
|
|
def BuildOptions():
|
|
|
|
result = optparse.OptionParser()
|
|
|
|
result.add_option("-m", "--mode",
|
|
|
|
help='Build variants (comma-separated).',
|
|
|
|
metavar='[all,debug,release]',
|
|
|
|
default='debug')
|
|
|
|
result.add_option("-v", "--verbose",
|
|
|
|
help='Verbose output.',
|
|
|
|
default=False, action="store_true")
|
2012-11-12 12:55:02 +00:00
|
|
|
result.add_option("-a", "--arch",
|
2011-10-05 05:34:19 +00:00
|
|
|
help='Target architectures (comma-separated).',
|
2013-01-18 21:34:53 +00:00
|
|
|
metavar='[all,ia32,x64,simarm,arm,simmips,mips]',
|
2011-10-05 05:34:19 +00:00
|
|
|
default=utils.GuessArchitecture())
|
2012-08-29 20:42:28 +00:00
|
|
|
result.add_option("--os",
|
|
|
|
help='Target OSs (comma-separated).',
|
|
|
|
metavar='[all,host,android]',
|
|
|
|
default='host')
|
2011-10-05 05:34:19 +00:00
|
|
|
result.add_option("-j",
|
|
|
|
help='The number of parallel jobs to run.',
|
|
|
|
metavar=HOST_CPUS,
|
|
|
|
default=str(HOST_CPUS))
|
|
|
|
result.add_option("--devenv",
|
|
|
|
help='Path containing devenv.com on Windows',
|
2012-10-16 21:28:18 +00:00
|
|
|
default='C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7'
|
|
|
|
'\\IDE')
|
|
|
|
result.add_option("--executable",
|
|
|
|
help='Name of the devenv.com/msbuild executable on Windows (varies for '
|
|
|
|
'different versions of Visual Studio)', default='devenv.com')
|
2011-10-05 05:34:19 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
2012-08-29 20:42:28 +00:00
|
|
|
def ProcessOsOption(os):
|
|
|
|
if os == 'host':
|
|
|
|
return HOST_OS
|
|
|
|
return os
|
|
|
|
|
|
|
|
|
|
|
|
def ProcessOptions(options, args):
|
2011-10-05 05:34:19 +00:00
|
|
|
if options.arch == 'all':
|
2012-03-03 01:44:24 +00:00
|
|
|
options.arch = 'ia32,x64'
|
2011-10-05 05:34:19 +00:00
|
|
|
if options.mode == 'all':
|
2011-12-01 12:58:53 +00:00
|
|
|
options.mode = 'release,debug'
|
2012-08-29 20:42:28 +00:00
|
|
|
if options.os == 'all':
|
|
|
|
options.os = 'host,android'
|
2011-10-05 05:34:19 +00:00
|
|
|
options.mode = options.mode.split(',')
|
|
|
|
options.arch = options.arch.split(',')
|
2012-08-29 20:42:28 +00:00
|
|
|
options.os = options.os.split(',')
|
2011-10-05 05:34:19 +00:00
|
|
|
for mode in options.mode:
|
|
|
|
if not mode in ['debug', 'release']:
|
|
|
|
print "Unknown mode %s" % mode
|
|
|
|
return False
|
|
|
|
for arch in options.arch:
|
2013-01-18 21:34:53 +00:00
|
|
|
if not arch in ['ia32', 'x64', 'simarm', 'arm', 'simmips', 'mips']:
|
2011-10-05 05:34:19 +00:00
|
|
|
print "Unknown arch %s" % arch
|
|
|
|
return False
|
2012-08-29 20:42:28 +00:00
|
|
|
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
|
2011-10-05 05:34:19 +00:00
|
|
|
return True
|
|
|
|
|
|
|
|
|
2012-08-29 20:42:28 +00:00
|
|
|
def SetTools(arch, toolchainprefix):
|
|
|
|
toolsOverride = None
|
|
|
|
if arch == 'arm' and toolchainprefix == None:
|
|
|
|
toolchainprefix = armcompilerlocation + "/bin/arm-none-linux-gnueabi"
|
|
|
|
if toolchainprefix:
|
2011-10-05 05:34:19 +00:00
|
|
|
toolsOverride = {
|
2012-08-29 20:42:28 +00:00
|
|
|
"CC" : toolchainprefix + "-gcc",
|
|
|
|
"CXX" : toolchainprefix + "-g++",
|
|
|
|
"AR" : toolchainprefix + "-ar",
|
|
|
|
"LINK": toolchainprefix + "-g++",
|
|
|
|
"NM" : toolchainprefix + "-nm",
|
2011-10-05 05:34:19 +00:00
|
|
|
}
|
2012-08-29 20:42:28 +00:00
|
|
|
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)
|
2011-10-05 05:34:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
def Execute(args):
|
|
|
|
process = subprocess.Popen(args)
|
|
|
|
process.wait()
|
|
|
|
if process.returncode != 0:
|
2012-12-06 08:54:40 +00:00
|
|
|
raise Exception(args[0] + " failed")
|
2011-10-05 05:34:19 +00:00
|
|
|
|
|
|
|
|
2012-08-29 20:42:28 +00:00
|
|
|
def GClientRunHooks():
|
|
|
|
Execute(['gclient', 'runhooks'])
|
|
|
|
|
|
|
|
|
|
|
|
def RunhooksIfNeeded(host_os, mode, arch, target_os):
|
2012-08-29 20:52:08 +00:00
|
|
|
if host_os != 'linux':
|
|
|
|
return
|
2012-08-29 20:42:28 +00:00
|
|
|
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()
|
|
|
|
|
|
|
|
|
2011-10-05 05:34:19 +00:00
|
|
|
def CurrentDirectoryBaseName():
|
|
|
|
"""Returns the name of the current directory"""
|
|
|
|
return os.path.relpath(os.curdir, start=os.pardir)
|
|
|
|
|
2012-08-29 20:42:28 +00:00
|
|
|
|
2011-10-05 05:34:19 +00:00
|
|
|
def Main():
|
|
|
|
utils.ConfigureJava()
|
|
|
|
# Parse the options.
|
|
|
|
parser = BuildOptions()
|
|
|
|
(options, args) = parser.parse_args()
|
2012-08-29 20:42:28 +00:00
|
|
|
if not ProcessOptions(options, args):
|
2011-10-05 05:34:19 +00:00
|
|
|
parser.print_help()
|
|
|
|
return 1
|
|
|
|
# Determine which targets to build. By default we build the "all" target.
|
|
|
|
if len(args) == 0:
|
|
|
|
if HOST_OS == 'macos':
|
|
|
|
target = 'All'
|
|
|
|
else:
|
|
|
|
target = 'all'
|
|
|
|
else:
|
|
|
|
target = args[0]
|
2012-08-29 20:42:28 +00:00
|
|
|
|
|
|
|
# Remember path
|
|
|
|
old_path = os.environ['PATH']
|
2011-10-05 05:34:19 +00:00
|
|
|
# Build the targets for each requested configuration.
|
2012-08-29 20:42:28 +00:00
|
|
|
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,
|
|
|
|
'-configuration',
|
2011-12-20 18:16:11 +00:00
|
|
|
build_config,
|
2012-08-29 20:42:28 +00:00
|
|
|
'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':
|
2012-10-16 21:28:18 +00:00
|
|
|
args = [options.devenv + os.sep + options.executable,
|
2012-08-29 20:42:28 +00:00
|
|
|
'/build',
|
|
|
|
build_config,
|
|
|
|
project_file
|
|
|
|
]
|
|
|
|
else:
|
2012-10-16 21:28:18 +00:00
|
|
|
args = [options.devenv + os.sep + options.executable,
|
2012-08-29 20:42:28 +00:00
|
|
|
'/build',
|
|
|
|
build_config,
|
|
|
|
'/project',
|
|
|
|
target,
|
|
|
|
project_file
|
|
|
|
]
|
2011-12-20 18:47:16 +00:00
|
|
|
else:
|
2012-08-29 20:42:28 +00:00
|
|
|
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)
|
2012-10-23 09:20:03 +00:00
|
|
|
process = subprocess.Popen(args)
|
2012-08-29 20:42:28 +00:00
|
|
|
process.wait()
|
|
|
|
if process.returncode != 0:
|
|
|
|
print "BUILD FAILED"
|
|
|
|
return 1
|
2011-10-05 05:34:19 +00:00
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
sys.exit(Main())
|