OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """NaCl SDK tool SCons.""" | 6 """NaCl SDK tool SCons.""" |
7 | 7 |
8 import __builtin__ | 8 import __builtin__ |
9 import re | 9 import re |
10 import os | 10 import os |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 Args: | 52 Args: |
53 env: The SCons environment in question. | 53 env: The SCons environment in question. |
54 """ | 54 """ |
55 assert(env.Bit('built_elsewhere')) | 55 assert(env.Bit('built_elsewhere')) |
56 env.Replace(CC='true', CXX='true', LINK='true', AR='true', | 56 env.Replace(CC='true', CXX='true', LINK='true', AR='true', |
57 RANLIB='true', AS='true', ASPP='true', LD='true', | 57 RANLIB='true', AS='true', ASPP='true', LD='true', |
58 STRIP='true') | 58 STRIP='true') |
59 | 59 |
60 | 60 |
61 def _GetNaClSdkRoot(env, sdk_mode, psdk_mode): | |
62 """Return the path to the sdk. | |
63 | |
64 Args: | |
65 env: The SCons environment in question. | |
66 sdk_mode: A string indicating which location to select the tools from. | |
67 Returns: | |
68 The path to the sdk. | |
69 """ | |
70 | |
71 # Allow pnacl to override its path separately. See comments for why | |
72 # psdk_mode is separate from sdk_mode. | |
73 if env.Bit('bitcode') and psdk_mode.startswith('custom:'): | |
74 return os.path.abspath(psdk_mode[len('custom:'):]) | |
75 | |
76 if sdk_mode == 'local': | |
77 if env['PLATFORM'] in ['win32', 'cygwin']: | |
78 # Try to use cygpath under the assumption we are running thru cygwin. | |
79 # If this is not the case, then 'local' doesn't really make any sense, | |
80 # so then we should complain. | |
81 try: | |
82 path = subprocess.Popen( | |
83 ['cygpath', '-m', '/usr/local/nacl-sdk'], | |
84 shell=True, | |
85 stdout=subprocess.PIPE).communicate()[0].replace('\n', '') | |
86 except WindowsError: | |
87 raise NotImplementedError( | |
88 'Not able to decide where /usr/local/nacl-sdk is on this platform,' | |
89 'use naclsdk_mode=custom:...') | |
90 return path | |
91 else: | |
92 return '/usr/local/nacl-sdk' | |
93 | |
94 elif sdk_mode == 'download': | |
95 return env.GetToolchainDir() | |
96 elif sdk_mode.startswith('custom:'): | |
97 return os.path.abspath(sdk_mode[len('custom:'):]) | |
98 | |
99 elif sdk_mode == 'manual': | |
100 return None | |
101 | |
102 else: | |
103 raise Exception('Unknown sdk mode: %r' % sdk_mode) | |
104 | |
105 | |
106 def _SetEnvForNativeSdk(env, sdk_path): | 61 def _SetEnvForNativeSdk(env, sdk_path): |
107 """Initialize environment according to target architecture.""" | 62 """Initialize environment according to target architecture.""" |
108 | 63 |
109 bin_path = os.path.join(sdk_path, 'bin') | 64 bin_path = os.path.join(sdk_path, 'bin') |
110 # NOTE: attempts to eliminate this PATH setting and use | 65 # NOTE: attempts to eliminate this PATH setting and use |
111 # absolute path have been futile | 66 # absolute path have been futile |
112 env.PrependENVPath('PATH', bin_path) | 67 env.PrependENVPath('PATH', bin_path) |
113 | 68 |
114 tool_prefix = None | 69 tool_prefix = None |
115 tool_map = NACL_TOOL_MAP[env['TARGET_ARCHITECTURE']] | 70 tool_map = NACL_TOOL_MAP[env['TARGET_ARCHITECTURE']] |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 if env.Bit('built_elsewhere'): | 288 if env.Bit('built_elsewhere'): |
334 def FakeInstall(dest, source, env): | 289 def FakeInstall(dest, source, env): |
335 print 'Not installing', dest | 290 print 'Not installing', dest |
336 _StubOutEnvToolsForBuiltElsewhere(env) | 291 _StubOutEnvToolsForBuiltElsewhere(env) |
337 env.Replace(INSTALL=FakeInstall) | 292 env.Replace(INSTALL=FakeInstall) |
338 if env.Bit('translate_in_build_step'): | 293 if env.Bit('translate_in_build_step'): |
339 env.Replace(TRANSLATE='true') | 294 env.Replace(TRANSLATE='true') |
340 env.Replace(PNACLFINALIZE='true') | 295 env.Replace(PNACLFINALIZE='true') |
341 | 296 |
342 | 297 |
343 def _SetEnvForSdkManually(env): | |
344 def GetEnvOrDummy(v): | |
345 return os.getenv('NACL_SDK_' + v, 'MISSING_SDK_' + v) | |
346 | |
347 env.Replace(# Replace header and lib paths. | |
348 NACL_SDK_INCLUDE=GetEnvOrDummy('INCLUDE'), | |
349 NACL_SDK_LIB=GetEnvOrDummy('LIB'), | |
350 # Replace the normal unix tools with the NaCl ones. | |
351 CC=GetEnvOrDummy('CC'), | |
352 CXX=GetEnvOrDummy('CXX'), | |
353 AR=GetEnvOrDummy('AR'), | |
354 # NOTE: use g++ for linking so we can handle c AND c++ | |
355 LINK=GetEnvOrDummy('LINK'), | |
356 RANLIB=GetEnvOrDummy('RANLIB'), | |
357 ) | |
358 | |
359 def PNaClForceNative(env): | 298 def PNaClForceNative(env): |
360 assert(env.Bit('bitcode')) | 299 assert(env.Bit('bitcode')) |
361 if env.Bit('pnacl_generate_pexe'): | 300 if env.Bit('pnacl_generate_pexe'): |
362 env.Replace(CC='NO-NATIVE-CC-INVOCATION-ALLOWED', | 301 env.Replace(CC='NO-NATIVE-CC-INVOCATION-ALLOWED', |
363 CXX='NO-NATIVE-CXX-INVOCATION-ALLOWED') | 302 CXX='NO-NATIVE-CXX-INVOCATION-ALLOWED') |
364 return | 303 return |
365 | 304 |
366 env.Replace(OBJSUFFIX='.o', | 305 env.Replace(OBJSUFFIX='.o', |
367 SHLIBSUFFIX='.so') | 306 SHLIBSUFFIX='.so') |
368 arch_flag = ' -arch ${TARGET_FULLARCH}' | 307 arch_flag = ' -arch ${TARGET_FULLARCH}' |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 | 583 |
645 NOTE: SCons requires the use of this name, which fails lint. | 584 NOTE: SCons requires the use of this name, which fails lint. |
646 """ | 585 """ |
647 | 586 |
648 # make these methods to the top level scons file | 587 # make these methods to the top level scons file |
649 env.AddMethod(ValidateSdk) | 588 env.AddMethod(ValidateSdk) |
650 env.AddMethod(AddBiasForPNaCl) | 589 env.AddMethod(AddBiasForPNaCl) |
651 env.AddMethod(PNaClForceNative) | 590 env.AddMethod(PNaClForceNative) |
652 env.AddMethod(PNaClGetNNaClEnv) | 591 env.AddMethod(PNaClGetNNaClEnv) |
653 | 592 |
654 # Get configuration option for getting the naclsdk. Default is download. | |
655 # We have a separate flag for pnacl "psdk_mode" since even with PNaCl, | |
656 # the native nacl-gcc toolchain is used to build some parts like | |
657 # the irt-core. | |
658 sdk_mode = SCons.Script.ARGUMENTS.get('naclsdk_mode', 'download') | |
659 psdk_mode = SCons.Script.ARGUMENTS.get('pnaclsdk_mode', 'default') | |
660 if psdk_mode != 'default' and not psdk_mode.startswith('custom:'): | |
661 raise Exception( | |
662 'pnaclsdk_mode only supports "default" or "custom:path", not %s' % | |
663 psdk_mode) | |
664 | |
665 # Invoke the various unix tools that the NativeClient SDK resembles. | 593 # Invoke the various unix tools that the NativeClient SDK resembles. |
666 env.Tool('g++') | 594 env.Tool('g++') |
667 env.Tool('gcc') | 595 env.Tool('gcc') |
668 env.Tool('gnulink') | 596 env.Tool('gnulink') |
669 env.Tool('ar') | 597 env.Tool('ar') |
670 env.Tool('as') | 598 env.Tool('as') |
671 | 599 |
672 if env.Bit('pnacl_generate_pexe'): | 600 if env.Bit('pnacl_generate_pexe'): |
673 suffix = '.nonfinal.pexe' | 601 suffix = '.nonfinal.pexe' |
674 else: | 602 else: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
723 # Windows has a small limit on the command line size. The linking and AR | 651 # Windows has a small limit on the command line size. The linking and AR |
724 # commands can get quite large. So bring in the SCons machinery to put | 652 # commands can get quite large. So bring in the SCons machinery to put |
725 # most of a command line into a temporary file and pass it with | 653 # most of a command line into a temporary file and pass it with |
726 # @filename, which works with gcc. | 654 # @filename, which works with gcc. |
727 if env['PLATFORM'] in ['win32', 'cygwin']: | 655 if env['PLATFORM'] in ['win32', 'cygwin']: |
728 env['TEMPFILE'] = NaClTempFileMunge | 656 env['TEMPFILE'] = NaClTempFileMunge |
729 for com in ['LINKCOM', 'SHLINKCOM', 'ARCOM']: | 657 for com in ['LINKCOM', 'SHLINKCOM', 'ARCOM']: |
730 env[com] = "${TEMPFILE('%s')}" % env[com] | 658 env[com] = "${TEMPFILE('%s')}" % env[com] |
731 | 659 |
732 # Get root of the SDK. | 660 # Get root of the SDK. |
733 root = _GetNaClSdkRoot(env, sdk_mode, psdk_mode) | 661 root = env.GetToolchainDir() |
734 | 662 |
735 # Determine where to get the SDK from. | 663 # if bitcode=1 use pnacl toolchain |
736 if sdk_mode == 'manual': | 664 if env.Bit('bitcode'): |
737 _SetEnvForSdkManually(env) | 665 _SetEnvForPnacl(env, root) |
| 666 |
| 667 # Get GDB from the nacl-gcc toolchain even when using PNaCl. |
| 668 # TODO(mseaborn): We really want the nacl-gdb binary to be in a |
| 669 # separate tarball from the nacl-gcc toolchain, then this step |
| 670 # will not be necessary. |
| 671 # See http://code.google.com/p/nativeclient/issues/detail?id=2773 |
| 672 if env.Bit('target_x86'): |
| 673 temp_env = env.Clone() |
| 674 temp_env.ClearBits('bitcode') |
| 675 temp_root = temp_env.GetToolchainDir() |
| 676 _SetEnvForNativeSdk(temp_env, temp_root) |
| 677 env.Replace(GDB=temp_env['GDB']) |
| 678 elif env.Bit('built_elsewhere'): |
| 679 _StubOutEnvToolsForBuiltElsewhere(env) |
738 else: | 680 else: |
739 # if bitcode=1 use pnacl toolchain | 681 _SetEnvForNativeSdk(env, root) |
740 if env.Bit('bitcode'): | |
741 _SetEnvForPnacl(env, root) | |
742 | |
743 # Get GDB from the nacl-gcc toolchain even when using PNaCl. | |
744 # TODO(mseaborn): We really want the nacl-gdb binary to be in a | |
745 # separate tarball from the nacl-gcc toolchain, then this step | |
746 # will not be necessary. | |
747 # See http://code.google.com/p/nativeclient/issues/detail?id=2773 | |
748 if env.Bit('target_x86'): | |
749 temp_env = env.Clone() | |
750 temp_env.ClearBits('bitcode') | |
751 temp_root = _GetNaClSdkRoot(temp_env, sdk_mode, psdk_mode) | |
752 _SetEnvForNativeSdk(temp_env, temp_root) | |
753 env.Replace(GDB=temp_env['GDB']) | |
754 elif env.Bit('built_elsewhere'): | |
755 _StubOutEnvToolsForBuiltElsewhere(env) | |
756 else: | |
757 _SetEnvForNativeSdk(env, root) | |
758 | 682 |
759 env.Prepend(LIBPATH='${NACL_SDK_LIB}') | 683 env.Prepend(LIBPATH='${NACL_SDK_LIB}') |
760 | 684 |
761 # Install our scanner for (potential) linker scripts. | 685 # Install our scanner for (potential) linker scripts. |
762 # It applies to "source" files ending in .a or .so. | 686 # It applies to "source" files ending in .a or .so. |
763 # Dependency files it produces are to be found in ${LIBPATH}. | 687 # Dependency files it produces are to be found in ${LIBPATH}. |
764 # It is applied recursively to those dependencies in case | 688 # It is applied recursively to those dependencies in case |
765 # some of them are linker scripts too. | 689 # some of them are linker scripts too. |
766 ldscript_scanner = SCons.Scanner.Base( | 690 ldscript_scanner = SCons.Scanner.Base( |
767 function=ScanLinkerScript, | 691 function=ScanLinkerScript, |
768 skeys=['.a', '.so', '.pso'], | 692 skeys=['.a', '.so', '.pso'], |
769 path_function=SCons.Scanner.FindPathDirs('LIBPATH'), | 693 path_function=SCons.Scanner.FindPathDirs('LIBPATH'), |
770 recursive=True | 694 recursive=True |
771 ) | 695 ) |
772 env.Append(SCANNERS=ldscript_scanner) | 696 env.Append(SCANNERS=ldscript_scanner) |
773 | 697 |
774 # Scons tests can check this version number to decide whether to | 698 # Scons tests can check this version number to decide whether to |
775 # enable tests for toolchain bug fixes or new features. See | 699 # enable tests for toolchain bug fixes or new features. See |
776 # description in pnacl/build.sh. | 700 # description in pnacl/build.sh. |
777 if 'toolchain_feature_version' in SCons.Script.ARGUMENTS: | 701 if 'toolchain_feature_version' in SCons.Script.ARGUMENTS: |
778 version = int(SCons.Script.ARGUMENTS['toolchain_feature_version']) | 702 version = int(SCons.Script.ARGUMENTS['toolchain_feature_version']) |
779 else: | 703 else: |
780 version_file = os.path.join(root, 'FEATURE_VERSION') | 704 version_file = os.path.join(root, 'FEATURE_VERSION') |
781 if os.path.exists(version_file): | 705 if os.path.exists(version_file): |
782 with open(version_file, 'r') as fh: | 706 with open(version_file, 'r') as fh: |
783 version = int(fh.read()) | 707 version = int(fh.read()) |
784 else: | 708 else: |
785 version = 0 | 709 version = 0 |
786 env.Replace(TOOLCHAIN_FEATURE_VERSION=version) | 710 env.Replace(TOOLCHAIN_FEATURE_VERSION=version) |
OLD | NEW |