import tempfile
-# Mapping from env['PLATFORM'] (scons) to a single host platform from the point
-# of view of NaCl.
-NACL_CANONICAL_PLATFORM_MAP = {
- 'win32': 'win',
- 'cygwin': 'win',
- 'posix': 'linux',
- 'linux': 'linux',
- 'linux2': 'linux',
- 'darwin': 'mac',
-}
-
NACL_TOOL_MAP = {
'arm': {
'32': {
'other_libdir': 'lib32',
'as_flag': '--32',
'cc_flag': '-m32',
- 'ld_flag': ' -melf_nacl',
+ 'ld_flag': ' -melf_i386_nacl',
},
'64': {
'tooldir': 'x86_64-nacl',
'other_libdir': 'lib64',
'as_flag': '--64',
'cc_flag': '-m64',
- 'ld_flag': ' -melf64_nacl',
+ 'ld_flag': ' -melf_x86_64_nacl',
},
},
}
assert(env.Bit('built_elsewhere'))
env.Replace(CC='true', CXX='true', LINK='true', AR='true',
RANLIB='true', AS='true', ASPP='true', LD='true',
- STRIP='true')
-
-def _PlatformSubdirs(env):
- if env.Bit('bitcode'):
- os = NACL_CANONICAL_PLATFORM_MAP[env['PLATFORM']]
- name = 'pnacl_%s_x86' % os
- else:
- platform = NACL_CANONICAL_PLATFORM_MAP[env['PLATFORM']]
- arch = env['BUILD_ARCHITECTURE']
- subarch = env['TARGET_SUBARCH']
- name = platform + '_' + arch
- if not env.Bit('nacl_glibc'):
- name = name + '_newlib'
- return name
-
-
-def _GetNaClSdkRoot(env, sdk_mode, psdk_mode):
- """Return the path to the sdk.
-
- Args:
- env: The SCons environment in question.
- sdk_mode: A string indicating which location to select the tools from.
- Returns:
- The path to the sdk.
- """
-
- # Allow pnacl to override its path separately. See comments for why
- # psdk_mode is separate from sdk_mode.
- if env.Bit('bitcode') and psdk_mode.startswith('custom:'):
- return os.path.abspath(psdk_mode[len('custom:'):])
-
- if sdk_mode == 'local':
- if env['PLATFORM'] in ['win32', 'cygwin']:
- # Try to use cygpath under the assumption we are running thru cygwin.
- # If this is not the case, then 'local' doesn't really make any sense,
- # so then we should complain.
- try:
- path = subprocess.Popen(
- ['cygpath', '-m', '/usr/local/nacl-sdk'],
- env={'PATH': os.environ['PRESCONS_PATH']}, shell=True,
- stdout=subprocess.PIPE).communicate()[0].replace('\n', '')
- except WindowsError:
- raise NotImplementedError(
- 'Not able to decide where /usr/local/nacl-sdk is on this platform,'
- 'use naclsdk_mode=custom:...')
- return path
- else:
- return '/usr/local/nacl-sdk'
-
- elif sdk_mode == 'download':
- tcname = _PlatformSubdirs(env)
- return os.path.join(env['MAIN_DIR'], 'toolchain', tcname)
- elif sdk_mode.startswith('custom:'):
- return os.path.abspath(sdk_mode[len('custom:'):])
-
- elif sdk_mode == 'manual':
- return None
-
- else:
- raise Exception('Unknown sdk mode: %r' % sdk_mode)
+ STRIP='true', PNACLOPT='true', PNACLFINALIZE='true')
def _SetEnvForNativeSdk(env, sdk_path):
def _SetEnvForPnacl(env, root):
# All the PNaCl tools require Python to be in the PATH.
- # On the Windows bots, however, Python is not installed system-wide.
- # It must be pulled from ../third_party/python_26.
- python_dir = os.path.join('..', 'third_party', 'python_26')
- env.AppendENVPath('PATH', python_dir)
-
arch = env['TARGET_FULLARCH']
- assert arch in ['arm', 'arm-thumb2', 'mips32', 'x86-32', 'x86-64']
+ assert arch in ['arm', 'mips32', 'x86-32', 'x86-64']
if env.Bit('pnacl_unsandboxed'):
- arch = 'linux-%s' % arch
+ if env.Bit('host_linux'):
+ arch = '%s-linux' % arch
+ elif env.Bit('host_mac'):
+ arch = '%s-mac' % arch
+ if env.Bit('nonsfi_nacl'):
+ arch += '-nonsfi'
arch_flag = ' -arch %s' % arch
if env.Bit('pnacl_generate_pexe'):
ld_arch_flag = ''
else:
ld_arch_flag = arch_flag
- if env.Bit('nacl_glibc'):
- subroot = root + '/glibc'
- else:
- subroot = root
+ llc_mtriple_flag = ''
+ if env.Bit('minsfi'):
+ llc_cpu = ''
+ if env.Bit('build_x86_32'):
+ llc_cpu = 'i686'
+ elif env.Bit('build_x86_64'):
+ llc_cpu = 'x86_64'
+
+ if env.Bit('host_linux'):
+ llc_mtriple_flag = ' -mtriple=%s-linux-gnu' % llc_cpu
+ elif env.Bit('host_mac'):
+ llc_mtriple_flag = ' -mtriple=%s-apple-darwin' % llc_cpu
translator_root = os.path.join(os.path.dirname(root), 'pnacl_translator')
- binprefix = os.path.join(subroot, 'bin', 'pnacl-')
+ binprefix = os.path.join(root, 'bin', 'pnacl-')
binext = ''
if env.Bit('host_windows'):
binext = '.bat'
- if env.Bit('nacl_glibc'):
- # TODO(pdox): This bias is needed because runnable-ld is
- # expected to be in the same directory as the SDK.
- # This assumption should be removed.
- pnacl_lib = os.path.join(root, 'lib-%s' % arch)
- pnacl_extra_lib = os.path.join(subroot, 'lib')
- else:
- pnacl_lib = os.path.join(subroot, 'lib')
- pnacl_extra_lib = ''
-
- #TODO(robertm): remove NACL_SDK_INCLUDE ASAP
- if env.Bit('nacl_glibc'):
- pnacl_include = os.path.join(root, 'glibc', 'usr', 'include')
- else:
- pnacl_include = os.path.join(root, 'usr', 'include')
-
pnacl_ar = binprefix + 'ar' + binext
pnacl_as = binprefix + 'as' + binext
pnacl_nm = binprefix + 'nm' + binext
pnacl_cxx = binprefix + 'clang++' + binext
pnacl_ld = binprefix + 'ld' + binext
- pnacl_nativeld = binprefix + 'nativeld' + binext
pnacl_disass = binprefix + 'dis' + binext
pnacl_finalize = binprefix + 'finalize' + binext
+ pnacl_opt = binprefix + 'opt' + binext
pnacl_strip = binprefix + 'strip' + binext
+ pnacl_llc = binprefix + 'llc' + binext
# NOTE: XXX_flags start with space for easy concatenation
# The flags generated here get baked into the commands (CC, CXX, LINK)
pnacl_cc_flags = ' -std=gnu99'
pnacl_ld_flags = ' ' + ' '.join(env['PNACL_BCLDFLAGS'])
pnacl_translate_flags = ''
+ pnacl_llc_flags = ''
if env.Bit('nacl_pic'):
pnacl_cc_flags += ' -fPIC'
pnacl_ld_flags += ' -fPIC'
pnacl_translate_flags += ' -fPIC'
+ if env.Bit('minsfi'):
+ pnacl_llc_flags += ' -relocation-model=pic -filetype=obj'
+ pnacl_ld_flags += ' -nostdlib -Wl,-r -L' + os.path.join(root, 'usr', 'lib')
+
if env.Bit('use_sandboxed_translator'):
sb_flags = ' --pnacl-sb'
pnacl_ld_flags += sb_flags
if env.Bit('x86_64_zero_based_sandbox'):
pnacl_translate_flags += ' -sfi-zero-based-sandbox'
- if pnacl_extra_lib:
- env.Prepend(LIBPATH=pnacl_extra_lib)
-
env.Replace(# Replace header and lib paths.
- NACL_SDK_INCLUDE=pnacl_include,
- NACL_SDK_LIB=pnacl_lib,
+ NACL_SDK_INCLUDE=os.path.join(root, 'le32-nacl', 'include'),
+ NACL_SDK_LIB=os.path.join(root, 'le32-nacl', 'lib'),
# Remove arch-specific flags (if any)
BASE_LINKFLAGS='',
BASE_CFLAGS='',
# with shared libraries except use them with the toolchain.
SHLINK=pnacl_cxx + ld_arch_flag + pnacl_ld_flags,
LD=pnacl_ld,
- NATIVELD=pnacl_nativeld,
AR=pnacl_ar,
AS=pnacl_as + ld_arch_flag,
RANLIB=pnacl_ranlib,
STRIP=pnacl_strip,
TRANSLATE=pnacl_translate + arch_flag + pnacl_translate_flags,
PNACLFINALIZE=pnacl_finalize,
+ PNACLOPT=pnacl_opt,
+ LLC=pnacl_llc + llc_mtriple_flag + pnacl_llc_flags,
)
if env.Bit('built_elsewhere'):
env.Replace(PNACLFINALIZE='true')
-def _SetEnvForSdkManually(env):
- def GetEnvOrDummy(v):
- return os.getenv('NACL_SDK_' + v, 'MISSING_SDK_' + v)
-
- env.Replace(# Replace header and lib paths.
- NACL_SDK_INCLUDE=GetEnvOrDummy('INCLUDE'),
- NACL_SDK_LIB=GetEnvOrDummy('LIB'),
- # Replace the normal unix tools with the NaCl ones.
- CC=GetEnvOrDummy('CC'),
- CXX=GetEnvOrDummy('CXX'),
- AR=GetEnvOrDummy('AR'),
- # NOTE: use g++ for linking so we can handle c AND c++
- LINK=GetEnvOrDummy('LINK'),
- RANLIB=GetEnvOrDummy('RANLIB'),
- )
-
def PNaClForceNative(env):
assert(env.Bit('bitcode'))
if env.Bit('pnacl_generate_pexe'):
CXX=arch_flag + cc_flags,
ASPP=arch_flag + cc_flags,
LINK=cc_flags) # Already has -arch
- env['LD'] = '${NATIVELD}' + arch_flag
+ env['LD'] = 'NO-NATIVE-LD-INVOCATION-ALLOWED'
env['SHLINK'] = '${LINK}'
if env.Bit('built_elsewhere'):
_StubOutEnvToolsForBuiltElsewhere(env)
env.AddMethod(PNaClForceNative)
env.AddMethod(PNaClGetNNaClEnv)
- # Get configuration option for getting the naclsdk. Default is download.
- # We have a separate flag for pnacl "psdk_mode" since even with PNaCl,
- # the native nacl-gcc toolchain is used to build some parts like
- # the irt-core.
- sdk_mode = SCons.Script.ARGUMENTS.get('naclsdk_mode', 'download')
- psdk_mode = SCons.Script.ARGUMENTS.get('pnaclsdk_mode', 'default')
- if psdk_mode != 'default' and not psdk_mode.startswith('custom:'):
- raise Exception(
- 'pnaclsdk_mode only supports "default" or "custom:path", not %s' %
- psdk_mode)
-
# Invoke the various unix tools that the NativeClient SDK resembles.
env.Tool('g++')
env.Tool('gcc')
# Note: it appears we cannot add this in component_setup.py
STRIPFLAGS=['--strip-all'],
STRIPCOM='${STRIP} ${STRIPFLAGS}',
- TRANSLATEFLAGS=['-Wl,-L${LIB_DIR}'],
TRANSLATECOM='${TRANSLATE} ${TRANSLATEFLAGS} ${SOURCES} -o ${TARGET}',
PNACLFINALIZEFLAGS=[],
PNACLFINALIZECOM='${PNACLFINALIZE} ${PNACLFINALIZEFLAGS} ' +
env[com] = "${TEMPFILE('%s')}" % env[com]
# Get root of the SDK.
- root = _GetNaClSdkRoot(env, sdk_mode, psdk_mode)
+ root = env.GetToolchainDir()
- # Determine where to get the SDK from.
- if sdk_mode == 'manual':
- _SetEnvForSdkManually(env)
+ # if bitcode=1 use pnacl toolchain
+ if env.Bit('bitcode'):
+ _SetEnvForPnacl(env, root)
+
+ # Get GDB from the nacl-gcc toolchain even when using PNaCl.
+ # TODO(mseaborn): We really want the nacl-gdb binary to be in a
+ # separate tarball from the nacl-gcc toolchain, then this step
+ # will not be necessary.
+ # See http://code.google.com/p/nativeclient/issues/detail?id=2773
+ if env.Bit('target_x86'):
+ temp_env = env.Clone()
+ temp_env.ClearBits('bitcode')
+ temp_root = temp_env.GetToolchainDir()
+ _SetEnvForNativeSdk(temp_env, temp_root)
+ env.Replace(GDB=temp_env['GDB'])
+ elif env.Bit('built_elsewhere'):
+ _StubOutEnvToolsForBuiltElsewhere(env)
else:
- # if bitcode=1 use pnacl toolchain
- if env.Bit('bitcode'):
- _SetEnvForPnacl(env, root)
-
- # Get GDB from the nacl-gcc toolchain even when using PNaCl.
- # TODO(mseaborn): We really want the nacl-gdb binary to be in a
- # separate tarball from the nacl-gcc toolchain, then this step
- # will not be necessary.
- # See http://code.google.com/p/nativeclient/issues/detail?id=2773
- if env.Bit('target_x86'):
- temp_env = env.Clone()
- temp_env.ClearBits('bitcode')
- temp_root = _GetNaClSdkRoot(temp_env, sdk_mode, psdk_mode)
- _SetEnvForNativeSdk(temp_env, temp_root)
- env.Replace(GDB=temp_env['GDB'])
- elif env.Bit('built_elsewhere'):
- _StubOutEnvToolsForBuiltElsewhere(env)
- else:
- _SetEnvForNativeSdk(env, root)
+ _SetEnvForNativeSdk(env, root)
env.Prepend(LIBPATH='${NACL_SDK_LIB}')
recursive=True
)
env.Append(SCANNERS=ldscript_scanner)
+
+ # Scons tests can check this version number to decide whether to
+ # enable tests for toolchain bug fixes or new features. See
+ # description in pnacl/build.sh.
+ if 'toolchain_feature_version' in SCons.Script.ARGUMENTS:
+ version = int(SCons.Script.ARGUMENTS['toolchain_feature_version'])
+ else:
+ version_file = os.path.join(root, 'FEATURE_VERSION')
+ # There is no pnacl_newlib toolchain on ARM, only a pnacl_translator, so
+ # use that if necessary. Otherwise use it if we are doing sandboxed
+ # translation.
+ if not os.path.exists(version_file) or env.Bit('use_sandboxed_translator'):
+ version_file = os.path.join(os.path.dirname(root), 'pnacl_translator',
+ 'FEATURE_VERSION')
+ if os.path.exists(version_file):
+ with open(version_file, 'r') as fh:
+ version = int(fh.read())
+ else:
+ version = 0
+ env.Replace(TOOLCHAIN_FEATURE_VERSION=version)