2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
13 SCRIPT_DIR
= os
.path
.dirname(os
.path
.abspath(__file__
))
14 LIB_DIR
= os
.path
.dirname(SCRIPT_DIR
)
15 TOOLS_DIR
= os
.path
.dirname(LIB_DIR
)
16 SDK_DIR
= os
.path
.dirname(TOOLS_DIR
)
17 DATA_DIR
= os
.path
.join(SCRIPT_DIR
, 'data')
18 BUILD_TOOLS_DIR
= os
.path
.join(SDK_DIR
, 'build_tools')
20 sys
.path
.append(LIB_DIR
)
21 sys
.path
.append(TOOLS_DIR
)
22 sys
.path
.append(BUILD_TOOLS_DIR
)
25 import get_shared_deps
28 TOOLCHAIN_OUT
= os
.path
.join(build_paths
.OUT_DIR
, 'sdk_tests', 'toolchain')
29 NACL_X86_GLIBC_TOOLCHAIN
= os
.path
.join(TOOLCHAIN_OUT
,
30 '%s_x86' % getos
.GetPlatform(),
34 def StripDependencies(deps
):
35 '''Strip the dirnames and version suffixes from
36 a list of nexe dependencies.
39 /path/to/libpthread.so.1a2d3fsa -> libpthread.so
43 name
= os
.path
.basename(name
)
45 name
= name
.rsplit('.', 1)[0]
50 class TestGetNeeded(unittest
.TestCase
):
53 self
.toolchain
= NACL_X86_GLIBC_TOOLCHAIN
54 self
.objdump
= os
.path
.join(self
.toolchain
, 'bin', 'i686-nacl-objdump')
56 self
.objdump
+= '.exe'
58 self
.dyn_nexe
= self
.createTestNexe('test_dynamic_x86_32.nexe', 'i686')
59 self
.dyn_deps
= set(['libc.so', 'runnable-ld.so',
60 'libgcc_s.so', 'libpthread.so'])
64 shutil
.rmtree(self
.tempdir
)
67 self
.tempdir
= tempfile
.mkdtemp()
69 def createTestNexe(self
, name
, arch
):
70 '''Create an empty test .nexe file for use in create_nmf tests.
72 This is used rather than checking in test binaries since the
73 checked in binaries depend on .so files that only exist in the
74 certain SDK that built them.
76 compiler
= os
.path
.join(self
.toolchain
, 'bin', '%s-nacl-g++' % arch
)
79 os
.environ
['CYGWIN'] = 'nodosfilewarning'
80 program
= 'int main() { return 0; }'
81 name
= os
.path
.join(self
.tempdir
, name
)
82 cmd
= [compiler
, '-pthread', '-x' , 'c', '-o', name
, '-']
83 p
= subprocess
.Popen(cmd
, stdin
=subprocess
.PIPE
)
84 p
.communicate(input=program
)
85 self
.assertEqual(p
.returncode
, 0)
89 nexe
= os
.path
.join(DATA_DIR
, 'test_static_x86_32.nexe')
90 # GetNeeded should not raise an error if objdump is not set, but the .nexe
91 # is statically linked.
94 needed
= get_shared_deps
.GetNeeded([nexe
], objdump
, lib_path
)
96 # static nexe should have exactly one needed file
97 self
.assertEqual(len(needed
), 1)
98 self
.assertEqual(needed
.keys()[0], nexe
)
100 # arch of needed file should be x86-32
101 arch
= needed
.values()[0]
102 self
.assertEqual(arch
, 'x86-32')
104 def testDynamic(self
):
105 libdir
= os
.path
.join(self
.toolchain
, 'x86_64-nacl', 'lib32')
106 needed
= get_shared_deps
.GetNeeded([self
.dyn_nexe
],
108 objdump
=self
.objdump
)
109 names
= needed
.keys()
111 # this nexe has 5 dependencies
112 expected
= set(self
.dyn_deps
)
113 expected
.add(os
.path
.basename(self
.dyn_nexe
))
115 basenames
= set(StripDependencies(names
))
116 self
.assertEqual(expected
, basenames
)
118 def testMissingArchLibrary(self
):
119 libdir
= os
.path
.join(self
.toolchain
, 'x86_64-nacl', 'lib32')
121 nexes
= ['libgcc_s.so.1']
122 # CreateNmfUtils uses the 32-bit library path, but not the 64-bit one
123 # so searching for a 32-bit library should succeed while searching for
124 # a 64-bit one should fail.
125 get_shared_deps
.GleanFromObjdump(nexes
, 'x86-32', self
.objdump
, lib_path
)
126 self
.assertRaises(get_shared_deps
.Error
,
127 get_shared_deps
.GleanFromObjdump
,
128 nexes
, 'x86-64', self
.objdump
, lib_path
)
130 def testCorrectArch(self
):
131 lib_path
= [os
.path
.join(self
.toolchain
, 'x86_64-nacl', 'lib32'),
132 os
.path
.join(self
.toolchain
, 'x86_64-nacl', 'lib')]
134 needed
= get_shared_deps
.GetNeeded([self
.dyn_nexe
],
136 objdump
=self
.objdump
)
137 for arch
in needed
.itervalues():
138 self
.assertEqual(arch
, 'x86-32')
141 if __name__
== '__main__':