Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / native_client / toolchain_build / pnacl_targetlibs.py
1 #!/usr/bin/python
2 # Copyright (c) 2013 The Native Client 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 """Recipes for PNaCl target libs."""
7
8 import fnmatch
9 import os
10 import sys
11
12 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
13 import pynacl.gsd_storage
14 import pynacl.platform
15
16 import command
17 import pnacl_commands
18
19
20 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
21 NACL_DIR = os.path.dirname(SCRIPT_DIR)
22
23 CLANG_VER = '3.4'
24
25 # Return the path to the local copy of the driver script.
26 # msys should be false if the path will be called directly rather than passed to
27 # an msys or cygwin tool such as sh or make.
28 def PnaclTool(toolname, msys=True):
29   if not msys and pynacl.platform.IsWindows():
30     ext = '.bat'
31   else:
32     ext = ''
33   return command.path.join('%(abs_target_lib_compiler)s',
34                            'bin', 'pnacl-' + toolname + ext)
35
36 # PNaCl tools for newlib's environment, e.g. CC_FOR_TARGET=/path/to/pnacl-clang
37 TOOL_ENV_NAMES = { 'CC': 'clang', 'CXX': 'clang++', 'AR': 'ar', 'NM': 'nm',
38                    'RANLIB': 'ranlib', 'READELF': 'readelf',
39                    'OBJDUMP': 'illegal', 'AS': 'illegal', 'LD': 'illegal',
40                    'STRIP': 'illegal' }
41 TARGET_TOOLS = [ tool + '_FOR_TARGET=' + PnaclTool(name)
42                  for tool, name in TOOL_ENV_NAMES.iteritems() ]
43
44 def MakeCommand():
45   make_command = ['make']
46   if not pynacl.platform.IsWindows():
47     # The make that ships with msys sometimes hangs when run with -j.
48     # The ming32-make that comes with the compiler itself reportedly doesn't
49     # have this problem, but it has issues with pathnames with LLVM's build.
50     make_command.append('-j%(cores)s')
51   return make_command
52
53 # Return the component name to use for a component name with
54 # a host triple. GNU configuration triples contain dashes, which are converted
55 # to underscores so the names are legal for Google Storage.
56 def GSDJoin(*args):
57   return '_'.join([pynacl.gsd_storage.LegalizeName(arg) for arg in args])
58
59
60 # Copy the compiled bitcode archives used for linking C programs into the the
61 # current working directory. This allows the driver in the working directory to
62 # be used in cases which need the ability to link pexes (e.g. CMake
63 # try-compiles, LLVM testsuite, or libc++ testsuite). For now this also requires
64 # a build of libnacl however, which is driven by the buildbot script or
65 # external test script. TODO(dschuff): add support to drive the LLVM and libcxx
66 # test suites from toolchain_build rules.
67 def CopyBitcodeCLibs(bias_arch):
68   return [
69       command.RemoveDirectory('usr'),
70       command.Mkdir('usr'),
71       command.Command('cp -r %(' +
72                       GSDJoin('abs_libs_support_bitcode', bias_arch) +
73                       ')s usr', shell=True),
74       command.Command('cp -r %(' + GSDJoin('abs_newlib', bias_arch) +
75                       ')s/* usr', shell=True),
76       ]
77
78
79 def BiasedBitcodeTriple(bias_arch):
80   return 'le32-nacl' if bias_arch == 'le32' else bias_arch + '_bc-nacl'
81
82 def BiasedBitcodeTargetFlag(arch):
83   flagmap = {
84       # Arch     Target                           Extra flags.
85       'x86-64': ('x86_64-unknown-nacl',           []),
86       'x86-32': ('i686-unknown-nacl',             []),
87       'arm':    ('armv7-unknown-nacl-gnueabihf',  ['-mfloat-abi=hard']),
88       # MIPS doesn't use biased bitcode:
89       'mips32': ('le32-unknown-nacl',             []),
90   }
91   return ['--target=%s' % flagmap[arch][0]] + flagmap[arch][1]
92
93
94 def TargetBCLibCflags(bias_arch):
95   flags = '-g -O2 -mllvm -inline-threshold=5'
96   if bias_arch != 'le32':
97     flags += ' ' + ' '.join(BiasedBitcodeTargetFlag(bias_arch))
98   return flags
99
100 def NewlibIsystemCflags(bias_arch):
101   return ' '.join([
102     '-isystem',
103     command.path.join('%(' + GSDJoin('abs_newlib', bias_arch) +')s',
104                       BiasedBitcodeTriple(bias_arch), 'include')])
105
106 def LibCxxCflags(bias_arch):
107   # HAS_THREAD_LOCAL is used by libc++abi's exception storage, the fallback is
108   # pthread otherwise.
109   return ' '.join([TargetBCLibCflags(bias_arch), NewlibIsystemCflags(bias_arch),
110                    '-DHAS_THREAD_LOCAL=1'])
111
112
113 def LibStdcxxCflags(bias_arch):
114   return ' '.join([TargetBCLibCflags(bias_arch),
115                    NewlibIsystemCflags(bias_arch)])
116
117
118 # Build a single object file as bitcode.
119 def BuildTargetBitcodeCmd(source, output, bias_arch, output_dir='%(cwd)s'):
120   flags = ['-Wall', '-Werror', '-O2', '-c']
121   if bias_arch != 'le32':
122     flags.extend(BiasedBitcodeTargetFlag(bias_arch))
123   flags.extend(NewlibIsystemCflags(bias_arch).split())
124   return command.Command(
125       [PnaclTool('clang', msys=False)] + flags + [
126           command.path.join('%(src)s', source),
127      '-o', command.path.join(output_dir, output)])
128
129
130 # Build a single object file as native code.
131 def BuildTargetNativeCmd(sourcefile, output, arch, extra_flags=[],
132                          source_dir='%(src)s', output_dir='%(cwd)s'):
133   return command.Command(
134     [PnaclTool('clang', msys=False),
135      '--pnacl-allow-native', '--pnacl-allow-translate', '-Wall', '-Werror',
136      '-arch', arch, '--pnacl-bias=' + arch, '-O3',
137      # TODO(dschuff): this include breaks the input encapsulation for build
138      # rules.
139      '-I%(top_srcdir)s/..','-c'] +
140     NewlibIsystemCflags('le32').split() +
141     extra_flags +
142     [command.path.join(source_dir, sourcefile),
143      '-o', command.path.join(output_dir, output)])
144
145
146 def BuildLibgccEhCmd(sourcefile, output, arch):
147   # Return a command to compile a file from libgcc_eh (see comments in at the
148   # rule definition below).
149   flags_common = ['-DENABLE_RUNTIME_CHECKING', '-g', '-O2', '-W', '-Wall',
150                   '-Wwrite-strings', '-Wcast-qual', '-Wstrict-prototypes',
151                   '-Wmissing-prototypes', '-Wold-style-definition',
152                   '-DIN_GCC', '-DCROSS_DIRECTORY_STRUCTURE', '-DIN_LIBGCC2',
153                   '-D__GCC_FLOAT_NOT_NEEDED', '-Dinhibit_libc',
154                   '-DHAVE_CC_TLS', '-DHIDE_EXPORTS',
155                   '-fno-stack-protector', '-fexceptions',
156                   '-fvisibility=hidden',
157                   '-I.', '-I../.././gcc', '-I%(abs_gcc_src)s/gcc/libgcc',
158                   '-I%(abs_gcc_src)s/gcc', '-I%(abs_gcc_src)s/include',
159                   '-isystem', './include']
160   # For x86 we use nacl-gcc to build libgcc_eh because of some issues with
161   # LLVM's handling of the gcc intrinsics used in the library. See
162   # https://code.google.com/p/nativeclient/issues/detail?id=1933
163   # and http://llvm.org/bugs/show_bug.cgi?id=8541
164   # For ARM, LLVM does work and we use it to avoid dealing with the fact that
165   # arm-nacl-gcc uses different libgcc support functions than PNaCl.
166   if arch in ('arm', 'mips32'):
167     cc = PnaclTool('clang', msys=False)
168     flags_naclcc = ['-arch', arch, '--pnacl-bias=' + arch,
169                     '--pnacl-allow-translate', '--pnacl-allow-native']
170   else:
171     os_name = pynacl.platform.GetOS()
172     arch_name = pynacl.platform.GetArch()
173     platform_dir = '%s_%s' % (os_name, arch_name)
174     newlib_dir = 'nacl_x86_newlib'
175
176     nnacl_dir = os.path.join(NACL_DIR, 'toolchain', platform_dir,
177                              newlib_dir, 'bin')
178     gcc_binaries = {
179         'x86-32': 'i686-nacl-gcc',
180         'x86-64': 'x86_64-nacl-gcc',
181     }
182
183     cc = os.path.join(nnacl_dir, gcc_binaries[arch])
184     flags_naclcc = []
185   return command.Command([cc] + flags_naclcc + flags_common +
186                          ['-c',
187                           command.path.join('%(gcc_src)s', 'gcc', sourcefile),
188                           '-o', output])
189
190
191
192 def TargetLibsSrc(GitSyncCmds):
193   newlib_sys_nacl = command.path.join('%(output)s',
194                                       'newlib', 'libc', 'sys', 'nacl')
195   source = {
196       'newlib_src': {
197           'type': 'source',
198           'output_dirname': 'pnacl-newlib',
199           'commands': [
200               # Clean any headers exported from the NaCl tree before syncing.
201               command.CleanGitWorkingDir(
202                   '%(output)s', os.path.join('newlib', 'libc', 'include'))] +
203               GitSyncCmds('nacl-newlib') +
204               # Remove newlib versions of headers that will be replaced by
205               # headers from the NaCl tree.
206               [command.RemoveDirectory(command.path.join(newlib_sys_nacl,
207                                                          dirname))
208                for dirname in ['bits', 'sys', 'machine']] + [
209               command.Command([
210                   sys.executable,
211                   command.path.join('%(top_srcdir)s', 'src', 'trusted',
212                                     'service_runtime', 'export_header.py'),
213                   command.path.join('%(top_srcdir)s', 'src', 'trusted',
214                                     'service_runtime', 'include'),
215                   newlib_sys_nacl],
216                   cwd='%(abs_output)s',
217               )] + [
218               command.Copy(
219                   os.path.join('%(top_srcdir)s', 'src', 'untrusted', 'pthread',
220                                header),
221                   os.path.join('%(output)s', 'newlib', 'libc', 'include',
222                                header))
223               for header in ('pthread.h', 'semaphore.h')
224        ]
225       },
226       'compiler_rt_src': {
227           'type': 'source',
228           'output_dirname': 'compiler-rt',
229           'commands': GitSyncCmds('compiler-rt'),
230       },
231       'gcc_src': {
232           'type': 'source',
233           'output_dirname': 'pnacl-gcc',
234           'commands': GitSyncCmds('gcc'),
235       },
236   }
237   return source
238
239
240 def BitcodeLibs(bias_arch, is_canonical):
241   def B(component_name):
242     return GSDJoin(component_name, bias_arch)
243   bc_triple = BiasedBitcodeTriple(bias_arch)
244
245   libs = {
246       B('newlib'): {
247           'type': 'build' if is_canonical else 'work',
248           'dependencies': [ 'newlib_src', 'target_lib_compiler'],
249           'commands' : [
250               command.SkipForIncrementalCommand(
251                   ['sh', '%(newlib_src)s/configure'] +
252                   TARGET_TOOLS +
253                   ['CFLAGS_FOR_TARGET=' + TargetBCLibCflags(bias_arch) +
254                    ' -allow-asm',
255                   '--disable-multilib',
256                   '--prefix=',
257                   '--disable-newlib-supplied-syscalls',
258                   '--disable-texinfo',
259                   '--disable-libgloss',
260                   '--enable-newlib-iconv',
261                   '--enable-newlib-iconv-from-encodings=' +
262                   'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4',
263                   '--enable-newlib-iconv-to-encodings=' +
264                   'UTF-8,UTF-16LE,UCS-4LE,UTF-16,UCS-4',
265                   '--enable-newlib-io-long-long',
266                   '--enable-newlib-io-long-double',
267                   '--enable-newlib-io-c99-formats',
268                   '--enable-newlib-mb',
269                   '--target=le32-nacl'
270               ]),
271               command.Command(MakeCommand()),
272               command.Command(['make', 'DESTDIR=%(abs_output)s', 'install']),
273               # We configured newlib with target=le32-nacl to get its pure C
274               # implementation, so rename its output dir (which matches the
275               # target to the output dir for the package we are building)
276               command.Rename(os.path.join('%(output)s', 'le32-nacl'),
277                              os.path.join('%(output)s', bc_triple)),
278               # Copy nacl_random.h, used by libc++. It uses the IRT, so should
279               # be safe to include in the toolchain.
280               command.Mkdir(
281                   os.path.join('%(output)s', bc_triple, 'include', 'nacl')),
282               command.Copy(os.path.join('%(top_srcdir)s', 'src', 'untrusted',
283                                         'nacl', 'nacl_random.h'),
284                            os.path.join(
285                                '%(output)s', bc_triple, 'include', 'nacl',
286                                'nacl_random.h')),
287               # Remove the 'share' directory from the biased builds; the data is
288               # duplicated exactly and takes up 2MB per package.
289               command.RemoveDirectory(os.path.join('%(output)s', 'share'),
290                              run_cond = lambda x: bias_arch != 'le32'),
291           ],
292       },
293       B('libcxx'): {
294           'type': 'build' if is_canonical else 'work',
295           'dependencies': ['libcxx_src', 'libcxxabi_src', 'llvm_src', 'gcc_src',
296                            'target_lib_compiler', B('newlib'),
297                            B('libs_support_bitcode')],
298           'commands' :
299               CopyBitcodeCLibs(bias_arch) + [
300               command.SkipForIncrementalCommand(
301                   ['cmake', '-G', 'Unix Makefiles',
302                    '-DCMAKE_C_COMPILER_WORKS=1',
303                    '-DCMAKE_CXX_COMPILER_WORKS=1',
304                    '-DCMAKE_INSTALL_PREFIX=',
305                    '-DCMAKE_BUILD_TYPE=Release',
306                    '-DCMAKE_C_COMPILER=' + PnaclTool('clang'),
307                    '-DCMAKE_CXX_COMPILER=' + PnaclTool('clang++'),
308                    '-DCMAKE_SYSTEM_NAME=nacl',
309                    '-DCMAKE_AR=' + PnaclTool('ar'),
310                    '-DCMAKE_NM=' + PnaclTool('nm'),
311                    '-DCMAKE_RANLIB=' + PnaclTool('ranlib'),
312                    '-DCMAKE_LD=' + PnaclTool('illegal'),
313                    '-DCMAKE_AS=' + PnaclTool('illegal'),
314                    '-DCMAKE_OBJDUMP=' + PnaclTool('illegal'),
315                    '-DCMAKE_C_FLAGS=-std=gnu11 ' + LibCxxCflags(bias_arch),
316                    '-DCMAKE_CXX_FLAGS=-std=gnu++11 ' + LibCxxCflags(bias_arch),
317                    '-DLIT_EXECUTABLE=' + command.path.join(
318                        '%(llvm_src)s', 'utils', 'lit', 'lit.py'),
319                    # The lit flags are used by the libcxx testsuite, which is
320                    # currenty driven by an external script.
321                    '-DLLVM_LIT_ARGS=--verbose  --param shell_prefix="' +
322                     os.path.join(NACL_DIR,'run.py') +' -arch env --retries=1" '+
323                     '--param exe_suffix=".pexe" --param use_system_lib=true ' +
324                     '--param link_flags="-std=gnu++11 --pnacl-exceptions=sjlj '+
325                     '-L' + os.path.join(
326                         NACL_DIR,
327                         'toolchain/linux_x86/pnacl_newlib/sdk/lib') + '"',
328                    '-DLIBCXX_ENABLE_CXX0X=0',
329                    '-DLIBCXX_ENABLE_SHARED=0',
330                    '-DLIBCXX_CXX_ABI=libcxxabi',
331                    '-DLIBCXX_LIBCXXABI_INCLUDE_PATHS=' + command.path.join(
332                        '%(abs_libcxxabi_src)s', 'include'),
333                    '%(libcxx_src)s']),
334               command.Copy(os.path.join('%(gcc_src)s', 'gcc',
335                                         'unwind-generic.h'),
336                            os.path.join('include', 'unwind.h')),
337               command.Command(MakeCommand() + ['VERBOSE=1']),
338               command.Command([
339                   'make',
340                   'DESTDIR=' + os.path.join('%(abs_output)s', bc_triple),
341                   'VERBOSE=1',
342                   'install']),
343           ],
344       },
345       B('libstdcxx'): {
346           'type': 'build' if is_canonical else 'work',
347           'dependencies': ['gcc_src', 'gcc_src', 'target_lib_compiler',
348                            B('newlib')],
349           'commands' : [
350               command.SkipForIncrementalCommand([
351                   'sh',
352                   command.path.join('%(gcc_src)s', 'libstdc++-v3',
353                                     'configure')] +
354                   TARGET_TOOLS + [
355                   'CC_FOR_BUILD=cc',
356                   'CC=' + PnaclTool('clang'),
357                   'CXX=' + PnaclTool('clang++'),
358                   'AR=' + PnaclTool('ar'),
359                   'NM=' + PnaclTool('nm'),
360                   'RAW_CXX_FOR_TARGET=' + PnaclTool('clang++'),
361                   'LD=' + PnaclTool('illegal'),
362                   'RANLIB=' + PnaclTool('ranlib'),
363                   'CFLAGS=' + LibStdcxxCflags(bias_arch),
364                   'CXXFLAGS=' + LibStdcxxCflags(bias_arch),
365                   'CPPFLAGS=' + NewlibIsystemCflags(bias_arch),
366                   'CFLAGS_FOR_TARGET=' + LibStdcxxCflags(bias_arch),
367                   'CXXFLAGS_FOR_TARGET=' + LibStdcxxCflags(bias_arch),
368                   '--host=arm-none-linux-gnueabi',
369                   '--prefix=',
370                   '--enable-cxx-flags=-D__SIZE_MAX__=4294967295',
371                   '--disable-multilib',
372                   '--disable-linux-futex',
373                   '--disable-libstdcxx-time',
374                   '--disable-sjlj-exceptions',
375                   '--disable-libstdcxx-pch',
376                   '--with-newlib',
377                   '--disable-shared',
378                   '--disable-rpath']),
379               command.Copy(os.path.join('%(gcc_src)s', 'gcc',
380                                         'unwind-generic.h'),
381                            os.path.join('include', 'unwind.h')),
382               command.Command(MakeCommand()),
383               command.Command([
384                   'make',
385                   'DESTDIR=' + os.path.join('%(abs_output)s', bc_triple),
386                   'install-data']),
387               command.RemoveDirectory(
388                   os.path.join('%(output)s', bc_triple, 'share')),
389               command.Remove(os.path.join('%(output)s', bc_triple, 'lib',
390                                           'libstdc++*-gdb.py')),
391               command.Copy(
392                   os.path.join('src', '.libs', 'libstdc++.a'),
393                   os.path.join('%(output)s', bc_triple, 'lib', 'libstdc++.a')),
394           ],
395       },
396       B('libs_support_bitcode'): {
397           'type': 'build' if is_canonical else 'work',
398           'output_subdir': os.path.join(
399               'lib', 'clang', CLANG_VER, 'lib', bc_triple),
400           'dependencies': [ B('newlib'), 'target_lib_compiler'],
401           'inputs': { 'src': os.path.join(NACL_DIR,
402                                           'pnacl', 'support', 'bitcode')},
403           'commands': [
404               # Two versions of crt1.x exist, for different scenarios (with and
405               # without EH).  See:
406               # https://code.google.com/p/nativeclient/issues/detail?id=3069
407               command.Copy(command.path.join('%(src)s', 'crt1.x'),
408                            command.path.join('%(output)s', 'crt1.x')),
409               command.Copy(command.path.join('%(src)s', 'crt1_for_eh.x'),
410                            command.path.join('%(output)s', 'crt1_for_eh.x')),
411               # Install crti.bc (empty _init/_fini)
412               BuildTargetBitcodeCmd('crti.c', 'crti.bc', bias_arch,
413                                     output_dir='%(output)s'),
414               # Install crtbegin bitcode (__cxa_finalize for C++)
415               BuildTargetBitcodeCmd('crtbegin.c', 'crtbegin.bc', bias_arch,
416                                     output_dir='%(output)s'),
417               # Stubs for _Unwind_* functions when libgcc_eh is not included in
418               # the native link).
419               BuildTargetBitcodeCmd('unwind_stubs.c', 'unwind_stubs.bc',
420                                     bias_arch, output_dir='%(output)s'),
421               BuildTargetBitcodeCmd('sjlj_eh_redirect.cc',
422                                     'sjlj_eh_redirect.bc', bias_arch,
423                                     output_dir='%(output)s'),
424               # libpnaclmm.a (__atomic_* library functions).
425               BuildTargetBitcodeCmd('pnaclmm.c', 'pnaclmm.bc', bias_arch),
426               command.Command([
427                   PnaclTool('ar'), 'rc',
428                   command.path.join('%(output)s', 'libpnaclmm.a'),
429                   'pnaclmm.bc']),
430           ],
431       },
432   }
433   return libs
434
435
436 def NativeLibs(arch, is_canonical):
437   setjmp_arch = arch
438   if setjmp_arch.endswith('-nonsfi'):
439     setjmp_arch = setjmp_arch[:-len('-nonsfi')]
440
441   arch_cmds = []
442   if arch == 'arm':
443     arch_cmds.append(
444         BuildTargetNativeCmd('aeabi_read_tp.S', 'aeabi_read_tp.o', arch))
445   elif arch == 'x86-32-nonsfi':
446     arch_cmds.extend(
447         [BuildTargetNativeCmd('entry_linux.c', 'entry_linux.o', arch),
448          BuildTargetNativeCmd('entry_linux_x86_32.S', 'entry_linux_asm.o',
449                               arch)])
450   elif arch == 'arm-nonsfi':
451     arch_cmds.extend(
452         [BuildTargetNativeCmd('entry_linux.c', 'entry_linux.o', arch),
453          BuildTargetNativeCmd('entry_linux_arm.S', 'entry_linux_asm.o',
454                               arch)])
455   native_lib_dir = os.path.join('translator', arch, 'lib')
456
457   libs = {
458       GSDJoin('libs_support_native', arch): {
459           'type': 'build' if is_canonical else 'work',
460           'output_subdir': native_lib_dir,
461           'dependencies': [ 'newlib_src', 'newlib_le32',
462                             'target_lib_compiler'],
463           # These libs include
464           # arbitrary stuff from native_client/src/{include,untrusted,trusted}
465           'inputs': { 'src': os.path.join(NACL_DIR, 'pnacl', 'support'),
466                       'include': os.path.join(NACL_DIR, 'src'),
467                       'newlib_subset': os.path.join(
468                           NACL_DIR, 'src', 'third_party',
469                           'pnacl_native_newlib_subset')},
470           'commands': [
471               BuildTargetNativeCmd('crtbegin.c', 'crtbegin.o', arch,
472                                    output_dir='%(output)s'),
473               BuildTargetNativeCmd('crtbegin.c', 'crtbegin_for_eh.o', arch,
474                                    ['-DLINKING_WITH_LIBGCC_EH'],
475                                    output_dir='%(output)s'),
476               BuildTargetNativeCmd('crtend.c', 'crtend.o', arch,
477                                    output_dir='%(output)s'),
478               # libcrt_platform.a
479               BuildTargetNativeCmd('pnacl_irt.c', 'pnacl_irt.o', arch),
480               BuildTargetNativeCmd('relocate.c', 'relocate.o', arch),
481               BuildTargetNativeCmd(
482                   'setjmp_%s.S' % setjmp_arch.replace('-', '_'),
483                   'setjmp.o', arch),
484               BuildTargetNativeCmd('string.c', 'string.o', arch,
485                                    ['-std=c99'],
486                                    source_dir='%(newlib_subset)s'),
487               # Pull in non-errno __ieee754_fmod from newlib and rename it to
488               # fmod. This is to support the LLVM frem instruction.
489               BuildTargetNativeCmd(
490                   'e_fmod.c', 'e_fmod.o', arch,
491                   ['-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/',
492                    '-D__ieee754_fmod=fmod'],
493                   source_dir='%(abs_newlib_src)s/newlib/libm/math'),
494               BuildTargetNativeCmd(
495                   'ef_fmod.c', 'ef_fmod.o', arch,
496                   ['-std=c99', '-I%(abs_newlib_src)s/newlib/libm/common/',
497                    '-D__ieee754_fmodf=fmodf'],
498                   source_dir='%(abs_newlib_src)s/newlib/libm/math')] +
499               arch_cmds + [
500               command.Command(' '.join([
501                   PnaclTool('ar'), 'rc',
502                   command.path.join('%(output)s', 'libcrt_platform.a'),
503                   '*.o']), shell=True),
504               # Dummy IRT shim
505               BuildTargetNativeCmd('dummy_shim_entry.c', 'dummy_shim_entry.o',
506                                    arch),
507               command.Command([PnaclTool('ar'), 'rc',
508                                command.path.join('%(output)s',
509                                                  'libpnacl_irt_shim_dummy.a'),
510                                'dummy_shim_entry.o']),
511           ],
512       },
513       GSDJoin('compiler_rt', arch): {
514           'type': 'build' if is_canonical else 'work',
515           'output_subdir': native_lib_dir,
516           'dependencies': ['compiler_rt_src', 'target_lib_compiler',
517                            'newlib_le32'],
518           'commands': [
519               command.Command(MakeCommand() + [
520                   '-f',
521                   command.path.join('%(compiler_rt_src)s', 'lib',
522                                     'Makefile-pnacl'),
523                   'libgcc.a', 'CC=' + PnaclTool('clang'),
524                   'AR=' + PnaclTool('ar')] +
525                   ['SRC_DIR=' + command.path.join('%(abs_compiler_rt_src)s',
526                                                   'lib'),
527                    'CFLAGS=-arch ' + arch + ' -DPNACL_' +
528                     arch.replace('-', '_') + ' --pnacl-allow-translate -O3 ' +
529                    NewlibIsystemCflags('le32')]),
530               command.Copy('libgcc.a', os.path.join('%(output)s', 'libgcc.a')),
531           ],
532       },
533   }
534   if not arch.endswith('-nonsfi'):
535     libs.update({
536       GSDJoin('libgcc_eh', arch): {
537           'type': 'build' if is_canonical else 'work',
538           'output_subdir': native_lib_dir,
539           'dependencies': [ 'gcc_src', 'target_lib_compiler'],
540           'inputs': { 'scripts': os.path.join(NACL_DIR, 'pnacl', 'scripts')},
541           'commands': [
542               # Instead of trying to use gcc's build system to build only
543               # libgcc_eh, we just build the C files and archive them manually.
544               command.RemoveDirectory('include'),
545               command.Mkdir('include'),
546               command.Copy(os.path.join('%(gcc_src)s', 'gcc',
547                            'unwind-generic.h'),
548                            os.path.join('include', 'unwind.h')),
549               command.Copy(os.path.join('%(scripts)s', 'libgcc-tconfig.h'),
550                            'tconfig.h'),
551               command.WriteData('', 'tm.h'),
552               BuildLibgccEhCmd('unwind-dw2.c', 'unwind-dw2.o', arch),
553               BuildLibgccEhCmd('unwind-dw2-fde-glibc.c',
554                                'unwind-dw2-fde-glibc.o', arch),
555               command.Command([PnaclTool('ar'), 'rc',
556                                command.path.join('%(output)s', 'libgcc_eh.a'),
557                                'unwind-dw2.o', 'unwind-dw2-fde-glibc.o']),
558           ],
559       },
560     })
561   return libs
562
563 def UnsandboxedIRT(arch):
564   libs = {
565       GSDJoin('unsandboxed_irt', arch): {
566           'type': 'build',
567           'output_subdir': os.path.join('translator', arch, 'lib'),
568           # This lib #includes
569           # arbitrary stuff from native_client/src/{include,untrusted,trusted}
570           'inputs': { 'support': os.path.join(NACL_DIR, 'src', 'nonsfi', 'irt'),
571                       'untrusted': os.path.join(
572                           NACL_DIR, 'src', 'untrusted', 'irt'),
573                       'include': os.path.join(NACL_DIR, 'src'), },
574           'commands': [
575               # The NaCl headers insist on having a platform macro such as
576               # NACL_LINUX defined, but src/nonsfi/irt_interfaces.c does not
577               # itself use any of these macros, so defining NACL_LINUX here
578               # even on non-Linux systems is OK.
579               # TODO(dschuff): this include path breaks the input encapsulation
580               # for build rules.
581               command.Command([
582                   'gcc', '-m32', '-O2', '-Wall', '-Werror',
583                   '-I%(top_srcdir)s/..', '-DNACL_LINUX=1', '-DDEFINE_MAIN',
584                   '-c', command.path.join('%(support)s', 'irt_interfaces.c'),
585                   '-o', command.path.join('%(output)s', 'unsandboxed_irt.o')]),
586               command.Command([
587                   'gcc', '-m32', '-O2', '-Wall', '-Werror',
588                   '-I%(top_srcdir)s/..',
589                   '-c', command.path.join('%(untrusted)s', 'irt_query_list.c'),
590                   '-o', command.path.join('%(output)s', 'irt_query_list.o')]),
591           ],
592       },
593   }
594   return libs