Index: SConstruct |
=================================================================== |
--- SConstruct (revision 6583) |
+++ SConstruct (working copy) |
@@ -7,11 +7,14 @@ |
import glob |
import os |
import platform |
+import shutil |
import stat |
import subprocess |
import sys |
import zlib |
sys.path.append("./common") |
+sys.path.append('../third_party') |
+import simplejson |
from SCons.Errors import UserError |
from SCons.Script import GetBuildFailures |
@@ -1163,10 +1166,139 @@ |
pre_base_env.AddMethod(GetPPAPIPluginPath) |
+ |
+# runnable-ld.so log has following format: |
+# lib_name => path_to_lib (0x....address) |
+def ParseLibInfoInRunnableLdLog(line): |
+ pos = line.find(' => ') |
+ if pos < 0: |
+ return None |
+ lib_name = line[:pos].strip() |
+ lib_path = line[pos+4:] |
+ pos1 = lib_path.rfind(' (') |
+ if pos1 < 0: |
+ return None |
+ lib_path = lib_path[:pos1] |
+ return lib_name, lib_path |
+ |
+ |
+# Copy libs and manifest to the target directory. |
+# source[0] is a manifest file |
+# source[1] is a .libs file with a list of libs generated by runnable-ld.so |
+def CopyLibsForExtensionCommand(target, source, env): |
+ source_manifest = str(source[0]) |
+ target_manifest = str(target[0]) |
+ shutil.copyfile(source_manifest, target_manifest) |
+ target_dir = os.path.dirname(target_manifest) |
+ libs_file = open(str(source[1]), 'r') |
+ for line in libs_file.readlines(): |
+ lib_info = ParseLibInfoInRunnableLdLog(line) |
+ if lib_info: |
+ lib_name, lib_path = lib_info |
+ 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')) |
+ libs_file.close() |
+ |
+ |
+# Extensions are loaded from directory on disk and so all dynamic libraries |
+# they use must be copied to extension directory. The option --extra_serving_dir |
+# does not help us in this case. |
+def CopyLibsForExtension(env, target_dir, manifest): |
+ if not env.Bit('nacl_glibc'): |
+ return env.Install(target_dir, manifest) |
+ manifest_base_name = os.path.basename(str(env.subst(manifest))) |
+ lib_list_node = env.File('${STAGING_DIR}/' + manifest_base_name + '.libs') |
+ nmf_node = env.Command( |
+ target_dir + '/' + manifest_base_name, |
+ [manifest, lib_list_node], |
+ CopyLibsForExtensionCommand) |
+ return nmf_node |
+ |
+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): |
+ source_file = open(str(source[0]), 'r') |
+ obj = simplejson.load(source_file) |
+ source_file.close() |
+ libs_file = open(str(source[1]), 'r') |
+ lib_names = [] |
+ for line in libs_file.readlines(): |
+ lib_info = ParseLibInfoInRunnableLdLog(line) |
+ if lib_info: |
+ lib_name, _ = lib_info |
+ lib_names.append(lib_name) |
+ libs_file.close() |
+ if 'files' not in obj: |
+ obj['files'] = {} |
+ for lib_name in lib_names: |
+ obj['files']['lib/' + lib_name] = {} |
+ obj['files']['lib/' + lib_name]['portable'] = {} |
+ obj['files']['lib/' + lib_name]['portable']['url'] = lib_name |
+ obj['files']['main.nexe'] = {} |
+ for k, v in obj['program'].items(): |
+ obj['files']['main.nexe'][k] = v.copy() |
+ v['url'] = 'runnable-ld.so' |
+ target_file = open(str(target[0]), 'w') |
+ simplejson.dump(obj, target_file) |
+ target_file.close() |
+ return 0 |
+ |
+ |
+# Returns nexe specified in manifest file. |
+def GetNexeFromManifest(env, manifest): |
+ manifest_file = open(str(env.File(manifest)), 'r') |
+ obj = simplejson.load(manifest_file) |
+ manifest_file.close() |
+ nexe = obj['program'][env.subst('${TARGET_FULLARCH}')]['url'] |
+ return nexe |
+ |
+manifest_map = {} |
+ |
+ |
+# Returns command line arguments for browser tester that add generated manifest |
+# to a list of files to serve. |
+def GenerateManifestCommands(env, manifest): |
+ manifest = env.subst(manifest) |
+ manifest_base_name = os.path.basename(manifest) |
+ nexe = GetNexeFromManifest(env, manifest) |
+ result = ['--file', 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 |
+ # fall through |
+ if manifest_base_name in manifest_map: |
+ if manifest_map[manifest_base_name] != nexe: |
+ print nexe |
+ 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'], |
+ '${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 |
+ |
+ |
def PPAPIBrowserTester(env, |
target, |
url, |
files, |
+ nmfs=None, |
map_files=(), |
extensions=(), |
timeout=20, |
@@ -1218,6 +1350,11 @@ |
command.extend(['--extension', extension]) |
for dest_path, dep_file in map_files: |
command.extend(['--map_file', dest_path, dep_file]) |
+ command.extend(['--serving_dir', '${NACL_SDK_LIB}']) |
+ command.extend(['--serving_dir', '${LIB_DIR}']) |
+ if not nmfs is None: |
+ for nmf_file in nmfs: |
+ command.extend(GenerateManifestCommands(env, nmf_file)) |
if 'browser_test_tool' in ARGUMENTS: |
command.extend(['--tool', ARGUMENTS['browser_test_tool']]) |
command.extend(args) |
@@ -1248,11 +1385,9 @@ |
pre_base_env.AddMethod(PPAPIBrowserTesterIsBroken) |
-# 3D disabled for arm, newlib & pnacl |
+# 3D is disabled everywhere |
def PPAPIGraphics3DIsBroken(env): |
- return (env.Bit('target_arm') or |
- not env.Bit('nacl_glibc') or |
- env.Bit('bitcode')) |
+ return True |
pre_base_env.AddMethod(PPAPIGraphics3DIsBroken) |
@@ -1364,6 +1499,7 @@ |
# rather than the architecture of Python currently running. |
def PyAutoTesterIsBroken(env): |
return (PPAPIBrowserTesterIsBroken(env) |
+ or env.Bit('nacl_glibc') |
or (not env.Bit('host_mac') |
and env.Bit('build_x86_32') |
and platform.architecture()[0] == '64bit')) |