2 # Copyright (c) 2011 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.
14 # Where things are in relation to this script.
15 SCRIPT_DIR
= os
.path
.dirname(os
.path
.abspath(__file__
))
16 SRC_DIR
= os
.path
.dirname(SCRIPT_DIR
)
17 NACL_DIR
= os
.path
.join(SRC_DIR
, 'native_client')
19 # Pathing to the two command_buffer directories (relative to native_client).
20 NACL_CMD_BUFFER_DIR
= os
.path
.join('src', 'shared',
21 'ppapi_proxy', 'command_buffer')
22 GPU_CMD_BUFFER_DIR
= os
.path
.join('..', 'gpu', 'command_buffer')
24 # Pathing to mirror of nacl tree in ppapi.
25 PPAPI_NACL_DIR
= os
.path
.join(SRC_DIR
, 'ppapi', 'native_client')
28 def RelativePath(path
, base
):
29 """Find the relative path.
32 path: path we want a relative path to.
33 base: path we want a relative path from.
35 The relative path from base to path.
37 path
= os
.path
.abspath(path
)
38 base
= os
.path
.abspath(base
)
39 path_parts
= path
.split(os
.sep
)
40 base_parts
= base
.split(os
.sep
)
41 while path_parts
and base_parts
and path_parts
[0] == base_parts
[0]:
42 path_parts
= path_parts
[1:]
43 base_parts
= base_parts
[1:]
44 rel_parts
= ['..'] * len(base_parts
) + path_parts
45 return os
.sep
.join(rel_parts
)
48 def PrintInputs(platforms
):
49 """Print all the transitive inputs required to build the IRT.
52 platforms: list of platform names to build for.
55 for platform
in platforms
:
56 # Invoke scons to get dependency tree.
58 sys
.executable
, 'scons.py', '-n', '--tree=all',
59 '--mode=nacl', 'platform=' + platform
,
60 'scons-out/nacl_irt-' + platform
+ '/staging/irt.nexe',
62 p
= subprocess
.Popen(cmd
, cwd
=NACL_DIR
,
63 stdout
=subprocess
.PIPE
,
64 stderr
=subprocess
.PIPE
)
65 (p_stdout
, p_stderr
) = p
.communicate()
66 # If things fail on windows, try running --help, if that fails,
67 # emit this script as an input (to satiate gyp), and assume we're being
68 # run on a test only bot.
69 # TODO(bradnelson): add plumbing to the buildbots to allow this script
70 # to know its on a test only bot + make scons return a _particular_
71 # return code so we can detect this kind of fail in one step.
72 if p
.returncode
!= 0 and sys
.platform
== 'win32':
73 cmd
= [sys
.executable
, 'scons.py', '--help']
74 p
= subprocess
.Popen(cmd
, cwd
=NACL_DIR
,
75 stdout
=subprocess
.PIPE
,
76 stderr
=subprocess
.PIPE
)
77 (p_stdout
, p_stderr
) = p
.communicate()
79 # If scons can't even run, emit just this script as an input.
80 # See comment above this one.
81 print RelativePath(__file__
, SCRIPT_DIR
).replace(os
.sep
, '/')
85 # Extract unique inputs.
86 for line
in p_stdout
.splitlines():
87 m
= re
.match('^[ -+|]*\+\-(.+)', line
)
93 if filename
.startswith('scons-out'):
95 if filename
.endswith('.nexe'):
97 # Apply the underlay of gpu/command_buffer (to match scons).
98 if filename
.startswith(NACL_CMD_BUFFER_DIR
+ os
.sep
):
99 filename
= GPU_CMD_BUFFER_DIR
+ filename
[len(NACL_CMD_BUFFER_DIR
):]
100 # Apply the underlay of ppapi (to match scons).
101 if (not os
.path
.exists(os
.path
.join(NACL_DIR
, filename
)) and
102 os
.path
.exists(os
.path
.join(PPAPI_NACL_DIR
, filename
))):
103 filename
= '../ppapi/native_client/' + filename
105 # Check that everything exists and make it script relative.
106 # Exclude things above SRC_DIR.
109 nf
= os
.path
.join(NACL_DIR
, f
)
110 if not os
.path
.exists(nf
):
111 raise Exception('missing input file "%s"' % nf
)
112 # If the relative path from SRC_DIR to the file starts with ../ ignore it.
113 # (i.e. the file is outside the client).
114 if RelativePath(nf
, SRC_DIR
).startswith('..' + os
.sep
):
116 rel_inputs
.add(RelativePath(nf
, SCRIPT_DIR
).replace(os
.sep
, '/'))
118 rel_inputs
= sorted(list(rel_inputs
))
123 def BuildIRT(platforms
, out_dir
):
124 """Build the IRT for several platforms.
127 platforms: list of platform names to build for.
128 out_dir: directory to output the IRT to.
130 # Make out_dir absolute.
131 out_dir
= os
.path
.abspath(out_dir
)
133 scons_out
= os
.path
.join(NACL_DIR
, 'scons-out')
134 if os
.path
.exists(scons_out
):
135 shutil
.rmtree(scons_out
)
136 # Build for each platform.
137 for platform
in platforms
:
139 sys
.executable
, 'scons.py', '--verbose', '-j8',
140 '--mode=nacl', 'platform=' + platform
,
141 'scons-out/nacl_irt-' + platform
+ '/staging/irt.nexe',
143 print 'Running: ' + ' '.join(cmd
)
144 # Work around the fact that python's readline module (used by scons),
145 # attempts to alter file handle state on stdin in a way that blocks if
146 # a process is not a member of a foreground job on a tty on OSX.
149 # hydric:test mseaborn$ python -c 'import readline' &
151 # hydric:test mseaborn$
152 # [1]+ Stopped python -c 'import readline'
154 # i.e. the process receives a stop signal when it's a background job.
155 if sys
.platform
== 'darwin':
156 devnull
= open(os
.devnull
, 'r')
159 p
= subprocess
.Popen(cmd
, cwd
=NACL_DIR
, stdin
=devnull
)
161 if p
.returncode
!= 0:
163 # Copy out each platform after stripping.
164 for platform
in platforms
:
165 uplatform
= platform
.replace('-', '_')
166 # NaCl Trusted code is in thumb2 mode in CrOS, but as yet,
167 # untrusted code is still in classic ARM mode
168 # arm-thumb2 is for the future when untrusted code is in thumb2 as well
169 platform2
= {'arm': 'pnacl',
170 'arm-thumb2' : 'pnacl',
172 'x86-64': 'x86_64'}.get(platform
, platform
)
177 }.get(sys
.platform
, 'linux')
178 nexe
= os
.path
.join(out_dir
, 'nacl_irt_' + uplatform
+ '.nexe')
179 if platform
in ['arm', 'arm-thumb2']:
181 '../native_client/toolchain/pnacl_linux_x86_64_newlib/bin/' +
182 platform2
+ '-strip',
184 '../native_client/scons-out/nacl_irt-' + platform \
185 + '/staging/irt.nexe',
190 '../native_client/toolchain/' + cplatform
+ '_x86_newlib/bin/' +
191 platform2
+ '-nacl-strip',
193 '../native_client/scons-out/nacl_irt-' + platform \
194 + '/staging/irt.nexe',
197 print 'Running: ' + ' '.join(cmd
)
198 p
= subprocess
.Popen(cmd
, cwd
=SCRIPT_DIR
)
200 if p
.returncode
!= 0:
205 parser
= optparse
.OptionParser()
206 parser
.add_option('--inputs', dest
='inputs', default
=False,
208 help='only emit the transitive inputs to the irt build')
209 parser
.add_option('--platform', dest
='platforms', action
='append',
211 help='add a platform to build for (x86-32|x86-64)')
212 parser
.add_option('--outdir', dest
='outdir',
213 help='directory to out irt to')
214 (options
, args
) = parser
.parse_args(argv
[1:])
215 if args
or not options
.platforms
or (
216 not options
.inputs
and not options
.outdir
):
221 PrintInputs(options
.platforms
)
223 BuildIRT(options
.platforms
, options
.outdir
)
227 if __name__
== '__main__':
228 sys
.exit(Main(sys
.argv
))