14467eccaad29fc63a06686675933db6950323a8
[platform/upstream/nodejs.git] / deps / v8 / build / gyp_v8
1 #!/usr/bin/env python
2 #
3 # Copyright 2012 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 #     * Redistributions of source code must retain the above copyright
9 #       notice, this list of conditions and the following disclaimer.
10 #     * Redistributions in binary form must reproduce the above
11 #       copyright notice, this list of conditions and the following
12 #       disclaimer in the documentation and/or other materials provided
13 #       with the distribution.
14 #     * Neither the name of Google Inc. nor the names of its
15 #       contributors may be used to endorse or promote products derived
16 #       from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 # This script is wrapper for V8 that adds some support for how GYP
31 # is invoked by V8 beyond what can be done in the gclient hooks.
32
33 import glob
34 import os
35 import platform
36 import shlex
37 import subprocess
38 import sys
39
40 script_dir = os.path.dirname(os.path.realpath(__file__))
41 v8_root = os.path.abspath(os.path.join(script_dir, os.pardir))
42
43 sys.path.insert(0, os.path.join(v8_root, 'build', 'gyp', 'pylib'))
44 import gyp
45
46 # Add paths so that pymod_do_main(...) can import files.
47 sys.path.insert(
48     1, os.path.abspath(os.path.join(v8_root, 'tools', 'generate_shim_headers')))
49
50
51 def apply_gyp_environment(file_path=None):
52   """
53   Reads in a *.gyp_env file and applies the valid keys to os.environ.
54   """
55   if not file_path or not os.path.exists(file_path):
56     return
57   file_contents = open(file_path).read()
58   try:
59     file_data = eval(file_contents, {'__builtins__': None}, None)
60   except SyntaxError, e:
61     e.filename = os.path.abspath(file_path)
62     raise
63   supported_vars = ( 'V8_GYP_FILE',
64                      'V8_GYP_SYNTAX_CHECK',
65                      'GYP_DEFINES',
66                      'GYP_GENERATOR_FLAGS',
67                      'GYP_GENERATOR_OUTPUT', )
68   for var in supported_vars:
69     val = file_data.get(var)
70     if val:
71       if var in os.environ:
72         print 'INFO: Environment value for "%s" overrides value in %s.' % (
73             var, os.path.abspath(file_path)
74         )
75       else:
76         os.environ[var] = val
77
78
79 def additional_include_files(args=[]):
80   """
81   Returns a list of additional (.gypi) files to include, without
82   duplicating ones that are already specified on the command line.
83   """
84   # Determine the include files specified on the command line.
85   # This doesn't cover all the different option formats you can use,
86   # but it's mainly intended to avoid duplicating flags on the automatic
87   # makefile regeneration which only uses this format.
88   specified_includes = set()
89   for arg in args:
90     if arg.startswith('-I') and len(arg) > 2:
91       specified_includes.add(os.path.realpath(arg[2:]))
92
93   result = []
94   def AddInclude(path):
95     if os.path.realpath(path) not in specified_includes:
96       result.append(path)
97
98   # Always include standalone.gypi
99   AddInclude(os.path.join(v8_root, 'build', 'standalone.gypi'))
100
101   # Optionally add supplemental .gypi files if present.
102   supplements = glob.glob(os.path.join(v8_root, '*', 'supplement.gypi'))
103   for supplement in supplements:
104     AddInclude(supplement)
105
106   return result
107
108
109 def run_gyp(args):
110   rc = gyp.main(args)
111
112   # Check for landmines (reasons to clobber the build). This must be run here,
113   # rather than a separate runhooks step so that any environment modifications
114   # from above are picked up.
115   print 'Running build/landmines.py...'
116   subprocess.check_call(
117       [sys.executable, os.path.join(script_dir, 'landmines.py')])
118
119   if rc != 0:
120     print 'Error running GYP'
121     sys.exit(rc)
122
123
124 if __name__ == '__main__':
125   args = sys.argv[1:]
126
127   if 'SKIP_V8_GYP_ENV' not in os.environ:
128     # Update the environment based on v8.gyp_env
129     gyp_env_path = os.path.join(os.path.dirname(v8_root), 'v8.gyp_env')
130     apply_gyp_environment(gyp_env_path)
131
132   # This could give false positives since it doesn't actually do real option
133   # parsing.  Oh well.
134   gyp_file_specified = False
135   for arg in args:
136     if arg.endswith('.gyp'):
137       gyp_file_specified = True
138       break
139
140   # If we didn't get a file, check an env var, and then fall back to
141   # assuming 'all.gyp' from the same directory as the script.
142   if not gyp_file_specified:
143     gyp_file = os.environ.get('V8_GYP_FILE')
144     if gyp_file:
145       # Note that V8_GYP_FILE values can't have backslashes as
146       # path separators even on Windows due to the use of shlex.split().
147       args.extend(shlex.split(gyp_file))
148     else:
149       args.append(os.path.join(script_dir, 'all.gyp'))
150
151   args.extend(['-I' + i for i in additional_include_files(args)])
152
153   # There shouldn't be a circular dependency relationship between .gyp files
154   args.append('--no-circular-check')
155
156   # Set the GYP DEPTH variable to the root of the V8 project.
157   args.append('--depth=' + os.path.relpath(v8_root))
158
159   # If V8_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
160   # to enfore syntax checking.
161   syntax_check = os.environ.get('V8_GYP_SYNTAX_CHECK')
162   if syntax_check and int(syntax_check):
163     args.append('--check')
164
165   print 'Updating projects from gyp files...'
166   sys.stdout.flush()
167
168   # Generate for the architectures supported on the given platform.
169   gyp_args = list(args)
170   gyp_generators = os.environ.get('GYP_GENERATORS')
171   if platform.system() == 'Linux' and gyp_generators != 'ninja':
172     # Work around for crbug.com/331475.
173     for f in glob.glob(os.path.join(v8_root, 'out', 'Makefile.*')):
174       os.unlink(f)
175     # --generator-output defines where the Makefile goes.
176     gyp_args.append('--generator-output=out')
177     # -Goutput_dir defines where the build output goes, relative to the
178     # Makefile. Set it to . so that the build output doesn't end up in out/out.
179     gyp_args.append('-Goutput_dir=.')
180   run_gyp(gyp_args)