| Index: SConstruct
|
| diff --git a/SConstruct b/SConstruct
|
| index 7529deb3519967a396b9ccff52d1dd5eda0b3d6c..72f6e0a1cb6fe8a463df05260af8098bf4c3f6e9 100755
|
| --- a/SConstruct
|
| +++ b/SConstruct
|
| @@ -1308,6 +1308,9 @@ def CopyLibsForExtensionCommand(target, source, env):
|
| lib_info = ParseLibInfoInRunnableLdLog(line)
|
| if lib_info:
|
| lib_name, lib_path = lib_info
|
| + # Note: This probably work with pnacl _pexes_ right now, because
|
| + # the NEEDED metadata in the bitcode doesn't have the original file paths.
|
| + # It probably shouldn't have the original file paths anyway...
|
| shutil.copyfile(lib_path, os.path.join(target_dir, lib_name))
|
| shutil.copyfile(env.subst('${NACL_SDK_LIB}/runnable-ld.so'),
|
| os.path.join(target_dir, 'runnable-ld.so'))
|
| @@ -1334,9 +1337,11 @@ pre_base_env.AddMethod(CopyLibsForExtension)
|
| # Generate manifest from newlib manifest and the list of libs generated by
|
| # runnable-ld.so.
|
| def GenerateManifestFunc(target, source, env):
|
| + # Open the original manifest and parse it.
|
| source_file = open(str(source[0]), 'r')
|
| obj = json.load(source_file)
|
| source_file.close()
|
| + # Open the file with ldd-format list of NEEDED libs and parse it.
|
| libs_file = open(str(source[1]), 'r')
|
| lib_names = []
|
| arch = env.subst('${TARGET_FULLARCH}')
|
| @@ -1346,62 +1351,90 @@ def GenerateManifestFunc(target, source, env):
|
| lib_name, _ = lib_info
|
| lib_names.append(lib_name)
|
| libs_file.close()
|
| + # Inject the NEEDED libs into the manifest.
|
| if 'files' not in obj:
|
| obj['files'] = {}
|
| for lib_name in lib_names:
|
| obj['files'][lib_name] = {}
|
| obj['files'][lib_name][arch] = {}
|
| obj['files'][lib_name][arch]['url'] = lib_name
|
| + # Put what used to be specified under 'program' into 'main.nexe'.
|
| obj['files']['main.nexe'] = {}
|
| for k, v in obj['program'].items():
|
| obj['files']['main.nexe'][k] = v.copy()
|
| v['url'] = 'runnable-ld.so'
|
| + # Put runnable-ld.so into the 'program' field, for all known
|
| + # NMF architectures (besides 'portable').
|
| + new_program_dict = {}
|
| + obj['program'] = new_program_dict
|
| + for arch in ['x86-32', 'x86-64', 'arm']:
|
| + new_program_dict[arch] = {}
|
| + new_program_dict[arch]['url'] = 'runnable-ld.so'
|
| + # Write the new manifest!
|
| target_file = open(str(target[0]), 'w')
|
| json.dump(obj, target_file)
|
| target_file.close()
|
| return 0
|
|
|
|
|
| -# Returns nexe specified in manifest file.
|
| -def GetNexeFromManifest(env, manifest):
|
| +# Returns a pair (main program, is_portable), based on the program
|
| +# specified in manifest file.
|
| +def GetMainProgramFromManifest(env, manifest):
|
| manifest_file = open(str(env.File(manifest)), 'r')
|
| obj = json.load(manifest_file)
|
| manifest_file.close()
|
| - nexe = obj['program'][env.subst('${TARGET_FULLARCH}')]['url']
|
| - return nexe
|
| -
|
| + program_dict = obj['program']
|
| + if env.Bit('bitcode'):
|
| + # For Pnacl we are not yet always using the 'portable' key in the manifest.
|
| + # Sometimes we translate to a native nexe for testing.
|
| + if 'portable' in program_dict.keys():
|
| + return (program_dict['portable']['url'], True)
|
| + # otherwise, fall through to nexe case.
|
| + return (program_dict[env.subst('${TARGET_FULLARCH}')]['url'], False)
|
| +
|
| +# Is this for detecting if we've staged a manifest file yet or not?
|
| manifest_map = {}
|
|
|
| -
|
| # Returns scons node for generated manifest.
|
| def GeneratedManifestNode(env, manifest):
|
| manifest = env.subst(manifest)
|
| manifest_base_name = os.path.basename(manifest)
|
| - nexe = GetNexeFromManifest(env, manifest)
|
| + main_program, is_portable = GetMainProgramFromManifest(env, manifest)
|
| result = env.File('${STAGING_DIR}/' + manifest_base_name)
|
| if not env.Bit('nacl_glibc'):
|
| if manifest_base_name not in manifest_map:
|
| env.Install('${STAGING_DIR}', manifest)
|
| - manifest_map[manifest_base_name] = nexe
|
| + manifest_map[manifest_base_name] = main_program
|
| # fall through
|
| if manifest_base_name in manifest_map:
|
| - if manifest_map[manifest_base_name] != nexe:
|
| - print nexe
|
| + if manifest_map[manifest_base_name] != main_program:
|
| + print main_program
|
| print manifest_map[manifest_base_name]
|
| raise Exception("Two manifest files with the same name")
|
| return result
|
| - manifest_map[manifest_base_name] = nexe
|
| - lib_list_node = env.Command(
|
| - '${STAGING_DIR}/' + manifest_base_name + '.libs',
|
| - [GetSelLdr(env),
|
| - '${NACL_SDK_LIB}/runnable-ld.so',
|
| - env.File('${STAGING_DIR}/' + os.path.basename(nexe)),
|
| - '${SCONSTRUCT_DIR}/DEPS'],
|
| - # We ignore return code using '-' in order to build tests where binaries
|
| - # do not validate. This is the scons feature.
|
| - '-${SOURCES[0]} -a -E LD_TRACE_LOADED_OBJECTS=1 ${SOURCES[1]} '
|
| - '--library-path ${NACL_SDK_LIB}:${LIB_DIR} ${SOURCES[2].posix} '
|
| - '> ${TARGET}')
|
| + manifest_map[manifest_base_name] = main_program
|
| + lib_list_filename = '${STAGING_DIR}/' + manifest_base_name + '.libs'
|
| + if is_portable:
|
| + # Use pnacl-meta to extract the NEEDED libraries.
|
| + # Note: This relies on the pexe containing the transitive dependencies.
|
| + lib_list_node = env.Command(
|
| + lib_list_filename,
|
| + ['${READMETA}',
|
| + env.File('${STAGING_DIR}/' + os.path.basename(main_program))],
|
| + '${SOURCES[0]} --format=ldd ${SOURCES[1]} > ${TARGET}')
|
| + else:
|
| + # Run sel_ldr on the nexe to trace the NEEDED libraries.
|
| + lib_list_node = env.Command(
|
| + lib_list_filename,
|
| + [GetSelLdr(env),
|
| + '${NACL_SDK_LIB}/runnable-ld.so',
|
| + env.File('${STAGING_DIR}/' + os.path.basename(main_program)),
|
| + '${SCONSTRUCT_DIR}/DEPS'],
|
| + # We ignore return code using '-' in order to build tests where binaries
|
| + # do not validate. This is the scons feature.
|
| + '-${SOURCES[0]} -a -E LD_TRACE_LOADED_OBJECTS=1 ${SOURCES[1]} '
|
| + '--library-path ${NACL_SDK_LIB}:${LIB_DIR} ${SOURCES[2].posix} '
|
| + '> ${TARGET}')
|
| nmf_node = env.Command(
|
| '${STAGING_DIR}/' + manifest_base_name,
|
| [manifest, lib_list_node],
|
|
|