Merge pull request #8718 from demopark/master
[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_electron_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 NPM = 'npm'
18 if sys.platform in ['win32', 'cygwin']:
19   NPM += '.cmd'
20
21
22 def main():
23   os.chdir(SOURCE_ROOT)
24
25   args = parse_args()
26   defines = args_to_defines(args)
27   if not args.yes and PLATFORM != 'win32':
28     check_root()
29   if args.verbose:
30     enable_verbose_mode()
31   if sys.platform == 'cygwin':
32     update_win32_python()
33
34   update_submodules()
35
36   libcc_source_path = args.libcc_source_path
37   libcc_shared_library_path = args.libcc_shared_library_path
38   libcc_static_library_path = args.libcc_static_library_path
39
40   # Redirect to use local libchromiumcontent build.
41   if args.build_libchromiumcontent:
42     build_libchromiumcontent(args.verbose, args.target_arch, defines)
43     dist_dir = os.path.join(SOURCE_ROOT, 'vendor', 'brightray', 'vendor',
44                             'libchromiumcontent', 'dist', 'main')
45     libcc_source_path = os.path.join(dist_dir, 'src')
46     libcc_shared_library_path = os.path.join(dist_dir, 'shared_library')
47     libcc_static_library_path = os.path.join(dist_dir, 'static_library')
48
49   if PLATFORM != 'win32':
50     if not args.disable_clang and args.clang_dir == '':
51       # Download prebuilt clang binaries.
52       update_clang()
53
54   setup_python_libs()
55   update_node_modules('.')
56   bootstrap_brightray(args.dev, args.url, args.target_arch,
57                       libcc_source_path, libcc_shared_library_path,
58                       libcc_static_library_path)
59
60   if PLATFORM == 'linux':
61     download_sysroot(args.target_arch)
62
63   create_chrome_version_h()
64   touch_config_gypi()
65   run_update(defines, args.msvs)
66   update_electron_modules('spec', args.target_arch)
67
68
69 def parse_args():
70   parser = argparse.ArgumentParser(description='Bootstrap this project')
71   parser.add_argument('-u', '--url',
72                       help='The base URL from which to download '
73                       'libchromiumcontent (i.e., the URL you passed to '
74                       'libchromiumcontent\'s script/upload script',
75                       default=BASE_URL,
76                       required=False)
77   parser.add_argument('-v', '--verbose',
78                       action='store_true',
79                       help='Prints the output of the subprocesses')
80   parser.add_argument('-d', '--dev', action='store_true',
81                       help='Do not download static_library build')
82   parser.add_argument('-y', '--yes', '--assume-yes',
83                       action='store_true',
84                       help='Run non-interactively by assuming "yes" to all ' \
85                            'prompts.')
86   parser.add_argument('--msvs', action='store_true',
87                       help='Generate Visual Studio project')
88   parser.add_argument('--target_arch', default=get_target_arch(),
89                       help='Manually specify the arch to build for')
90   parser.add_argument('--clang_dir', default='', help='Path to clang binaries')
91   parser.add_argument('--disable_clang', action='store_true',
92                       help='Use compilers other than clang for building')
93   parser.add_argument('--build_libchromiumcontent', action='store_true',
94                       help='Build local version of libchromiumcontent')
95   parser.add_argument('--libcc_source_path', required=False,
96                       help='The source path of libchromiumcontent. ' \
97                            'NOTE: All options of libchromiumcontent are ' \
98                            'required OR let electron choose it')
99   parser.add_argument('--libcc_shared_library_path', required=False,
100                       help='The shared library path of libchromiumcontent.')
101   parser.add_argument('--libcc_static_library_path', required=False,
102                       help='The static library path of libchromiumcontent.')
103   parser.add_argument('--defines', default='',
104                       help='The build variables passed to gyp')
105   return parser.parse_args()
106
107
108 def args_to_defines(args):
109   defines = args.defines
110   if args.disable_clang:
111     defines += ' clang=0'
112   if args.clang_dir:
113     defines += ' make_clang_dir=' + args.clang_dir
114     defines += ' clang_use_chrome_plugins=0'
115   return defines
116
117
118 def check_root():
119   if os.geteuid() == 0:
120     print "We suggest not running this as root, unless you're really sure."
121     choice = raw_input("Do you want to continue? [y/N]: ")
122     if choice not in ('y', 'Y'):
123       sys.exit(0)
124
125
126 def update_submodules():
127   execute_stdout(['git', 'submodule', 'sync', '--recursive'])
128   execute_stdout(['git', 'submodule', 'update', '--init', '--recursive'])
129
130
131 def setup_python_libs():
132   for lib in ('requests', 'boto'):
133     with scoped_cwd(os.path.join(VENDOR_DIR, lib)):
134       execute_stdout([sys.executable, 'setup.py', 'build'])
135
136
137 def bootstrap_brightray(is_dev, url, target_arch, libcc_source_path,
138                         libcc_shared_library_path,
139                         libcc_static_library_path):
140   bootstrap = os.path.join(VENDOR_DIR, 'brightray', 'script', 'bootstrap')
141   args = [
142     '--commit', LIBCHROMIUMCONTENT_COMMIT,
143     '--target_arch', target_arch,
144     url
145   ]
146   if is_dev:
147     args = ['--dev'] + args
148   if (libcc_source_path != None and
149       libcc_shared_library_path != None and
150       libcc_static_library_path != None):
151     args += ['--libcc_source_path', libcc_source_path,
152              '--libcc_shared_library_path', libcc_shared_library_path,
153              '--libcc_static_library_path', libcc_static_library_path]
154   execute_stdout([sys.executable, bootstrap] + args)
155
156
157 def set_clang_env(env):
158   llvm_dir = os.path.join(SOURCE_ROOT, 'vendor', 'llvm-build',
159                           'Release+Asserts', 'bin')
160   env['CC']  = os.path.join(llvm_dir, 'clang')
161   env['CXX'] = os.path.join(llvm_dir, 'clang++')
162
163
164 def update_node_modules(dirname, env=None):
165   if env is None:
166     env = os.environ.copy()
167   if PLATFORM == 'linux':
168     # Use prebuilt clang for building native modules.
169     set_clang_env(env)
170     env['npm_config_clang'] = '1'
171   with scoped_cwd(dirname):
172     args = [NPM, 'install']
173     if is_verbose_mode():
174       args += ['--verbose']
175     # Ignore npm install errors when running in CI.
176     if os.environ.has_key('CI'):
177       try:
178         execute_stdout(args, env)
179       except subprocess.CalledProcessError:
180         pass
181     else:
182       execute_stdout(args, env)
183
184
185 def update_electron_modules(dirname, target_arch):
186   env = os.environ.copy()
187   env['npm_config_arch']    = target_arch
188   env['npm_config_target']  = get_electron_version()
189   env['npm_config_disturl'] = 'https://atom.io/download/electron'
190   update_node_modules(dirname, env)
191
192
193 def update_win32_python():
194   with scoped_cwd(VENDOR_DIR):
195     if not os.path.exists('python_26'):
196       execute_stdout(['git', 'clone', PYTHON_26_URL])
197
198
199 def build_libchromiumcontent(verbose, target_arch, defines):
200   args = [sys.executable,
201           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, msvs):
254   args = [sys.executable, os.path.join(SOURCE_ROOT, 'script', 'update.py')]
255   if defines:
256     args += ['--defines', defines]
257   if msvs:
258     args += ['--msvs']
259
260   execute_stdout(args)
261
262
263 if __name__ == '__main__':
264   sys.exit(main())