Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: native_client_sdk/src/build_tools/sdk_tools/set_nacl_env.py

Issue 13106002: [NaCl SDK] A bunch of spelling fixes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix presubmit Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 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 ''' A tool to setup the NaCl build env and invoke a command such as make '''
7
8 __author__ = 'gwink@google.com (Georges Winkenbach)'
9
10 import optparse
11 import os
12 import subprocess
13 import sys
14
15 # The default sdk platform to use if the user doesn't specify one.
16 __DEFAULT_SDK_PLATFORM = 'pepper_15'
17
18 # Usage info.
19 __GLOBAL_HELP = '''%prog options [command]
20
21 set-nacl-env is a utility that sets up the environment required to build
22 NaCl modules and invokes an optional command in a shell. If no command
23 is specified, set-nacl-env spawns a new shell instead. Optionally, the user
24 can request that the settings are printed to stdout.
25 '''
26
27 # Map the string stored in |sys.platform| into a toolchain host specifier.
28 __PLATFORM_TO_HOST_MAP = {
29 'win32': 'windows',
30 'cygwin': 'windows',
31 'linux2': 'linux',
32 'darwin': 'mac',
33 }
34
35 # Map key triplet of (host, arch, variant) keys to the corresponding subdir in
36 # the toolchain path. For instance (mac, x86-32, newlib) maps to mac_x86_newlib.
37 # Note to NaCl eng.: this map is duplicated in nack_utils.py; you must keep them
38 # synched.
39 __HOST_TO_TOOLCHAIN_MAP = {
40 'mac': { # Host arch variant
41 'x86-32': {
42 'newlib': 'mac_x86_newlib', # Mac x86-32 newlib
43 'glibc' : 'mac_x86'}, # Mac x86-32 glibc
44 'x86-64': {
45 'newlib': 'mac_x86_newlib', # Mac x86-64 newlib
46 'glibc' : 'mac_x86'}, # Mac x86-64 glibc
47 },
48 'windows': {
49 'x86-32': {
50 'newlib': 'win_x86_newlib', # Windows x86-32 newlib
51 'glibc' : 'win_x86'}, # Windows x86-32 glibc
52 'x86-64': {
53 'newlib': 'win_x86_newlib', # Windows x86-64 newlib
54 'glibc' : 'win_x86'}, # Windows x86-64 glibc
55 },
56 'linux': {
57 'x86-32': {
58 'newlib': 'linux_x86_newlib', # Windows x86-32 newlib
59 'glibc' : 'linux_x86'}, # Windows x86-32 glibc
60 'x86-64': {
61 'newlib': 'linux_x86_newlib', # Windows x86-64 newlib
62 'glibc' : 'linux_x86'}, # Windows x86-64 glibc
63 },
64 }
65
66 # Map architecture specification to the corresponding tool-name prefix.
67 # @private
68 __VALID_ARCH_SPECS = {
69 'x86-32': 'i686',
70 'x86-64': 'x86_64',
71 }
72
73 # Valid lib variants.
74 __VALID_VARIANT = ['glibc', 'newlib']
75
76 # Lists of env keys for build tools. Note: Each matching value is actually a
77 # format template with fields for 'prefix' such as 'i686-nacl-' and 'extras'
78 # such as ' -m64'.
79 __BUILD_TOOLS = {
80 'CC': '{prefix}gcc{extras}',
81 'CXX': '{prefix}g++{extras}',
82 'AR': '{prefix}ar{extras}',
83 'LINK': '{prefix}g++{extras}',
84 'STRIP': '{prefix}strip',
85 'RANLIB': '{prefix}ranlib',
86 }
87
88 # List of env keys for build options with corresponding settings that are
89 # common to all build configurations.
90 __BUILD_OPTIONS = {
91 'CFLAGS': ['-std=gnu99', '-Wall', '-Wswitch-enum', '-g'],
92 'CXXFLAGS': ['-std=gnu++98', '-Wswitch-enum', '-g', '-pthread'],
93 'CPPFLAGS': ['-D_GNU_SOURCE=1', '-D__STDC_FORMAT_MACROS=1'],
94 'LDFLAGS': [],
95 }
96
97 # All the build-flags env keys in one list.
98 __ALL_ENV_KEYS = __BUILD_TOOLS.keys() + __BUILD_OPTIONS.keys()
99
100 # Map build types to the corresponding build flags.
101 __BUILD_TYPES = {
102 'debug': ['-O0'],
103 'release': ['-O3'],
104 }
105
106
107 def FormatOptionList(option_list, prefix='', separator=' '):
108 ''' Format a list of build-option items into a string.
109
110 Format a list of build-option items into a string suitable for output.
111
112 Args:
113 prefix: a prefix string to prepend to each list item. For instance,
114 prefix='-D' with item='__DEBUG' generates '-D__DEBUG'.
115 separator: a separator string to insert between items.
116
117 Returns:
118 A formatted string. An empty string if list is empty.
119 '''
120 return separator.join([prefix + item for item in option_list])
121
122
123 def GetNaclSdkRoot():
124 ''' Produce a string with the full path to the NaCl SDK root.
125
126 The path to nacl-sdk root is derived from one of two sources. First, if
127 NACL_SDK_ROOT is defined in env it is assumed to contain the desired sdk
128 root. That makes it possible for this tool to run from any location. If
129 NACL_SDK_ROOT is not defined or is empty, the sdk root is taken as the
130 parent directory to this script's file. This works well when this script
131 is ran from the sdk_tools directory in the standard SDK installation.
132
133 Returns:
134 A string with the path to the NaCl SDK root.
135 '''
136 if 'NACL_SDK_ROOT' in os.environ:
137 return os.environ['NACL_SDK_ROOT']
138 else:
139 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
140 SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(SCRIPT_DIR)))
141 return os.path.join(SRC_DIR, 'native_client')
142
143
144 def GetToolchainPath(options):
145 ''' Build the path to the toolchain directory.
146
147 Given the host, sdk-root directory, sdk platform, architecture and library
148 variant, this function builds the path to the toolchain directory.
149
150 Examples:
151 For
152 sdk_root == 'c:/cool_code/nacl_sdk'
153 arch == 'x86-32'
154 lib variant == 'newlib'
155 nacl platform = 'pepper_17'
156 host == 'mac'
157 this function returns :
158 toolchain_path == /cool_code/nacl_sdk/pepper_17/toolchain/mac_x86_newlib
159
160 Args:
161 options: the options instances containing attributes options.host,
162 options.arch, options.lib_variant, options.sdk_root and
163 options.sdk_platform.
164
165 Returns:
166 A string containing the absolute path to the base directory for the
167 toolchain.
168 '''
169 host = options.host
170 arch = options.arch
171 variant = options.lib_variant
172 toolchain_dir = __HOST_TO_TOOLCHAIN_MAP[host][arch][variant]
173 base_dir = os.path.abspath(options.sdk_root)
174 return os.path.join(base_dir, options.sdk_platform, 'toolchain',
175 toolchain_dir)
176
177
178 def ConfigureBaseEnv(merge):
179 ''' Configure and return a new env instance with the essential options.
180
181 Create and return a new env instance with the base configuration. That env
182 contains at least an empty entry for each key defined in __ALL_ENV_KEYS.
183 However, if merge is True, a copy of the current os.environ is used to seed
184 env.
185
186 Argument:
187 merge: True ==> merge build configuration with os.environ..
188
189 Returns:
190 A base env map.
191 '''
192 env = {}
193 if merge:
194 for key, value in os.environ.items():
195 env[key] = [value]
196 # Ensure that every env key has a default definition.
197 for key in __ALL_ENV_KEYS:
198 env.setdefault(key, [])
199 return env
200
201
202 def SetBuildTools(env, tool_bin_path, tool_prefix, extras_flags=''):
203 ''' Configure the build tools build flags in env.
204
205 Given the absolute path to the toolchain's bin directory, tool_prefix and
206 optional extra_flags build flags, set the entries for the build tools
207 in env. For instance, using the sample path from GetToolchainPath above and
208 tool_prefix = 'i686-nacl-' we would get
209
210 env['CC'] =
211 '/cool_code/nacl_sdk/pepper_17/toolchain/mac_x86_newlib/bin/i686-nacl-gcc'
212
213 Args:
214 env: the env map to setup.
215 tool_bin_path: the absolute path to the toolchain's bin directory.
216 tool_prefix: a string with the tool's prefix, such as 'i686-nacl-'.
217 extra_flags: optional extra flags, such as ' -m64'.
218 '''
219 for key, val in __BUILD_TOOLS.iteritems():
220 tool_name = val.format(prefix=tool_prefix, extras=extras_flags)
221 env[key] = os.path.join(tool_bin_path, tool_name)
222
223
224 def SetRuntimeTools(env, tool_runtime_path):
225 ''' Setup the runtime tools in env.
226
227 Given an absolute path to the toolchain's runtime directory, setup the
228 entries for the runtime tools in env.
229
230 Args:
231 env: the env map to setup.
232 tool_runtime_path: the absolute path to the toolchain's runtime directory.
233 '''
234 env['NACL_IRT_CORE32'] = os.path.join(tool_runtime_path,
235 'irt_core_x86_32.nexe')
236 env['NACL_IRT_CORE64'] = os.path.join(tool_runtime_path,
237 'irt_core_x86_64.nexe')
238
239
240 def SetCommonBuildOptions(env, options):
241 ''' Set the common build options, such as CFLAGS.
242
243 Set the build options, such as CFLAGS that are common to all build
244 configurations, given the built type.
245
246 Args:
247 env: the env map to set.
248 build_type: one of 'debug' or 'release'.
249 '''
250 # Set the build flags from __BUILD_OPTIONS.
251 for key, val in __BUILD_OPTIONS.iteritems():
252 env[key].extend(val)
253 # Add the build-type specific flags.
254 env['CFLAGS'].extend(__BUILD_TYPES[options.build_type])
255 env['CXXFLAGS'].extend(__BUILD_TYPES[options.build_type])
256 if not options.no_ppapi:
257 env['LDFLAGS'].extend(['-lppapi'])
258
259
260 def SetupX86Env(options):
261 ''' Generate a new env map for X86 builds.
262
263 Generate and return a new env map for x86-NN architecture. The NN bit
264 size is derived from options.arch.
265
266 Argument:
267 options: the cmd-line options.
268
269 Returns:
270 A new env map with the build configuration flags set.
271 '''
272 env = ConfigureBaseEnv(options.merge)
273
274 # Where to find tools and libraries within the toolchain directory.
275 tool_bin_path = os.path.join(options.toolchain_path, 'bin')
276 tool_runtime_path = os.path.join(options.toolchain_path, 'runtime')
277
278 # Store the bin paths into env. This isn't really part of the build
279 # environment. But it's nice to have there for reference.
280 env['NACL_TOOL_BIN_PATH'] = tool_bin_path
281 env['NACL_TOOL_RUNTIME_PATH'] = tool_runtime_path
282
283 if options.arch == 'x86-32':
284 SetBuildTools(env, tool_bin_path, 'i686-nacl-', extras_flags=' -m32')
285 else:
286 assert(options.arch == 'x86-64')
287 SetBuildTools(env, tool_bin_path, 'x86_64-nacl-', extras_flags=' -m64')
288 SetRuntimeTools(env, tool_runtime_path)
289 SetCommonBuildOptions(env, options)
290 return env
291
292
293 def dump(options, env, template):
294 ''' Dump the build settings in env to stdout.
295
296 Args:
297 options: the cmd-line options, used to output the target buid configuartion.
298 env: the env map with the build flags.
299 template: a fiormatting template used to format options output. It must
300 contain format fields 'option' and 'value'.
301 '''
302 if options.pretty_print:
303 print '\nConfiguration:'
304 print '-------------'
305 print ' Host = %s' % options.host
306 print ' NaCl SDK root = %s' % options.sdk_root
307 print ' SDK platform = %s' % options.sdk_platform
308 print ' Target architecture = %s' % options.arch
309 print ' Lib variant = %s' % options.lib_variant
310
311 if options.pretty_print:
312 print '\nNaCl toolchain paths:'
313 print '-------------------------'
314 print ' toolchain = %s' % options.toolchain_path
315 print ' toolchain bin = %s' % env['NACL_TOOL_BIN_PATH']
316 print ' toolchain runtime = %s' % env['NACL_TOOL_RUNTIME_PATH']
317
318 if options.pretty_print:
319 print '\nBuild tools:'
320 print '-----------'
321 print template.format(option='CC', value=env['CC'])
322 print template.format(option='CXX', value=env['CXX'])
323 print template.format(option='AR', value=env['AR'])
324 print template.format(option='LINK', value=env['LINK'])
325 print template.format(option='STRIP', value=env['STRIP'])
326 print template.format(option='RANLIB', value=env['RANLIB'])
327
328 if options.pretty_print:
329 print '\nBuild settings:'
330 print '--------------'
331 print template.format(option='CFLAGS',
332 value=FormatOptionList(option_list=env['CFLAGS']))
333 print template.format(option='CXXFLAGS',
334 value=FormatOptionList(option_list=env['CXXFLAGS']))
335 print template.format(option='LDFLAGS',
336 value=FormatOptionList(option_list=env['LDFLAGS']))
337 print template.format(option='CPPFLAGS',
338 value=FormatOptionList(option_list=env['CPPFLAGS']))
339 if options.pretty_print:
340 print '\nRuntime tools:'
341 print '-------------'
342 print template.format(option='NACL_IRT_CORE32', value=env['NACL_IRT_CORE32'])
343 print template.format(option='NACL_IRT_CORE64', value=env['NACL_IRT_CORE64'])
344 print ''
345
346
347 def NormalizeEnv(env):
348 ''' Returns a copy of env normalized.
349
350 Internally, this script uses lists to keep track of build settings in env.
351 This function converts these list to space-separated strings of items,
352 suitable for use as a subprocess env.
353
354 Argument:
355 env: env map that must be normalized.
356
357 Returns:
358 A copy of env with lists converted to strings.
359 '''
360 norm_env = {}
361 for key, value in env.iteritems():
362 if isinstance(value, list):
363 norm_env[key] = ' '.join(value)
364 else:
365 norm_env[key] = value
366 return norm_env
367
368
369 def RunCommandOrShell(cmd_list, env):
370 ''' Run the command in cmd_list or a shell if cmd_list is empty.
371
372 Run the command in cmd_list using a normalized copy of env. For instance,
373 cmd_list might contain the items ['make', 'application'], which would
374 cause command 'make application' to run in the current directory. If cmd_list
375 is empty, this function will spawn a new sbushell instead.
376
377 Args:
378 cmd_list: the command list to run.
379 env: the environment to use.
380 '''
381 # If cmd_list is empty, set it up to spawn a shell instead. If cmd_list
382 # isn't empty, it will run in the current shell (for security and so that the
383 # user can see the output).
384 new_shell = False
385 if cmd_list:
386 # Normalize cmd_list by building a list of individual arguments.
387 new_cmd_list = []
388 for item in cmd_list:
389 new_cmd_list += item.split()
390 cmd_list = new_cmd_list
391 else:
392 # Build a shell command.
393 new_shell = True
394 if sys.platform == 'win32':
395 cmd_list = ['cmd']
396 else:
397 cmd_list = ['/bin/bash', '-s']
398 return subprocess.call(cmd_list, env=NormalizeEnv(env), shell=new_shell)
399
400
401 def GenerateBuildSettings(options, args):
402 ''' Generate the build settings and dump them or invoke a command.
403
404 Given the cmd-line options and remaining cmd-line arguments, generate the
405 required build settings and either dump them to stdout or invoke a shell
406 command.
407
408 Args:
409 options: cmd-line options.
410 args: unconsumed cmd-line arguments.
411
412 Returns:
413 0 in case of success or a command result code otherwise.
414 '''
415 # A few generated options, which we store in options for convenience.
416 options.host = __PLATFORM_TO_HOST_MAP[sys.platform]
417 options.sdk_root = GetNaclSdkRoot()
418 options.toolchain_path = GetToolchainPath(options)
419
420 env = SetupX86Env(options)
421 if options.dump:
422 dump(options, env, template=options.format_template)
423 return 0
424 else:
425 return RunCommandOrShell(args, env)
426
427
428 def main(argv):
429 ''' Do main stuff, mainly.
430 '''
431 parser = optparse.OptionParser(usage=__GLOBAL_HELP)
432 parser.add_option(
433 '-a', '--arch', dest='arch',
434 choices=['x86-32', 'x86-64'],
435 default='x86-64',
436 help='The target architecture; one of x86-32 or x86-64. '
437 '[default = %default.]')
438 parser.add_option(
439 '-A', '--no_ppapi', dest='no_ppapi',
440 default=False,
441 action='store_true',
442 help='Do not add -lppapi to the link settings.')
443 parser.add_option(
444 '-d', '--dump', dest='dump',
445 default=False,
446 action='store_true',
447 help='Dump the build settings to stdout')
448 parser.add_option(
449 '-D', '--pretty_print', dest='pretty_print',
450 default=False,
451 action='store_true',
452 help='Print section headers when dumping to stdout')
453 parser.add_option(
454 '-f', '--format_template', dest='format_template',
455 default=' {option}={value}',
456 help="The formatting template used to output (option, value) pairs."
457 "[default='%default.']")
458 parser.add_option(
459 '-n', '--no_merge', dest='merge',
460 default=True,
461 action='store_false',
462 help='Do not merge the build options with current environment. By default'
463 ' %prog merges the build flags with the current environment vars.'
464 ' This option turns that off.')
465 parser.add_option(
466 '-p', '--platform', dest='sdk_platform',
467 default=__DEFAULT_SDK_PLATFORM,
468 help='The SDK platform to use; e.g. pepper_16. [default = %default.]')
469 parser.add_option(
470 '-t', '--build_type', dest='build_type',
471 choices=__BUILD_TYPES.keys(),
472 default='debug',
473 help='The desired build type; one of debug or release.'
474 ' [default = %default.]')
475 parser.add_option(
476 '-v', '--variant', dest='lib_variant',
477 choices=['glibc', 'newlib'], default='newlib',
478 help='The lib variant to use; one of glibc or newlib. '
479 '[default = %default.]')
480
481 (options, args) = parser.parse_args(argv)
482
483 # Verify that we're running on a supported host.
484 if sys.platform not in __PLATFORM_TO_HOST_MAP:
485 sys.stderr.write('Platform %s is not supported.' % sys.platform)
486 return 1
487
488 return GenerateBuildSettings(options, args)
489
490
491 if __name__ == '__main__':
492 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « native_client_sdk/src/build_tools/manifest_util.py ('k') | native_client_sdk/src/build_tools/template.mk » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698