Do not download clang on Windows
[platform/framework/web/crosswalk-tizen.git] / script / bootstrap.py
1 #!/usr/bin/env python
2
3 import argparse
4 import os
5 import subprocess
6 import sys
7
8 from lib.config import LIBCHROMIUMCONTENT_COMMIT, BASE_URL, PLATFORM, \
9                        enable_verbose_mode, is_verbose_mode, get_target_arch
10 from lib.util import execute_stdout, get_atom_shell_version, scoped_cwd
11
12
13 SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
14 VENDOR_DIR = os.path.join(SOURCE_ROOT, 'vendor')
15 PYTHON_26_URL = 'https://chromium.googlesource.com/chromium/deps/python_26'
16
17 if os.environ.has_key('CI'):
18   NPM = os.path.join(SOURCE_ROOT, 'node_modules', '.bin', 'npm')
19 else:
20   NPM = 'npm'
21 if sys.platform in ['win32', 'cygwin']:
22   NPM += '.cmd'
23
24
25 def main():
26   os.chdir(SOURCE_ROOT)
27
28   args = parse_args()
29   defines = args_to_defines(args)
30   if not args.yes and PLATFORM != 'win32':
31     check_root()
32   if args.verbose:
33     enable_verbose_mode()
34   if sys.platform == 'cygwin':
35     update_win32_python()
36
37   update_submodules()
38
39   libcc_source_path = args.libcc_source_path
40   libcc_shared_library_path = args.libcc_shared_library_path
41   libcc_static_library_path = args.libcc_static_library_path
42
43   # Redirect to use local libchromiumcontent build.
44   if args.build_libchromiumcontent:
45     build_libchromiumcontent(args.verbose, args.target_arch, defines)
46     dist_dir = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
47                             'libchromiumcontent', 'dist', 'main')
48     libcc_source_path = os.path.join(dist_dir, 'src')
49     libcc_shared_library_path = os.path.join(dist_dir, 'shared_library')
50     libcc_static_library_path = os.path.join(dist_dir, 'static_library')
51
52   if PLATFORM != 'win32':
53     # Download prebuilt clang binaries.
54     update_clang()
55     if not args.disable_clang and args.clang_dir == '':
56       # Build with prebuilt clang.
57       set_clang_env(os.environ)
58
59   setup_python_libs()
60   update_node_modules('.')
61   bootstrap_brightray(args.dev, args.url, args.target_arch,
62                       libcc_source_path, libcc_shared_library_path,
63                       libcc_static_library_path)
64
65   if PLATFORM == 'linux':
66     download_sysroot(args.target_arch)
67
68   create_chrome_version_h()
69   touch_config_gypi()
70   run_update(defines)
71   update_electron_modules('spec', args.target_arch)
72
73
74 def parse_args():
75   parser = argparse.ArgumentParser(description='Bootstrap this project')
76   parser.add_argument('-u', '--url',
77                       help='The base URL from which to download '
78                       'libchromiumcontent (i.e., the URL you passed to '
79                       'libchromiumcontent\'s script/upload script',
80                       default=BASE_URL,
81                       required=False)
82   parser.add_argument('-v', '--verbose',
83                       action='store_true',
84                       help='Prints the output of the subprocesses')
85   parser.add_argument('-d', '--dev', action='store_true',
86                       help='Do not download static_library build')
87   parser.add_argument('-y', '--yes', '--assume-yes',
88                       action='store_true',
89                       help='Run non-interactively by assuming "yes" to all ' \
90                            'prompts.')
91   parser.add_argument('--target_arch', default=get_target_arch(),
92                       help='Manually specify the arch to build for')
93   parser.add_argument('--clang_dir', default='', help='Path to clang binaries')
94   parser.add_argument('--disable_clang', action='store_true',
95                       help='Use compilers other than clang for building')
96   parser.add_argument('--build_libchromiumcontent', action='store_true',
97                       help='Build local version of libchromiumcontent')
98   parser.add_argument('--libcc_source_path', required=False,
99                       help='The source path of libchromiumcontent. ' \
100                            'NOTE: All options of libchromiumcontent are ' \
101                            'required OR let electron choose it')
102   parser.add_argument('--libcc_shared_library_path', required=False,
103                       help='The shared library path of libchromiumcontent.')
104   parser.add_argument('--libcc_static_library_path', required=False,
105                       help='The static library path of libchromiumcontent.')
106   return parser.parse_args()
107
108
109 def args_to_defines(args):
110   defines = ''
111   if args.disable_clang:
112     defines += ' clang=0'
113   if args.clang_dir:
114     defines += ' make_clang_dir=' + args.clang_dir
115     defines += ' clang_use_chrome_plugins=0'
116   return defines
117
118
119 def check_root():
120   if os.geteuid() == 0:
121     print "We suggest not running this as root, unless you're really sure."
122     choice = raw_input("Do you want to continue? [y/N]: ")
123     if choice not in ('y', 'Y'):
124       sys.exit(0)
125
126
127 def update_submodules():
128   execute_stdout(['git', 'submodule', 'sync'])
129   execute_stdout(['git', 'submodule', 'update', '--init', '--recursive'])
130
131
132 def setup_python_libs():
133   for lib in ('requests', 'boto'):
134     with scoped_cwd(os.path.join(VENDOR_DIR, lib)):
135       execute_stdout([sys.executable, 'setup.py', 'build'])
136
137
138 def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path,
139                         libcc_shared_library_path,
140                         libcc_static_library_path):
141   bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap')
142   args = [
143     '--commit', LIBCHROMIUMCONTENT_COMMIT,
144     '--target_arch', target_arch,
145     url
146   ]
147   if is_dev:
148     args = ['--dev'] + args
149   if (libcc_source_path != None and
150       libcc_shared_library_path != None and
151       libcc_static_library_path != None):
152     args += ['--libcc_source_path', libcc_source_path,
153              '--libcc_shared_library_path', libcc_shared_library_path,
154              '--libcc_static_library_path', libcc_static_library_path]
155   execute_stdout([sys.executable, bootstrap] + args)
156
157
158 def set_clang_env(env):
159   llvm_dir = os.path.join(SOURCE_ROOT, 'vendor', 'llvm-build',
160                           'Release+Asserts', 'bin')
161   env['CC']  = os.path.join(llvm_dir, 'clang')
162   env['CXX'] = os.path.join(llvm_dir, 'clang++')
163
164
165 def update_node_modules(dirname, env=None):
166   if env is None:
167     env = os.environ.copy()
168   if PLATFORM == 'linux':
169     # Use prebuilt clang for building native modules.
170     set_clang_env(env)
171     env['npm_config_clang'] = '1'
172   with scoped_cwd(dirname):
173     args = [NPM, 'install']
174     if is_verbose_mode():
175       args += ['--verbose']
176     # Ignore npm install errors when running in CI.
177     if os.environ.has_key('CI'):
178       try:
179         execute_stdout(args, env)
180       except subprocess.CalledProcessError:
181         pass
182     else:
183       execute_stdout(args, env)
184
185
186 def update_electron_modules(dirname, target_arch):
187   env = os.environ.copy()
188   env['npm_config_arch']    = target_arch
189   env['npm_config_target']  = get_atom_shell_version()
190   env['npm_config_disturl'] = 'https://atom.io/download/atom-shell'
191   update_node_modules(dirname, env)
192
193
194 def update_win32_python():
195   with scoped_cwd(VENDOR_DIR):
196     if not os.path.exists('python_26'):
197       execute_stdout(['git', 'clone', PYTHON_26_URL])
198
199
200 def build_libchromiumcontent(verbose, target_arch, defines):
201   args = [os.path.join(SOURCE_ROOT, 'script', 'build-libchromiumcontent.py')]
202   if verbose:
203     args += ['-v']
204   if defines:
205     args += ['--defines', defines]
206   execute_stdout(args + ['--target_arch', target_arch])
207
208
209 def update_clang():
210   execute_stdout([os.path.join(SOURCE_ROOT, 'script', 'update-clang.sh')])
211
212
213 def download_sysroot(target_arch):
214   if target_arch == 'ia32':
215     target_arch = 'i386'
216   if target_arch == 'x64':
217     target_arch = 'amd64'
218   execute_stdout([sys.executable,
219                   os.path.join(SOURCE_ROOT, 'script', 'install-sysroot.py'),
220                   '--arch', target_arch])
221
222 def create_chrome_version_h():
223   version_file = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
224                               'libchromiumcontent', 'VERSION')
225   target_file = os.path.join(SOURCE_ROOT, 'atom', 'common', 'chrome_version.h')
226   template_file = os.path.join(SOURCE_ROOT, 'script', 'chrome_version.h.in')
227
228   with open(version_file, 'r') as f:
229     version = f.read()
230   with open(template_file, 'r') as f:
231     template = f.read()
232   content = template.replace('{PLACEHOLDER}', version.strip())
233
234   # We update the file only if the content has changed (ignoring line ending
235   # differences).
236   should_write = True
237   if os.path.isfile(target_file):
238     with open(target_file, 'r') as f:
239       should_write = f.read().replace('r', '') != content.replace('r', '')
240   if should_write:
241     with open(target_file, 'w') as f:
242       f.write(content)
243
244
245 def touch_config_gypi():
246   config_gypi = os.path.join(SOURCE_ROOT, 'vendor', 'node', 'config.gypi')
247   with open(config_gypi, 'w+') as f:
248     content = "\n{'variables':{}}"
249     if f.read() != content:
250       f.write(content)
251
252
253 def run_update(defines):
254   update = os.path.join(SOURCE_ROOT, 'script', 'update.py')
255   execute_stdout([sys.executable, update, '--defines', defines])
256
257
258 if __name__ == '__main__':
259   sys.exit(main())