OLD | NEW |
| (Empty) |
1 #!/usr/bin/python | |
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. | |
5 | |
6 import optparse | |
7 import os | |
8 import re | |
9 import shutil | |
10 import subprocess | |
11 import sys | |
12 | |
13 | |
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') | |
18 | |
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') | |
23 | |
24 | |
25 def RelativePath(path, base): | |
26 """Find the relative path. | |
27 | |
28 Arguments: | |
29 path: path we want a relative path to. | |
30 base: path we want a relative path from. | |
31 Returns: | |
32 The relative path from base to path. | |
33 """ | |
34 path = os.path.abspath(path) | |
35 base = os.path.abspath(base) | |
36 path_parts = path.split(os.sep) | |
37 base_parts = base.split(os.sep) | |
38 while path_parts and base_parts and path_parts[0] == base_parts[0]: | |
39 path_parts = path_parts[1:] | |
40 base_parts = base_parts[1:] | |
41 rel_parts = ['..'] * len(base_parts) + path_parts | |
42 return os.sep.join(rel_parts) | |
43 | |
44 | |
45 def PrintInputs(platforms): | |
46 """Print all the transitive inputs required to build the IRT. | |
47 | |
48 Arguments: | |
49 platforms: list of platform names to build for. | |
50 """ | |
51 inputs = set() | |
52 for platform in platforms: | |
53 # Invoke scons to get dependency tree. | |
54 cmd = [ | |
55 sys.executable, 'scons.py', '-n', '--tree=all', | |
56 '--mode=nacl', 'platform=' + platform, | |
57 'scons-out/nacl_irt-' + platform + '/staging/irt.nexe', | |
58 ] | |
59 p = subprocess.Popen(cmd, cwd=NACL_DIR, | |
60 stdout=subprocess.PIPE, | |
61 stderr=subprocess.PIPE) | |
62 (p_stdout, p_stderr) = p.communicate() | |
63 if p.returncode != 0: | |
64 sys.exit(2) | |
65 # Extract unique inputs. | |
66 for line in p_stdout.splitlines(): | |
67 m = re.match('^[ -+|]*\+\-(.+)', line) | |
68 if not m: | |
69 continue | |
70 filename = m.group(1) | |
71 if '[' in filename: | |
72 continue | |
73 if filename.startswith('scons-out'): | |
74 continue | |
75 if filename.endswith('.nexe'): | |
76 continue | |
77 # Apply the underlay of gpu/command_buffer (to match scons). | |
78 if filename.startswith(NACL_CMD_BUFFER_DIR + os.sep): | |
79 filename = GPU_CMD_BUFFER_DIR + filename[len(NACL_CMD_BUFFER_DIR):] | |
80 inputs.add(filename) | |
81 # Check that everything exists and make it script relative. | |
82 # Exclude things above SRC_DIR. | |
83 rel_inputs = set() | |
84 for f in inputs: | |
85 nf = os.path.join(NACL_DIR, f) | |
86 if not os.path.exists(nf): | |
87 raise Exception('missing input file "%s"' % nf) | |
88 # If the relative path from SRC_DIR to the file starts with ../ ignore it. | |
89 # (i.e. the file is outside the client). | |
90 if RelativePath(nf, SRC_DIR).startswith('..' + os.sep): | |
91 continue | |
92 rel_inputs.add(RelativePath(nf, SCRIPT_DIR)) | |
93 # Print it sorted. | |
94 rel_inputs = sorted(list(rel_inputs)) | |
95 for f in rel_inputs: | |
96 print f | |
97 | |
98 | |
99 def BuildIRT(platforms, out_dir): | |
100 """Build the IRT for several platforms. | |
101 | |
102 Arguments: | |
103 platforms: list of platform names to build for. | |
104 out_dir: directory to output the IRT to. | |
105 """ | |
106 # Make out_dir absolute. | |
107 out_dir = os.path.abspath(out_dir) | |
108 # Clean. | |
109 scons_out = os.path.join(NACL_DIR, 'scons-out') | |
110 if os.path.exists(scons_out): | |
111 shutil.rmtree(scons_out) | |
112 # Build for each platform. | |
113 for platform in platforms: | |
114 cmd = [ | |
115 sys.executable, 'scons.py', '--verbose', '-j8', | |
116 '--mode=nacl', 'platform=' + platform, | |
117 'scons-out/nacl_irt-' + platform + '/staging/irt.nexe', | |
118 ] | |
119 print 'Running: ' + ' '.join(cmd) | |
120 # Work around the fact that python's readline module (used by scons), | |
121 # attempts to alter file handle state on stdin in a way that blocks if | |
122 # a process is not a member of a foreground job on a tty on OSX. | |
123 # e.g. On a Mac: | |
124 # | |
125 # hydric:test mseaborn$ python -c 'import readline' & | |
126 # [1] 67058 | |
127 # hydric:test mseaborn$ | |
128 # [1]+ Stopped python -c 'import readline' | |
129 # | |
130 # i.e. the process receives a stop signal when it's a background job. | |
131 if sys.platform == 'darwin': | |
132 devnull = open(os.devnull, 'r') | |
133 else: | |
134 devnull = None | |
135 p = subprocess.Popen(cmd, cwd=NACL_DIR, stdin=devnull) | |
136 p.wait() | |
137 if p.returncode != 0: | |
138 sys.exit(3) | |
139 # Copy out each platform after stripping. | |
140 for platform in platforms: | |
141 uplatform = platform.replace('-', '_') | |
142 platform2 = {'x86-32': 'i686', 'x86-64': 'x86_64'}.get(platform, platform) | |
143 cplatform = { | |
144 'win32': 'win', | |
145 'cygwin': 'win', | |
146 'darwin': 'mac', | |
147 }.get(sys.platform, 'linux') | |
148 nexe = os.path.join(out_dir, 'nacl_irt_' + uplatform + '.nexe') | |
149 cmd = [ | |
150 '../native_client/toolchain/' + cplatform + '_x86_newlib/bin/' + | |
151 platform2 + '-nacl-strip', | |
152 '--strip-debug', | |
153 '../native_client/scons-out/nacl_irt-' + platform + '/staging/irt.nexe', | |
154 '-o', nexe | |
155 ] | |
156 print 'Running: ' + ' '.join(cmd) | |
157 p = subprocess.Popen(cmd, cwd=SCRIPT_DIR) | |
158 p.wait() | |
159 if p.returncode != 0: | |
160 sys.exit(4) | |
161 | |
162 | |
163 def Main(argv): | |
164 parser = optparse.OptionParser() | |
165 parser.add_option('--inputs', dest='inputs', default=False, | |
166 action='store_true', | |
167 help='only emit the transitive inputs to the irt build') | |
168 parser.add_option('--platform', dest='platforms', action='append', | |
169 default=[], | |
170 help='add a platform to build for (x86-32|x86-64)') | |
171 parser.add_option('--outdir', dest='outdir', | |
172 help='directory to out irt to') | |
173 (options, args) = parser.parse_args(argv[1:]) | |
174 if args or not options.platforms or ( | |
175 not options.inputs and not options.outdir): | |
176 parser.print_help() | |
177 sys.exit(1) | |
178 | |
179 if options.inputs: | |
180 PrintInputs(options.platforms) | |
181 else: | |
182 BuildIRT(options.platforms, options.outdir) | |
183 | |
184 | |
185 if __name__ == '__main__': | |
186 Main(sys.argv) | |
OLD | NEW |