1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import optparse
7import os
8import sys
9import tarfile
10
11import buildbot_common
12from build_paths import SCRIPT_DIR
13
14SDK_BUILD_DIR = SCRIPT_DIR
15MONO_BUILD_DIR = os.path.join(SDK_BUILD_DIR, 'mono_build')
16MONO_DIR = os.path.join(MONO_BUILD_DIR, 'nacl-mono')
17
18
19def main(args):
20  parser = optparse.OptionParser()
21  parser.add_option('--arch',
22                    help='Target architecture',
23                    dest='arch',
24                    default='x86-32')
25  parser.add_option('--sdk-revision',
26                    help='SDK Revision'
27                         ' (default=buildbot revision)',
28                    dest='sdk_revision',
29                    default=None)
30  parser.add_option('--sdk-url',
31                    help='SDK Download URL',
32                    dest='sdk_url',
33                    default=None)
34  parser.add_option('--install-dir',
35                    help='Install Directory',
36                    dest='install_dir',
37                    default='naclmono')
38  (options, args) = parser.parse_args(args[1:])
39
40  assert sys.platform.find('linux') != -1
41
42  buildbot_revision = os.environ.get('BUILDBOT_REVISION', '')
43
44  build_prefix = options.arch + ' '
45
46  buildbot_common.BuildStep(build_prefix + 'Clean Old SDK')
47  buildbot_common.MakeDir(MONO_BUILD_DIR)
48  buildbot_common.RemoveDir(os.path.join(MONO_BUILD_DIR, 'pepper_*'))
49
50  buildbot_common.BuildStep(build_prefix + 'Setup New SDK')
51  sdk_dir = None
52  sdk_revision = options.sdk_revision
53  sdk_url = options.sdk_url
54  if not sdk_url:
55    if not sdk_revision:
56      assert buildbot_revision
57      sdk_revision = buildbot_revision.split(':')[0]
58    sdk_url = 'gs://nativeclient-mirror/nacl/nacl_sdk/'\
59              'trunk.%s/naclsdk_linux.tar.bz2' % sdk_revision
60
61  sdk_url = sdk_url.replace('https://storage.googleapis.com/', 'gs://')
62
63  sdk_file = sdk_url.split('/')[-1]
64
65  buildbot_common.Run([buildbot_common.GetGsutil(), 'cp', sdk_url, sdk_file],
66                      cwd=MONO_BUILD_DIR)
67  tar_file = None
68  try:
69    tar_file = tarfile.open(os.path.join(MONO_BUILD_DIR, sdk_file))
70    pepper_dir = os.path.commonprefix(tar_file.getnames())
71    tar_file.extractall(path=MONO_BUILD_DIR)
72    sdk_dir = os.path.join(MONO_BUILD_DIR, pepper_dir)
73  finally:
74    if tar_file:
75      tar_file.close()
76
77  assert sdk_dir
78
79  buildbot_common.BuildStep(build_prefix + 'Checkout Mono')
80  # TODO(elijahtaylor): Get git URL from master/trigger to make this
81  # more flexible for building from upstream and release branches.
82  if options.arch == 'arm':
83    git_url = 'git://github.com/igotti-google/mono.git'
84    git_rev = 'arm_nacl'
85  else:
86    git_url = 'git://github.com/elijahtaylor/mono.git'
87    git_rev = 'HEAD'
88  if buildbot_revision:
89    # Unfortunately, we use different git branches/revisions
90    # for ARM and x86 now, so ignore buildbot_revision variable for ARM.
91    # Need to rethink this approach, if we'll plan to support
92    # more flexible repo selection mechanism.
93    if options.arch != 'arm':
94      git_rev = buildbot_revision.split(':')[1]
95  # ARM and x86 is built out of different git trees, so distinguish
96  # them by appending the arch. It also makes 32 and 64 bit x86 separated,
97  # which is good.
98  # TODO(olonho): maybe we need to avoid modifications of global.
99  global MONO_DIR
100  tag = options.arch
101  MONO_DIR = "%s-%s" % (MONO_DIR, tag)
102  if not os.path.exists(MONO_DIR):
103    buildbot_common.MakeDir(MONO_DIR)
104    buildbot_common.Run(['git', 'clone', git_url, MONO_DIR])
105  else:
106    buildbot_common.Run(['git', 'fetch'], cwd=MONO_DIR)
107  if git_rev:
108    buildbot_common.Run(['git', 'checkout', git_rev], cwd=MONO_DIR)
109
110  arch_to_bitsize = {'x86-32': '32',
111                     'x86-64': '64',
112                     'arm':    'arm'}
113  arch_to_output_folder = {'x86-32': 'runtime-x86-32-build',
114                           'x86-64': 'runtime-x86-64-build',
115                           'arm':    'runtime-arm-build'}
116
117  buildbot_common.BuildStep(build_prefix + 'Configure Mono')
118  os.environ['NACL_SDK_ROOT'] = sdk_dir
119  os.environ['TARGET_ARCH'] = options.arch
120  os.environ['TARGET_BITSIZE'] = arch_to_bitsize[options.arch]
121  buildbot_common.Run(['./autogen.sh'], cwd=MONO_DIR)
122  buildbot_common.Run(['make', 'distclean'], cwd=MONO_DIR)
123
124  buildbot_common.BuildStep(build_prefix + 'Build and Install Mono')
125  nacl_interp_script = os.path.join(SDK_BUILD_DIR, 'nacl_interp_loader_mono.sh')
126  os.environ['NACL_INTERP_LOADER'] = nacl_interp_script
127  buildbot_common.Run(['./nacl-mono-runtime.sh',
128                      MONO_DIR, # Mono directory with 'configure'
129                      arch_to_output_folder[options.arch], # Build dir
130                      options.install_dir],
131                      cwd=SDK_BUILD_DIR)
132
133  # TODO(elijahtaylor,olonho): Re-enable tests on arm when they compile/run.
134  if options.arch != 'arm':
135    buildbot_common.BuildStep(build_prefix + 'Test Mono')
136    buildbot_common.Run(['make', 'check', '-j8'],
137        cwd=os.path.join(SDK_BUILD_DIR, arch_to_output_folder[options.arch]))
138
139  return 0
140
141
142if __name__ == '__main__':
143  sys.exit(main(sys.argv))
144