3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
7 # This script is wrapper for Crosswalk that adds some support for how GYP
8 # is invoked by Chromium beyond what can be done in the gclient hooks.
18 xwalk_dir = os.path.dirname(os.path.realpath(__file__))
19 chrome_src = os.path.abspath(os.path.join(xwalk_dir, os.pardir))
21 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
24 sys.path.insert(0, os.path.join(chrome_src, 'build'))
25 import gyp_environment
28 # Assume this file is in a one-level-deep subdirectory of the source root.
29 SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
31 # Add paths so that pymod_do_main(...) can import files.
32 sys.path.insert(1, os.path.join(chrome_src, 'build', 'android', 'gyp'))
33 sys.path.insert(1, os.path.join(chrome_src, 'tools'))
34 sys.path.insert(1, os.path.join(chrome_src, 'tools', 'generate_shim_headers'))
35 sys.path.insert(1, os.path.join(chrome_src, 'tools', 'grit'))
36 sys.path.insert(1, os.path.join(chrome_src, 'chrome', 'tools', 'build'))
37 sys.path.insert(1, os.path.join(chrome_src, 'chromecast', 'tools', 'build'))
38 sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
39 sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src',
41 sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
42 sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
43 sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
44 'Source', 'build', 'scripts'))
46 # On Windows, Psyco shortens warm runs of build/gyp_chromium by about
47 # 20 seconds on a z600 machine with 12 GB of RAM, from 90 down to 70
48 # seconds. Conversely, memory usage of build/gyp_chromium with Psyco
49 # maxes out at about 158 MB vs. 132 MB without it.
51 # Psyco uses native libraries, so we need to load a different
52 # installation depending on which OS we are running under. It has not
53 # been tested whether using Psyco on our Mac and Linux builds is worth
54 # it (the GYP running time is a lot shorter, so the JIT startup cost
55 # may not be worth it).
56 if sys.platform == 'win32':
58 sys.path.insert(0, os.path.join(chrome_src, 'third_party', 'psyco_win32'))
66 def GetSupplementalFiles():
67 """Returns a list of the supplemental files that are included in all GYP
69 return glob.glob(os.path.join(chrome_src, '*', 'supplement.gypi'))
72 def ProcessGypDefinesItems(items):
73 """Converts a list of strings to a list of key-value pairs."""
76 tokens = item.split('=', 1)
77 # Some GYP variables have hyphens, which we don't support.
79 result += [(tokens[0], tokens[1])]
81 # No value supplied, treat it as a boolean and set it. Note that we
82 # use the string '1' here so we have a consistent definition whether
83 # you do 'foo=1' or 'foo'.
84 result += [(tokens[0], '1')]
88 def GetGypVars(supplemental_files):
89 """Returns a dictionary of all GYP vars."""
90 # Find the .gyp directory in the user's home directory.
91 home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None)
93 home_dot_gyp = os.path.expanduser(home_dot_gyp)
96 if sys.platform in ('cygwin', 'win32'):
97 home_vars.append('USERPROFILE')
98 for home_var in home_vars:
99 home = os.getenv(home_var)
101 home_dot_gyp = os.path.join(home, '.gyp')
102 if not os.path.exists(home_dot_gyp):
108 include_gypi = os.path.join(home_dot_gyp, "include.gypi")
109 if os.path.exists(include_gypi):
110 supplemental_files += [include_gypi]
112 # GYP defines from the supplemental.gypi files.
114 for supplement in supplemental_files:
115 with open(supplement, 'r') as f:
117 file_data = eval(f.read(), {'__builtins__': None}, None)
118 except SyntaxError, e:
119 e.filename = os.path.abspath(supplement)
121 variables = file_data.get('variables', [])
123 supp_items += [(v, str(variables[v]))]
125 # GYP defines from the environment.
126 env_items = ProcessGypDefinesItems(
127 shlex.split(os.environ.get('GYP_DEFINES', '')))
129 # GYP defines from the command line. We can't use optparse since we want
130 # to ignore all arguments other than "-D".
131 cmdline_input_items = []
132 for i in range(len(sys.argv))[1:]:
133 if sys.argv[i].startswith('-D'):
134 if sys.argv[i] == '-D' and i + 1 < len(sys.argv):
135 cmdline_input_items += [sys.argv[i + 1]]
136 elif len(sys.argv[i]) > 2:
137 cmdline_input_items += [sys.argv[i][2:]]
138 cmdline_items = ProcessGypDefinesItems(cmdline_input_items)
140 vars_dict = dict(supp_items + env_items + cmdline_items)
144 def GetOutputDirectory():
145 """Returns the output directory that GYP will use."""
146 # GYP generator flags from the command line. We can't use optparse since we
147 # want to ignore all arguments other than "-G".
148 needle = '-Goutput_dir='
149 cmdline_input_items = []
150 for item in sys.argv[1:]:
151 if item.startswith(needle):
152 return item[len(needle):]
154 env_items = shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', ''))
155 needle = 'output_dir='
156 for item in env_items:
157 if item.startswith(needle):
158 return item[len(needle):]
163 def additional_include_files(supplemental_files, args=[]):
165 Returns a list of additional (.gypi) files to include, without duplicating
166 ones that are already specified on the command line. The list of supplemental
167 include files is passed in as an argument.
169 # Determine the include files specified on the command line.
170 # This doesn't cover all the different option formats you can use,
171 # but it's mainly intended to avoid duplicating flags on the automatic
172 # makefile regeneration which only uses this format.
173 specified_includes = set()
175 if arg.startswith('-I') and len(arg) > 2:
176 specified_includes.add(os.path.realpath(arg[2:]))
179 def AddInclude(path):
180 if os.path.realpath(path) not in specified_includes:
183 if os.environ.get('GYP_INCLUDE_FIRST') != None:
184 AddInclude(os.path.join(chrome_src, os.environ.get('GYP_INCLUDE_FIRST')))
186 # Include xwalk common.gypi to effect chromium source tree.
187 AddInclude(os.path.join(xwalk_dir, 'build', 'common.gypi'))
189 # Always include common.gypi.
190 AddInclude(os.path.join(chrome_src, 'build', 'common.gypi'))
192 # Optionally add supplemental .gypi files if present.
193 for supplement in supplemental_files:
194 AddInclude(supplement)
196 if os.environ.get('GYP_INCLUDE_LAST') != None:
197 AddInclude(os.path.join(chrome_src, os.environ.get('GYP_INCLUDE_LAST')))
202 if __name__ == '__main__':
203 # Disabling garbage collection saves about 1 second out of 16 on a Linux
204 # z620 workstation. Since this is a short-lived process it's not a problem to
205 # leak a few cyclyc references in order to spare the CPU cycles for
212 use_analyzer = len(args) and args[0] == '--analyzer'
215 os.environ['GYP_GENERATORS'] = 'analyzer'
216 args.append('-Gconfig_path=' + args.pop(0))
217 args.append('-Ganalyzer_output_path=' + args.pop(0))
219 if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)):
220 print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.'
223 # Support external media types capability such as MP4/MP3.
224 args = list(set(args))
226 ip_media_codecs = False # Default: no third-party codecs be build in.
228 if arg.startswith('-Dproprietary_codecs') or arg.startswith('-Dffmpeg_branding'):
230 elif arg == '-Dmediacodecs_EULA=1':
231 ip_media_codecs = True # Exception: mediacodecs_EULA be enabled.
236 args.append('-Dproprietary_codecs=1')
238 # Triggering media playback dynamically with third-party codecs by owner.
239 if ip_media_codecs == True:
240 args.append('-Dffmpeg_branding=Chrome')
242 # Use the Psyco JIT if available.
245 print "Enabled Psyco JIT."
247 # Fall back on hermetic python if we happen to get run under cygwin.
248 # TODO(bradnelson): take this out once this issue is fixed:
249 # http://code.google.com/p/gyp/issues/detail?id=177
250 if sys.platform == 'cygwin':
251 import find_depot_tools
252 depot_tools_path = find_depot_tools.add_depot_tools_to_path()
253 python_dir = sorted(glob.glob(os.path.join(depot_tools_path,
254 'python2*_bin')))[-1]
255 env = os.environ.copy()
256 env['PATH'] = python_dir + os.pathsep + env.get('PATH', '')
257 p = subprocess.Popen(
258 [os.path.join(python_dir, 'python.exe')] + sys.argv,
259 env=env, shell=False)
261 sys.exit(p.returncode)
263 # This could give false positives since it doesn't actually do real option
265 gyp_file_specified = False
267 if arg.endswith('.gyp'):
268 gyp_file_specified = True
271 gyp_environment.SetEnvironment()
273 # If we didn't get a file, check an env var, and then fall back to
274 # assuming 'all.gyp' from the same directory as the script.
275 if not gyp_file_specified:
276 gyp_file = os.environ.get('CHROMIUM_GYP_FILE')
278 # Note that CHROMIUM_GYP_FILE values can't have backslashes as
279 # path separators even on Windows due to the use of shlex.split().
280 args.extend(shlex.split(gyp_file))
282 args.append(os.path.join(xwalk_dir, 'xwalk.gyp'))
284 # There shouldn't be a circular dependency relationship between .gyp files,
285 # but in Chromium's .gyp files, on non-Mac platforms, circular relationships
286 # currently exist. The check for circular dependencies is currently
287 # bypassed on other platforms, but is left enabled on the Mac, where a
288 # violation of the rule causes Xcode to misbehave badly.
289 # TODO(mark): Find and kill remaining circular dependencies, and remove this
290 # option. http://crbug.com/35878.
291 # TODO(tc): Fix circular dependencies in ChromiumOS then add linux2 to the
293 # TODO(tmpsantos): Make runtime a proper module and enable the circular check
295 args.append('--no-circular-check')
297 # We explicitly don't support the make gyp generator (crbug.com/348686). Be
298 # nice and fail here, rather than choking in gyp.
299 if re.search(r'(^|,|\s)make($|,|\s)', os.environ.get('GYP_GENERATORS', '')):
300 print 'Error: make gyp generator not supported (check GYP_GENERATORS).'
303 # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
304 # to enfore syntax checking.
305 syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK')
306 if syntax_check and int(syntax_check):
307 args.append('--check')
309 supplemental_includes = GetSupplementalFiles()
310 gyp_vars_dict = GetGypVars(supplemental_includes)
312 # TODO(dmikurube): Remove these checks and messages after a while.
313 if ('linux_use_tcmalloc' in gyp_vars_dict or
314 'android_use_tcmalloc' in gyp_vars_dict):
315 print '*****************************************************************'
316 print '"linux_use_tcmalloc" and "android_use_tcmalloc" are deprecated!'
317 print '-----------------------------------------------------------------'
318 print 'You specify "linux_use_tcmalloc" or "android_use_tcmalloc" in'
319 print 'your GYP_DEFINES. Please switch them into "use_allocator" now.'
320 print 'See http://crbug.com/345554 for the details.'
321 print '*****************************************************************'
323 # Automatically turn on crosscompile support for platforms that need it.
324 # (The Chrome OS build sets CC_host / CC_target which implicitly enables
326 if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
327 gyp_vars_dict.get('OS') in ['android', 'ios'],
328 'GYP_CROSSCOMPILE' not in os.environ)):
329 os.environ['GYP_CROSSCOMPILE'] = '1'
330 if gyp_vars_dict.get('OS') == 'android':
331 args.append('--check')
334 ['-I' + i for i in additional_include_files(supplemental_includes, args)])
336 args.extend(['-D', 'gyp_output_dir=' + GetOutputDirectory()])
338 # Enable Web Audio by default on Android x86
339 if gyp_vars_dict.get('OS') == 'android':
340 args.append('-Duse_openmax_dl_fft=1')
342 # Enable Aura by default on all platforms except Android and Mac.
343 if gyp_vars_dict.get('OS') != 'android' and sys.platform not in ('darwin',):
344 args.append('-Duse_aura=1')
346 if gyp_vars_dict.get('OS') == 'android':
347 args.append('-Dnotifications=1')
348 args.append('-Drelease_unwind_tables=0')
351 print 'Updating projects from gyp files...'
355 gyp_rc = gyp.main(args)
358 vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
359 if vs2013_runtime_dll_dirs:
360 x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
361 vs_toolchain.CopyVsRuntimeDlls(
362 os.path.join(chrome_src, GetOutputDirectory()),
363 (x86_runtime, x64_runtime))