OLD | NEW |
1 #! -*- python -*- | 1 #! -*- 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 import atexit | 6 import atexit |
7 import glob | 7 import glob |
8 import os | 8 import os |
9 import platform | 9 import platform |
10 import shutil | 10 import shutil |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1301 def CopyLibsForExtensionCommand(target, source, env): | 1301 def CopyLibsForExtensionCommand(target, source, env): |
1302 source_manifest = str(source[0]) | 1302 source_manifest = str(source[0]) |
1303 target_manifest = str(target[0]) | 1303 target_manifest = str(target[0]) |
1304 shutil.copyfile(source_manifest, target_manifest) | 1304 shutil.copyfile(source_manifest, target_manifest) |
1305 target_dir = os.path.dirname(target_manifest) | 1305 target_dir = os.path.dirname(target_manifest) |
1306 libs_file = open(str(source[1]), 'r') | 1306 libs_file = open(str(source[1]), 'r') |
1307 for line in libs_file.readlines(): | 1307 for line in libs_file.readlines(): |
1308 lib_info = ParseLibInfoInRunnableLdLog(line) | 1308 lib_info = ParseLibInfoInRunnableLdLog(line) |
1309 if lib_info: | 1309 if lib_info: |
1310 lib_name, lib_path = lib_info | 1310 lib_name, lib_path = lib_info |
| 1311 # Note: This probably does NOT work with pnacl _pexes_ right now, because |
| 1312 # the NEEDED metadata in the bitcode doesn't have the original file paths. |
| 1313 # This should probably be done without such knowledge. |
1311 shutil.copyfile(lib_path, os.path.join(target_dir, lib_name)) | 1314 shutil.copyfile(lib_path, os.path.join(target_dir, lib_name)) |
1312 shutil.copyfile(env.subst('${NACL_SDK_LIB}/runnable-ld.so'), | 1315 shutil.copyfile(env.subst('${NACL_SDK_LIB}/runnable-ld.so'), |
1313 os.path.join(target_dir, 'runnable-ld.so')) | 1316 os.path.join(target_dir, 'runnable-ld.so')) |
1314 libs_file.close() | 1317 libs_file.close() |
1315 | 1318 |
1316 | 1319 |
1317 # Extensions are loaded from directory on disk and so all dynamic libraries | 1320 # Extensions are loaded from directory on disk and so all dynamic libraries |
1318 # they use must be copied to extension directory. The option --extra_serving_dir | 1321 # they use must be copied to extension directory. The option --extra_serving_dir |
1319 # does not help us in this case. | 1322 # does not help us in this case. |
1320 def CopyLibsForExtension(env, target_dir, manifest): | 1323 def CopyLibsForExtension(env, target_dir, manifest): |
1321 if not env.Bit('nacl_glibc'): | 1324 if not env.Bit('nacl_glibc'): |
1322 return env.Install(target_dir, manifest) | 1325 return env.Install(target_dir, manifest) |
1323 manifest_base_name = os.path.basename(str(env.subst(manifest))) | 1326 manifest_base_name = os.path.basename(str(env.subst(manifest))) |
1324 lib_list_node = env.File('${STAGING_DIR}/' + manifest_base_name + '.libs') | 1327 lib_list_node = env.File('${STAGING_DIR}/' + manifest_base_name + '.libs') |
1325 nmf_node = env.Command( | 1328 nmf_node = env.Command( |
1326 target_dir + '/' + manifest_base_name, | 1329 target_dir + '/' + manifest_base_name, |
1327 [manifest, lib_list_node], | 1330 [manifest, lib_list_node], |
1328 CopyLibsForExtensionCommand) | 1331 CopyLibsForExtensionCommand) |
1329 return nmf_node | 1332 return nmf_node |
1330 | 1333 |
1331 pre_base_env.AddMethod(CopyLibsForExtension) | 1334 pre_base_env.AddMethod(CopyLibsForExtension) |
1332 | 1335 |
1333 | 1336 |
1334 # Generate manifest from newlib manifest and the list of libs generated by | 1337 # Generate manifest from newlib manifest and the list of libs generated by |
1335 # runnable-ld.so. | 1338 # runnable-ld.so. |
1336 def GenerateManifestFunc(target, source, env): | 1339 def GenerateManifestFunc(target, source, env): |
| 1340 # Open the original manifest and parse it. |
1337 source_file = open(str(source[0]), 'r') | 1341 source_file = open(str(source[0]), 'r') |
1338 obj = json.load(source_file) | 1342 obj = json.load(source_file) |
1339 source_file.close() | 1343 source_file.close() |
| 1344 # Open the file with ldd-format list of NEEDED libs and parse it. |
1340 libs_file = open(str(source[1]), 'r') | 1345 libs_file = open(str(source[1]), 'r') |
1341 lib_names = [] | 1346 lib_names = [] |
1342 arch = env.subst('${TARGET_FULLARCH}') | 1347 arch = env.subst('${TARGET_FULLARCH}') |
1343 for line in libs_file.readlines(): | 1348 for line in libs_file.readlines(): |
1344 lib_info = ParseLibInfoInRunnableLdLog(line) | 1349 lib_info = ParseLibInfoInRunnableLdLog(line) |
1345 if lib_info: | 1350 if lib_info: |
1346 lib_name, _ = lib_info | 1351 lib_name, _ = lib_info |
1347 lib_names.append(lib_name) | 1352 lib_names.append(lib_name) |
1348 libs_file.close() | 1353 libs_file.close() |
| 1354 # Inject the NEEDED libs into the manifest. |
1349 if 'files' not in obj: | 1355 if 'files' not in obj: |
1350 obj['files'] = {} | 1356 obj['files'] = {} |
1351 for lib_name in lib_names: | 1357 for lib_name in lib_names: |
1352 obj['files'][lib_name] = {} | 1358 obj['files'][lib_name] = {} |
1353 obj['files'][lib_name][arch] = {} | 1359 obj['files'][lib_name][arch] = {} |
1354 obj['files'][lib_name][arch]['url'] = lib_name | 1360 obj['files'][lib_name][arch]['url'] = lib_name |
| 1361 # Put what used to be specified under 'program' into 'main.nexe'. |
1355 obj['files']['main.nexe'] = {} | 1362 obj['files']['main.nexe'] = {} |
1356 for k, v in obj['program'].items(): | 1363 for k, v in obj['program'].items(): |
1357 obj['files']['main.nexe'][k] = v.copy() | 1364 obj['files']['main.nexe'][k] = v.copy() |
1358 v['url'] = 'runnable-ld.so' | 1365 v['url'] = 'runnable-ld.so' |
| 1366 # Put runnable-ld.so into the 'program' field, for all known |
| 1367 # NMF architectures (besides 'portable'). |
| 1368 new_program_dict = {} |
| 1369 obj['program'] = new_program_dict |
| 1370 for arch in ['x86-32', 'x86-64', 'arm']: |
| 1371 new_program_dict[arch] = {} |
| 1372 new_program_dict[arch]['url'] = 'runnable-ld.so' |
| 1373 # Write the new manifest! |
1359 target_file = open(str(target[0]), 'w') | 1374 target_file = open(str(target[0]), 'w') |
1360 json.dump(obj, target_file) | 1375 json.dump(obj, target_file) |
1361 target_file.close() | 1376 target_file.close() |
1362 return 0 | 1377 return 0 |
1363 | 1378 |
1364 | 1379 |
1365 # Returns nexe specified in manifest file. | 1380 # Returns a pair (main program, is_portable), based on the program |
1366 def GetNexeFromManifest(env, manifest): | 1381 # specified in manifest file. |
| 1382 def GetMainProgramFromManifest(env, manifest): |
1367 manifest_file = open(str(env.File(manifest)), 'r') | 1383 manifest_file = open(str(env.File(manifest)), 'r') |
1368 obj = json.load(manifest_file) | 1384 obj = json.load(manifest_file) |
1369 manifest_file.close() | 1385 manifest_file.close() |
1370 nexe = obj['program'][env.subst('${TARGET_FULLARCH}')]['url'] | 1386 program_dict = obj['program'] |
1371 return nexe | 1387 if env.Bit('bitcode'): |
| 1388 # For Pnacl we are not yet always using the 'portable' key in the manifest. |
| 1389 # Sometimes we translate to a native nexe for testing. |
| 1390 if 'portable' in program_dict.keys(): |
| 1391 return (program_dict['portable']['url'], True) |
| 1392 # otherwise, fall through to nexe case. |
| 1393 return (program_dict[env.subst('${TARGET_FULLARCH}')]['url'], False) |
1372 | 1394 |
1373 manifest_map = {} | 1395 manifest_map = {} |
1374 | 1396 |
1375 | |
1376 # Returns scons node for generated manifest. | 1397 # Returns scons node for generated manifest. |
1377 def GeneratedManifestNode(env, manifest): | 1398 def GeneratedManifestNode(env, manifest): |
1378 manifest = env.subst(manifest) | 1399 manifest = env.subst(manifest) |
1379 manifest_base_name = os.path.basename(manifest) | 1400 manifest_base_name = os.path.basename(manifest) |
1380 nexe = GetNexeFromManifest(env, manifest) | 1401 main_program, is_portable = GetMainProgramFromManifest(env, manifest) |
1381 result = env.File('${STAGING_DIR}/' + manifest_base_name) | 1402 result = env.File('${STAGING_DIR}/' + manifest_base_name) |
1382 if not env.Bit('nacl_glibc'): | 1403 if not env.Bit('nacl_glibc'): |
1383 if manifest_base_name not in manifest_map: | 1404 if manifest_base_name not in manifest_map: |
1384 env.Install('${STAGING_DIR}', manifest) | 1405 env.Install('${STAGING_DIR}', manifest) |
1385 manifest_map[manifest_base_name] = nexe | 1406 manifest_map[manifest_base_name] = main_program |
1386 # fall through | 1407 # fall through |
1387 if manifest_base_name in manifest_map: | 1408 if manifest_base_name in manifest_map: |
1388 if manifest_map[manifest_base_name] != nexe: | 1409 if manifest_map[manifest_base_name] != main_program: |
1389 print nexe | 1410 print main_program |
1390 print manifest_map[manifest_base_name] | 1411 print manifest_map[manifest_base_name] |
1391 raise Exception("Two manifest files with the same name") | 1412 raise Exception("Two manifest files with the same name") |
1392 return result | 1413 return result |
1393 manifest_map[manifest_base_name] = nexe | 1414 manifest_map[manifest_base_name] = main_program |
1394 lib_list_node = env.Command( | 1415 if is_portable: |
1395 '${STAGING_DIR}/' + manifest_base_name + '.libs', | 1416 nmf_node = env.Command( |
1396 [GetSelLdr(env), | 1417 result, |
1397 '${NACL_SDK_LIB}/runnable-ld.so', | 1418 ['${GENNMF}', |
1398 env.File('${STAGING_DIR}/' + os.path.basename(nexe)), | 1419 env.File('${STAGING_DIR}/' + os.path.basename(main_program))], |
1399 '${SCONSTRUCT_DIR}/DEPS'], | 1420 # Generate a flat url scheme to simplify file-staging. |
1400 # We ignore return code using '-' in order to build tests where binaries | 1421 '${SOURCES[0]} -L${NACL_SDK_LIB} -L${LIB_DIR} ' + |
1401 # do not validate. This is the scons feature. | 1422 ' --flat-url-scheme ${SOURCES[1]} -o ${TARGET}') |
1402 '-${SOURCES[0]} -a -E LD_TRACE_LOADED_OBJECTS=1 ${SOURCES[1]} ' | 1423 else: |
1403 '--library-path ${NACL_SDK_LIB}:${LIB_DIR} ${SOURCES[2].posix} ' | 1424 # Run sel_ldr on the nexe to trace the NEEDED libraries. |
1404 '> ${TARGET}') | 1425 lib_list_node = env.Command( |
1405 nmf_node = env.Command( | 1426 '${STAGING_DIR}/' + manifest_base_name + '.libs', |
1406 '${STAGING_DIR}/' + manifest_base_name, | 1427 [GetSelLdr(env), |
1407 [manifest, lib_list_node], | 1428 '${NACL_SDK_LIB}/runnable-ld.so', |
1408 GenerateManifestFunc) | 1429 env.File('${STAGING_DIR}/' + os.path.basename(main_program)), |
| 1430 '${SCONSTRUCT_DIR}/DEPS'], |
| 1431 # We ignore return code using '-' in order to build tests where binaries |
| 1432 # do not validate. This is the scons feature. |
| 1433 '-${SOURCES[0]} -a -E LD_TRACE_LOADED_OBJECTS=1 ${SOURCES[1]} ' |
| 1434 '--library-path ${NACL_SDK_LIB}:${LIB_DIR} ${SOURCES[2].posix} ' |
| 1435 '> ${TARGET}') |
| 1436 nmf_node = env.Command( |
| 1437 '${STAGING_DIR}/' + manifest_base_name, |
| 1438 [manifest, lib_list_node], |
| 1439 GenerateManifestFunc) |
1409 return result | 1440 return result |
1410 | 1441 |
1411 | 1442 |
1412 def GetPnaclExtensionNode(env): | 1443 def GetPnaclExtensionNode(env): |
1413 """Get the scons node representing the pnacl support files. | 1444 """Get the scons node representing the pnacl support files. |
1414 """ | 1445 """ |
1415 # This is "built" by src/untrusted/pnacl_support_extension/nacl.scons. | 1446 # This is "built" by src/untrusted/pnacl_support_extension/nacl.scons. |
1416 return env.Dir('${STAGING_DIR}/pnacl_all') | 1447 return env.Dir('${STAGING_DIR}/pnacl_all') |
1417 | 1448 |
1418 pre_base_env.AddMethod(GetPnaclExtensionNode) | 1449 pre_base_env.AddMethod(GetPnaclExtensionNode) |
(...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3708 nacl_env.ValidateSdk() | 3739 nacl_env.ValidateSdk() |
3709 | 3740 |
3710 if BROKEN_TEST_COUNT > 0: | 3741 if BROKEN_TEST_COUNT > 0: |
3711 msg = "There are %d broken tests." % BROKEN_TEST_COUNT | 3742 msg = "There are %d broken tests." % BROKEN_TEST_COUNT |
3712 if GetOption('brief_comstr'): | 3743 if GetOption('brief_comstr'): |
3713 msg += " Add --verbose to the command line for more information." | 3744 msg += " Add --verbose to the command line for more information." |
3714 print msg | 3745 print msg |
3715 | 3746 |
3716 # separate warnings from actual build output | 3747 # separate warnings from actual build output |
3717 Banner('B U I L D - O U T P U T:') | 3748 Banner('B U I L D - O U T P U T:') |
OLD | NEW |