Index: SConstruct |
diff --git a/SConstruct b/SConstruct |
index 7529deb3519967a396b9ccff52d1dd5eda0b3d6c..789835af543c64a8c2379114925fed28737223c7 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 does NOT work with pnacl _pexes_ right now, because |
+ # the NEEDED metadata in the bitcode doesn't have the original file paths. |
+ # This should probably be done without such knowledge. |
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,66 +1351,92 @@ 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) |
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}') |
- nmf_node = env.Command( |
- '${STAGING_DIR}/' + manifest_base_name, |
- [manifest, lib_list_node], |
- GenerateManifestFunc) |
+ manifest_map[manifest_base_name] = main_program |
+ if is_portable: |
+ nmf_node = env.Command( |
+ result, |
+ ['${GENNMF}', |
+ env.File('${STAGING_DIR}/' + os.path.basename(main_program))], |
+ # Generate a flat url scheme to simplify file-staging. |
+ '${SOURCES[0]} -L${NACL_SDK_LIB} -L${LIB_DIR} ' + |
+ ' --flat-url-scheme ${SOURCES[1]} -o ${TARGET}') |
+ else: |
+ # Run sel_ldr on the nexe to trace the NEEDED libraries. |
+ 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(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], |
+ GenerateManifestFunc) |
return result |