summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorsbc@chromium.org <sbc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-24 16:44:12 +0000
committersbc@chromium.org <sbc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-24 16:44:12 +0000
commita07e2edee0dc76fd16cbe85f89fc2b5441afc47b (patch)
tree307655441be46a0cc0b865803799ca1f399276c1 /native_client_sdk
parent5c65fe817c7420d459b5b817bc1cf05210771e39 (diff)
downloadchromium_src-a07e2edee0dc76fd16cbe85f89fc2b5441afc47b.zip
chromium_src-a07e2edee0dc76fd16cbe85f89fc2b5441afc47b.tar.gz
chromium_src-a07e2edee0dc76fd16cbe85f89fc2b5441afc47b.tar.bz2
[NaCl SDK] Add sensible defaults to create_nmf.py
create_nmf will now derive a default library path and objdump location based on its location, or on NACL_SDK_ROOT. This significantly reduces the number of arguments that one needs to pass. BUG=179526 R=binji@chromium.org Review URL: https://codereview.chromium.org/15255006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202110 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rwxr-xr-xnative_client_sdk/src/tools/create_nmf.py82
-rw-r--r--native_client_sdk/src/tools/nacl_gcc.mk10
-rwxr-xr-xnative_client_sdk/src/tools/tests/create_nmf_test.py33
3 files changed, 114 insertions, 11 deletions
diff --git a/native_client_sdk/src/tools/create_nmf.py b/native_client_sdk/src/tools/create_nmf.py
index 93f8004..5c9d270 100755
--- a/native_client_sdk/src/tools/create_nmf.py
+++ b/native_client_sdk/src/tools/create_nmf.py
@@ -14,6 +14,7 @@ import struct
import subprocess
import sys
+import getos
import quote
if sys.version_info < (2, 6, 0):
@@ -23,6 +24,8 @@ if sys.version_info < (2, 6, 0):
NeededMatcher = re.compile('^ *NEEDED *([^ ]+)\n$')
FormatMatcher = re.compile('^(.+):\\s*file format (.+)\n$')
+SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
+
OBJDUMP_ARCH_MAP = {
# Names returned by Linux's objdump:
'elf64-x86-64': 'x86-64',
@@ -251,7 +254,9 @@ class NmfUtils(object):
set(['x86-32/libc.so', 'x86-64/libgcc.so'])
'''
if not self.objdump:
- raise Error('No objdump executable specified (see --help for more info)')
+ self.objdump = FindObjdumpExecutable()
+ if not self.objdump:
+ raise Error('No objdump executable found (see --help for more info)')
DebugPrint('GleanFromObjdump(%s)' % ([self.objdump, '-p'] + files.keys()))
proc = subprocess.Popen([self.objdump, '-p'] + files.keys(),
stdout=subprocess.PIPE,
@@ -519,6 +524,68 @@ def ParseExtraFiles(encoded_list, err):
return canonicalized
+def GetSDKRoot():
+ """Determine current NACL_SDK_ROOT, either via the environment variable
+ itself, or by attempting to derive it from the location of this script.
+ """
+ sdk_root = os.environ.get('NACL_SDK_ROOT')
+ if not sdk_root:
+ sdk_root = os.path.dirname(SCRIPT_DIR)
+ if not os.path.exists(os.path.join(sdk_root, 'toolchain')):
+ return None
+
+ return sdk_root
+
+
+def FindObjdumpExecutable():
+ """Derive path to objdump executable to use for determining shared
+ object dependencies.
+ """
+ sdk_root = GetSDKRoot()
+ if not sdk_root:
+ return None
+
+ osname = getos.GetPlatform()
+ toolchain = os.path.join(sdk_root, 'toolchain', '%s_x86_glibc' % osname)
+ objdump = os.path.join(toolchain, 'bin', 'x86_64-nacl-objdump')
+ if osname == 'win':
+ objdump += '.exe'
+
+ if not os.path.exists(objdump):
+ sys.stderr.write('WARNING: failed to find objdump in default '
+ 'location: %s' % objdump)
+ return None
+
+ return objdump
+
+
+def GetDefaultLibPath(config):
+ """Derive default library path to use when searching for shared
+ objects. This currently include the toolchain library folders
+ as well as the top level SDK lib folder and the naclports lib
+ folder. We include both 32-bit and 64-bit library paths.
+ """
+ assert(config in ('Debug', 'Release'))
+ sdk_root = GetSDKRoot()
+ if not sdk_root:
+ # TOOD(sbc): output a warning here? We would also need to suppress
+ # the warning when run from the chromium build.
+ return []
+
+ osname = getos.GetPlatform()
+ libpath = [
+ 'toolchain/%s_x86_glibc/x86_64-nacl/lib' % osname,
+ 'toolchain/%s_x86_glibc/x86_64-nacl/lib32' % osname,
+ 'lib/glibc_x86_32/%s' % config,
+ 'lib/glibc_x86_64/%s' % config,
+ 'ports/lib/glibc_x86_32/%s' % config,
+ 'ports/lib/glibc_x86_64/%s' % config,
+ ]
+ libpath = [os.path.normpath(p) for p in libpath]
+ libpath = [os.path.join(sdk_root, p) for p in libpath]
+ return libpath
+
+
def main(argv):
parser = optparse.OptionParser(
usage='Usage: %prog [options] nexe [extra_libs...]')
@@ -526,8 +593,14 @@ def main(argv):
help='Write manifest file to FILE (default is stdout)',
metavar='FILE')
parser.add_option('-D', '--objdump', dest='objdump',
- help='Use TOOL as the "objdump" tool to run',
+ help='Override the default "objdump" tool used to find '
+ 'shared object dependencies',
metavar='TOOL')
+ parser.add_option('--no-default-libpath',
+ help="Don't include the SDK default library paths")
+ parser.add_option('--debug-libs', action='store_true',
+ help='Use debug library paths when constructing default '
+ 'library path.')
parser.add_option('-L', '--library-path', dest='lib_path',
action='append', default=[],
help='Add DIRECTORY to library search path',
@@ -578,6 +651,11 @@ def main(argv):
else:
path_prefix = []
+ if not options.no_default_libpath:
+ # Add default libraries paths to the end of the search path.
+ config = options.debug_libs and 'Debug' or 'Release'
+ options.lib_path += GetDefaultLibPath(config)
+
nmf = NmfUtils(objdump=options.objdump,
main_files=args,
lib_path=options.lib_path,
diff --git a/native_client_sdk/src/tools/nacl_gcc.mk b/native_client_sdk/src/tools/nacl_gcc.mk
index a6f665f..1460637 100644
--- a/native_client_sdk/src/tools/nacl_gcc.mk
+++ b/native_client_sdk/src/tools/nacl_gcc.mk
@@ -352,15 +352,13 @@ NMF_ARCHES := $(foreach arch,$(ARCHES),_$(arch).nexe)
# $2 = Additional create_nmf.py arguments
#
NMF := python $(NACL_SDK_ROOT)/tools/create_nmf.py
-GLIBC_DUMP := $(TC_PATH)/$(OSNAME)_x86_glibc/x86_64-nacl/bin/objdump
-GLIBC_PATHS := -L $(TC_PATH)/$(OSNAME)_x86_glibc/x86_64-nacl/lib32
-GLIBC_PATHS += -L $(TC_PATH)/$(OSNAME)_x86_glibc/x86_64-nacl/lib
-GLIBC_PATHS += -L$(NACL_SDK_ROOT)/lib/$(TOOLCHAIN)_x86_64/$(CONFIG)
-GLIBC_PATHS += -L$(NACL_SDK_ROOT)/lib/$(TOOLCHAIN)_x86_32/$(CONFIG)
+ifeq ($(CONFIG),Debug)
+NMF_FLAGS += --debug-libs
+endif
define NMF_RULE
all:$(OUTDIR)/$(1).nmf
$(OUTDIR)/$(1).nmf : $(foreach arch,$(NMF_ARCHES),$(OUTDIR)/$(1)$(arch)) $(GLIBC_SO_LIST)
- $(call LOG,CREATE_NMF,$$@,$(NMF) -o $$@ $$^ -D $(GLIBC_DUMP) $(GLIBC_PATHS) -s $(OUTDIR) $(2) $(GLIBC_REMAP))
+ $(call LOG,CREATE_NMF,$$@,$(NMF) $(NMF_FLAGS) -o $$@ $$^ $(GLIBC_PATHS) -s $(OUTDIR) $(2) $(GLIBC_REMAP))
endef
diff --git a/native_client_sdk/src/tools/tests/create_nmf_test.py b/native_client_sdk/src/tools/tests/create_nmf_test.py
index e8fec58..fe08f6b 100755
--- a/native_client_sdk/src/tools/tests/create_nmf_test.py
+++ b/native_client_sdk/src/tools/tests/create_nmf_test.py
@@ -12,11 +12,16 @@ import unittest
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PARENT_DIR = os.path.dirname(SCRIPT_DIR)
DATA_DIR = os.path.join(SCRIPT_DIR, 'data')
+CHROME_SRC = os.path.dirname(os.path.dirname(os.path.dirname(PARENT_DIR)))
+MOCK_DIR = os.path.join(CHROME_SRC, "third_party", "pymock")
+# For the mock library
+sys.path.append(MOCK_DIR)
sys.path.append(PARENT_DIR)
-import getos
import create_nmf
+import getos
+import mock
class TestIsDynamicElf(unittest.TestCase):
@@ -75,13 +80,35 @@ class TestParseElfHeader(unittest.TestCase):
self.assertFalse(dynamic)
+class TestDefaultLibpath(unittest.TestCase):
+ def testWithoutNaClSDKRoot(self):
+ """GetDefaultLibPath wihtout NACL_SDK_ROOT set
+
+ In the absence of NACL_SDK_ROOT GetDefaultLibPath should
+ return the empty list."""
+ with mock.patch.dict('os.environ', clear=True):
+ paths = create_nmf.GetDefaultLibPath('Debug')
+ self.assertEqual(paths, [])
+
+ def testHonorNaClSDKRoot(self):
+ with mock.patch.dict('os.environ', {'NACL_SDK_ROOT': '/dummy/path'}):
+ paths = create_nmf.GetDefaultLibPath('Debug')
+ for path in paths:
+ self.assertTrue(path.startswith('/dummy/path'))
+
+ def testIncludesNaClPorts(self):
+ with mock.patch.dict('os.environ', {'NACL_SDK_ROOT': '/dummy/path'}):
+ paths = create_nmf.GetDefaultLibPath('Debug')
+ self.assertTrue(any(os.path.join('ports', 'lib') in p for p in paths),
+ "naclports libpath missing: %s" % str(paths))
+
+
class TestNmfUtils(unittest.TestCase):
"""Tests for the main NmfUtils class in create_nmf."""
def setUp(self):
self.tempdir = None
- chrome_src = os.path.dirname(os.path.dirname(os.path.dirname(PARENT_DIR)))
- toolchain = os.path.join(chrome_src, 'native_client', 'toolchain')
+ toolchain = os.path.join(CHROME_SRC, 'native_client', 'toolchain')
self.toolchain = os.path.join(toolchain, '%s_x86' % getos.GetPlatform())
self.objdump = os.path.join(self.toolchain, 'bin', 'i686-nacl-objdump')
if os.name == 'nt':