def replace(clazz, archive, objects, tools = None): 'Replace an archive into dest_dir.' tools = tools or clazz.DEFAULT_TOOLS if host.is_macos(): clazz._replace_darwin(archive, objects, tools) else: clazz._replace_with_ar(archive, objects, tools)
def _find_tar_exe_tar(): 'Find the tar executable explicitly in the system default place in case the user aliased it somehow' if host.is_linux(): return '/bin/tar' elif host.is_macos(): return '/usr/bin/tar' else: raise RuntimeError('Unknown host system')
class test_native_package_manager(unit_test): @skip_if(not host.is_macos(), 'not macos') def test_is_installed_macos(self): self.assertFalse(native_package_manager.is_installed('bash')) self.assertTrue( native_package_manager.is_installed('com.apple.pkg.Core')) @skip_if(not host.is_linux(), 'not linux') def test_is_installed_linux(self): self.assertTrue(native_package_manager.is_installed('bash')) self.assertFalse( native_package_manager.is_installed('com.apple.pkg.Core')) @skip_if(not host.is_linux(), 'not linux') def test_owner(self): self.assertEqual('coreutils', native_package_manager.owner('/bin/ls')) self.assertEqual('bash', native_package_manager.owner('/bin/bash')) def test_installed_packages(self): self.assertTrue(len(native_package_manager.installed_packages()) > 0)
def can_compile_macos(clazz): return host.is_macos()
def can_compile_android(clazz): return (host.is_macos() or host.is_linux()) and clazz.android_toolchain_is_valid()
def _make_shared_lib(target, objects): if host.is_macos(): _make_macos_lib(target, objects, True) else: _make_linux_shared_lib(target, objects)
def _make_static_lib(target, objects): if host.is_macos(): _make_macos_lib(target, objects, False) else: _make_linux_static_lib(target, objects)
#!/usr/bin/env python from bes.system import host from bes.common import string_util from bes.fs import file_util import os.path as path DEBUG = False #DEBUG = True if host.is_macos(): COMPILER = 'clang++' CFLAGS = ['--std=c++11'] else: COMPILER = 'g++' CFLAGS = [] ALL_LIBRARY_ARCHS = ['i386', 'x86_64', 'armv7', 'arm64'] FAT_ARCHS = ALL_LIBRARY_ARCHS THIN_ARCHS = ['x86_64'] EXE_ARCHS = ['i386', 'x86_64'] ARCHS_64 = ['x86_64', 'arm64'] ARCHS_32 = ['i386', 'armv7'] FRUIT_SOURCES = ['cherry.cpp', 'kiwi.cpp'] EXE_SOURCES = FRUIT_SOURCES + ['main.cpp'] def main(): _make_lib(COMPILER, 'fruits.a', FRUIT_SOURCES, 'fat_all', FAT_ARCHS, False)
class test_jail_cli(unit_test): __unit_test_data_dir__ = '${BES_TEST_DATA_DIR}/jail_cli' DEBUG = False #DEBUG = True __BES_JAIL_PY = path.normpath( path.join(path.dirname(__file__), '../../../../bin/rebuild_jail.py')) #com.apple.pkg.JavaTools #com.apple.pkg.MobileDevice #com.apple.pkg.MobileDeviceDevelopment __PACKAGE_ID = 'com.apple.pkg.MobileDevice' @skip_if(not host.is_macos(), 'not macos') @skip_if(not npm.is_installed(__PACKAGE_ID), 'not installed: %s' % (__PACKAGE_ID)) def test_create_from_packages(self): tmp_dir = temp_file.make_temp_dir(delete=not self.DEBUG) jail_config_content = ''' [jail] description: test packages: %s [%s] ''' % (self.__PACKAGE_ID, self.__PACKAGE_ID) tmp_jail_config = temp_file.make_temp_file(content=jail_config_content) cmd = [ self.__BES_JAIL_PY, 'create', tmp_dir, tmp_jail_config, ] rv = os_env.call_python_script(cmd) print(rv.stdout) self.assertEqual(0, rv.exit_code) expected_files = npm.package_contents(self.__PACKAGE_ID) actual_files = file_find.find(tmp_dir, file_type=file_find.ANY, relative=True) actual_files = [path.join('/', f) for f in actual_files] self.assertEqual(expected_files, actual_files) @skip_if(not host.is_macos(), 'not macos') def test_create_from_binaries(self): self.maxDiff = None tmp_dir = temp_file.make_temp_dir(delete=not self.DEBUG) jail_config_content = ''' [jail] description: test binaries: /bin/bash /bin/echo /bin/ls /bin/sh /usr/lib/dyl* ''' tmp_jail_config = temp_file.make_temp_file(content=jail_config_content) cmd = [ self.__BES_JAIL_PY, 'create', tmp_dir, tmp_jail_config, ] rv = os_env.call_python_script(cmd) print(rv.stdout) self.assertEqual(0, rv.exit_code) expected_files = sorted([ '/bin', '/bin/bash', '/bin/echo', '/bin/ls', '/bin/sh', '/usr', '/usr/lib', '/usr/lib/dyld', '/usr/lib/dylib1.10.5.o', '/usr/lib/dylib1.o', '/usr/lib/libDiagnosticMessagesClient.dylib', '/usr/lib/libSystem.B.dylib', '/usr/lib/libauto.dylib', '/usr/lib/libc++.1.dylib', '/usr/lib/libc++abi.dylib', '/usr/lib/libncurses.5.4.dylib', '/usr/lib/libobjc.A.dylib', '/usr/lib/libutil.dylib', '/usr/lib/system', '/usr/lib/system/libcache.dylib', '/usr/lib/system/libcommonCrypto.dylib', '/usr/lib/system/libcompiler_rt.dylib', '/usr/lib/system/libcopyfile.dylib', '/usr/lib/system/libcorecrypto.dylib', '/usr/lib/system/libdispatch.dylib', '/usr/lib/system/libdyld.dylib', '/usr/lib/system/libkeymgr.dylib', '/usr/lib/system/liblaunch.dylib', '/usr/lib/system/libmacho.dylib', '/usr/lib/system/libquarantine.dylib', '/usr/lib/system/libremovefile.dylib', '/usr/lib/system/libsystem_asl.dylib', '/usr/lib/system/libsystem_blocks.dylib', '/usr/lib/system/libsystem_c.dylib', '/usr/lib/system/libsystem_configuration.dylib', '/usr/lib/system/libsystem_coreservices.dylib', '/usr/lib/system/libsystem_coretls.dylib', '/usr/lib/system/libsystem_dnssd.dylib', '/usr/lib/system/libsystem_info.dylib', '/usr/lib/system/libsystem_kernel.dylib', '/usr/lib/system/libsystem_m.dylib', '/usr/lib/system/libsystem_malloc.dylib', '/usr/lib/system/libsystem_network.dylib', '/usr/lib/system/libsystem_networkextension.dylib', '/usr/lib/system/libsystem_notify.dylib', '/usr/lib/system/libsystem_platform.dylib', '/usr/lib/system/libsystem_pthread.dylib', '/usr/lib/system/libsystem_sandbox.dylib', '/usr/lib/system/libsystem_secinit.dylib', '/usr/lib/system/libsystem_stats.dylib', '/usr/lib/system/libsystem_trace.dylib', '/usr/lib/system/libunc.dylib', '/usr/lib/system/libunwind.dylib', '/usr/lib/system/libxpc.dylib', ]) actual_files = file_find.find(tmp_dir, file_type=file_find.ANY, relative=True) actual_files = [path.join('/', f) for f in actual_files] self.assertEqual(expected_files, actual_files)
class test_ar_replacement(unit_test): __unit_test_data_dir__ = '${BES_TEST_DATA_DIR}/binary_objects' IGNORED_CONTENTS = [] if host.is_macos(): IGNORED_CONTENTS = set(['__.SYMDEF']) def test_contents_thin(self): expected_contents = [ 'thin_cherry.o', 'thin_kiwi.o', ] actual_contents = ar_replacement.contents( self._test_file('thin_fruits_x86_64.a')) actual_contents = self._filter_contents(actual_contents) self.assertEqual(expected_contents, actual_contents) def test_contents_fat(self): expected_contents = [ 'fat_64_cherry.o', 'fat_64_kiwi.o', ] actual_contents = ar_replacement.contents( self._test_file('fat_64_fruits.a')) actual_contents = self._filter_contents(actual_contents) self.assertEqual(expected_contents, actual_contents) def test_extract_thin(self): expected_files = [ 'thin_cherry.o', 'thin_kiwi.o', ] tmp_dir = temp_file.make_temp_dir() ar_replacement.extract(self._test_file('thin_fruits_x86_64.a'), tmp_dir) actual_files = dir_util.list(tmp_dir, relative=True) actual_files = self._filter_contents(actual_files) self.assertEqual(expected_files, actual_files) @skip_if(not host.is_macos(), 'Not osx') def test_extract_fat(self): expected_files = [ 'arm64_fat_cherry.o', 'arm64_fat_kiwi.o', 'armv7_fat_cherry.o', 'armv7_fat_kiwi.o', 'i386_fat_cherry.o', 'i386_fat_kiwi.o', 'x86_64_fat_cherry.o', 'x86_64_fat_kiwi.o', ] tmp_dir = temp_file.make_temp_dir() ar_replacement.extract(self._test_file('fat_fruits.a'), tmp_dir) actual_files = dir_util.list(tmp_dir, relative=True) actual_files = self._filter_contents(actual_files) self.assertEqual(expected_files, actual_files) def test_replace_thin(self): expected_objects = [ 'thin_cherry.o', 'thin_kiwi.o', ] tmp_dir = temp_file.make_temp_dir() tmp_archive = path.join(tmp_dir, 'thin_fruits.a') objects = [self._test_file(o) for o in expected_objects] ar_replacement.replace(tmp_archive, objects) actual_objects = ar_replacement.contents(tmp_archive) actual_objects = self._filter_contents(actual_objects) self.assertEqual(expected_objects, actual_objects) def test_replace_fat(self): expected_objects = [ 'fat_cherry.o', 'fat_kiwi.o', ] tmp_dir = temp_file.make_temp_dir() tmp_archive = path.join(tmp_dir, 'fat_fruits.a') objects = [self._test_file(o) for o in expected_objects] ar_replacement.replace(tmp_archive, objects) actual_objects = ar_replacement.contents(tmp_archive) actual_objects = self._filter_contents(actual_objects) self.assertEqual(expected_objects, actual_objects) def test_replace_add_thin(self): expected_objects = [ 'thin_cherry.o', 'thin_kiwi.o', ] tmp_dir = temp_file.make_temp_dir() tmp_archive = path.join(tmp_dir, 'thin_fruits.a') objects = [self._test_file(o) for o in expected_objects] ar_replacement.replace(tmp_archive, objects) actual_objects = ar_replacement.contents(tmp_archive) actual_objects = self._filter_contents(actual_objects) self.assertEqual(expected_objects, actual_objects) expected_objects = [ 'thin_cherry.o', 'thin_kiwi.o', 'thin_x86_64_avocado.o', ] objects = [self._test_file(o) for o in ['thin_x86_64_avocado.o']] ar_replacement.replace(tmp_archive, objects) actual_objects = ar_replacement.contents(tmp_archive) actual_objects = self._filter_contents(actual_objects) self.assertEqual(expected_objects, actual_objects) def _test_file(self, filename): return self.platform_data_path(filename) @classmethod def _filter_contents(clazz, contents): def _include(c): for ignored in clazz.IGNORED_CONTENTS: if c.find(ignored) >= 0: return False return True return [c for c in contents if _include(c)]
def _archive_is_fat(clazz, archive): 'Return True if the archive is fat (and running on darwin)' return host.is_macos() and lipo.archive_is_fat(archive)
class test_library(unit_test): __unit_test_data_dir__ = '${BES_TEST_DATA_DIR}/binary_objects' def test_is_library(self): self.assertFalse( self.__is_library('cherry.o') ) self.assertFalse( self.__is_library('empty.txt') ) self.assertFalse( self.__is_library('fat_32_cherry.o') ) self.assertTrue( self.__is_library('fat_32_fruits.a') ) self.assertTrue( self.__is_library('fat_32_fruits.so') ) self.assertFalse( self.__is_library('fat_32_kiwi.o') ) self.assertFalse( self.__is_library('fat_64_cherry.o') ) self.assertTrue( self.__is_library('fat_64_fruits.a') ) self.assertTrue( self.__is_library('fat_64_fruits.so') ) self.assertFalse( self.__is_library('fat_64_kiwi.o') ) self.assertFalse( self.__is_library('fat_all_cherry.o') ) self.assertTrue( self.__is_library('fat_all_fruits.a') ) self.assertTrue( self.__is_library('fat_all_fruits.so') ) self.assertFalse( self.__is_library('fat_all_kiwi.o') ) self.assertFalse( self.__is_library('fat_avocado.o') ) self.assertFalse( self.__is_library('fat_cherry.o') ) self.assertTrue( self.__is_library('fat_all_fruits.a') ) self.assertFalse( self.__is_library('fat_kiwi.o') ) self.assertFalse( self.__is_library('fat_main.o') ) self.assertFalse( self.__is_library('fat_program.exe') ) self.assertFalse( self.__is_library('kiwi.o') ) self.assertTrue( self.__is_library('libarm64.a') ) self.assertTrue( self.__is_library('libarm64.so') ) self.assertTrue( self.__is_library('libarmv7.a') ) self.assertTrue( self.__is_library('libarmv7.so') ) self.assertTrue( self.__is_library('libi386.a') ) self.assertTrue( self.__is_library('libi386.so') ) self.assertTrue( self.__is_library('libx86_64.a') ) self.assertTrue( self.__is_library('libx86_64.so') ) self.assertFalse( self.__is_library('notalib.txt') ) self.assertFalse( self.__is_library('size1.txt') ) self.assertFalse( self.__is_library('size10.txt') ) self.assertFalse( self.__is_library('size2.txt') ) self.assertFalse( self.__is_library('size3.txt') ) self.assertFalse( self.__is_library('size4.txt') ) self.assertFalse( self.__is_library('size5.txt') ) self.assertFalse( self.__is_library('size6.txt') ) self.assertFalse( self.__is_library('size7.txt') ) self.assertFalse( self.__is_library('size8.txt') ) self.assertFalse( self.__is_library('size9.txt') ) self.assertFalse( self.__is_library('thin_arm64_avocado.o') ) self.assertFalse( self.__is_library('thin_armv7_avocado.o') ) self.assertFalse( self.__is_library('thin_cherry.o') ) self.assertTrue( self.__is_library('thin_fruits_arm64.a') ) self.assertTrue( self.__is_library('thin_fruits_arm64.so') ) self.assertTrue( self.__is_library('thin_fruits_armv7.a') ) self.assertTrue( self.__is_library('thin_fruits_armv7.so') ) self.assertTrue( self.__is_library('thin_fruits_i386.a') ) self.assertTrue( self.__is_library('thin_fruits_i386.so') ) self.assertTrue( self.__is_library('thin_fruits_x86_64.a') ) self.assertTrue( self.__is_library('thin_fruits_x86_64.so') ) self.assertFalse( self.__is_library('thin_i386_avocado.o') ) self.assertFalse( self.__is_library('thin_kiwi.o') ) self.assertFalse( self.__is_library('thin_main.o') ) self.assertFalse( self.__is_library('thin_program_i386.exe') ) self.assertFalse( self.__is_library('thin_program_x86_64.exe') ) self.assertFalse( self.__is_library('thin_x86_64_avocado.o') ) def test_is_shared_library(self): self.assertFalse( self.__is_shared_library('cherry.o') ) self.assertFalse( self.__is_shared_library('empty.txt') ) self.assertFalse( self.__is_shared_library('fat_32_cherry.o') ) self.assertFalse( self.__is_shared_library('fat_32_fruits.a') ) self.assertTrue( self.__is_shared_library('fat_32_fruits.so') ) self.assertFalse( self.__is_shared_library('fat_32_kiwi.o') ) self.assertFalse( self.__is_shared_library('fat_64_cherry.o') ) self.assertFalse( self.__is_shared_library('fat_64_fruits.a') ) self.assertTrue( self.__is_shared_library('fat_64_fruits.so') ) self.assertFalse( self.__is_shared_library('fat_64_kiwi.o') ) self.assertFalse( self.__is_shared_library('fat_all_cherry.o') ) self.assertFalse( self.__is_shared_library('fat_all_fruits.a') ) self.assertTrue( self.__is_shared_library('fat_all_fruits.so') ) self.assertFalse( self.__is_shared_library('fat_all_kiwi.o') ) self.assertFalse( self.__is_shared_library('fat_avocado.o') ) self.assertFalse( self.__is_shared_library('fat_cherry.o') ) self.assertFalse( self.__is_shared_library('fat_all_fruits.a') ) self.assertFalse( self.__is_shared_library('fat_kiwi.o') ) self.assertFalse( self.__is_shared_library('fat_main.o') ) self.assertFalse( self.__is_shared_library('fat_program.exe') ) self.assertFalse( self.__is_shared_library('kiwi.o') ) self.assertFalse( self.__is_shared_library('libarm64.a') ) self.assertTrue( self.__is_shared_library('libarm64.so') ) self.assertFalse( self.__is_shared_library('libarmv7.a') ) self.assertTrue( self.__is_shared_library('libarmv7.so') ) self.assertFalse( self.__is_shared_library('libi386.a') ) self.assertTrue( self.__is_shared_library('libi386.so') ) self.assertFalse( self.__is_shared_library('libx86_64.a') ) self.assertTrue( self.__is_shared_library('libx86_64.so') ) self.assertFalse( self.__is_shared_library('notalib.txt') ) self.assertFalse( self.__is_shared_library('size1.txt') ) self.assertFalse( self.__is_shared_library('size10.txt') ) self.assertFalse( self.__is_shared_library('size2.txt') ) self.assertFalse( self.__is_shared_library('size3.txt') ) self.assertFalse( self.__is_shared_library('size4.txt') ) self.assertFalse( self.__is_shared_library('size5.txt') ) self.assertFalse( self.__is_shared_library('size6.txt') ) self.assertFalse( self.__is_shared_library('size7.txt') ) self.assertFalse( self.__is_shared_library('size8.txt') ) self.assertFalse( self.__is_shared_library('size9.txt') ) self.assertFalse( self.__is_shared_library('thin_arm64_avocado.o') ) self.assertFalse( self.__is_shared_library('thin_armv7_avocado.o') ) self.assertFalse( self.__is_shared_library('thin_cherry.o') ) self.assertFalse( self.__is_shared_library('thin_fruits_arm64.a') ) self.assertTrue( self.__is_shared_library('thin_fruits_arm64.so') ) self.assertFalse( self.__is_shared_library('thin_fruits_armv7.a') ) self.assertTrue( self.__is_shared_library('thin_fruits_armv7.so') ) self.assertFalse( self.__is_shared_library('thin_fruits_i386.a') ) self.assertTrue( self.__is_shared_library('thin_fruits_i386.so') ) self.assertFalse( self.__is_shared_library('thin_fruits_x86_64.a') ) self.assertTrue( self.__is_shared_library('thin_fruits_x86_64.so') ) self.assertFalse( self.__is_shared_library('thin_i386_avocado.o') ) self.assertFalse( self.__is_shared_library('thin_kiwi.o') ) self.assertFalse( self.__is_shared_library('thin_main.o') ) self.assertFalse( self.__is_shared_library('thin_program_i386.exe') ) self.assertFalse( self.__is_shared_library('thin_program_x86_64.exe') ) self.assertFalse( self.__is_shared_library('thin_x86_64_avocado.o') ) @skip_if(not host.is_macos(), 'not macos') def test_dependencies_macos(self): deps = library.dependencies('/bin/bash') self.assertEquals( 2, len(deps) ) self.assertTrue( path.basename(deps[0]).startswith('libSystem') ) self.assertTrue( path.basename(deps[1]).startswith('libncurses') ) @skip_if(not host.is_linux(), 'not linux') def test_dependencies_linux(self): deps = library.dependencies('/bin/bash') if host.ARCH.startswith('arm'): expected_deps = [ '/lib/arm-linux-gnueabihf/libc.so.6', '/lib/arm-linux-gnueabihf/libdl.so.2', '/lib/arm-linux-gnueabihf/libtinfo.so.5', '/lib/ld-linux-armhf.so.3', ] if host.DISTRO == 'raspbian': expected_deps.append('/usr/lib/arm-linux-gnueabihf/libarmmem.so') else: expected_deps = [ '/lib/x86_64-linux-gnu/libc.so.6', '/lib/x86_64-linux-gnu/libdl.so.2', '/lib/x86_64-linux-gnu/libtinfo.so.5', '/lib64/ld-linux-x86-64.so.2', ] self.assertEquals( expected_deps, deps ) def __is_library(self, filename): return library.is_library(self.data_path(filename, platform_specific = True)) def __is_shared_library(self, filename): return library.is_shared_library(self.data_path(filename, platform_specific = True)) def __is_static_library(self, filename): return library.is_static_library(self.data_path(filename, platform_specific = True)) def test_is_archive_dir_error(self): self.assertFalse( library.is_archive('/usr/bin') ) def test_name(self): self.assertEqual( 'foo', library.name('/usr/lib/libfoo.1.2.3.dylib') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.1.2.dylib') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.1.dylib') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.dylib') ) self.assertEqual( 'foo', library.name('libfoo.dylib') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.so.1.2.3') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.so.1.2') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.so.1') ) self.assertEqual( 'foo', library.name('/usr/lib/libfoo.so') ) self.assertEqual( 'foo', library.name('libfoo.dylib') ) self.assertEqual( 'foo', library.name('libfoo.a') ) self.assertEqual( 'foo', library.name('libfoo.1.2.8.dylib') ) self.assertEqual( 'foo', library.name('libfoo.1.dylib') ) self.assertEqual( 'foo', library.name('libfoo.dylib') ) def test_name_add_prefix(self): self.assertEqual( 'libkiwi_foo.a', library.name_add_prefix('libfoo.a', 'kiwi_') ) self.assertEqual( 'libkiwi_foo.dylib', library.name_add_prefix('libfoo.dylib', 'kiwi_') ) self.assertEqual( 'libkiwi_foo.1.2.3.dylib', library.name_add_prefix('libfoo.1.2.3.dylib', 'kiwi_') ) self.assertEqual( 'libkiwi_foo.so', library.name_add_prefix('libfoo.so', 'kiwi_') ) self.assertEqual( 'libkiwi_foo.so.1', library.name_add_prefix('libfoo.so.1', 'kiwi_') ) self.assertEqual( None, library.name_add_prefix('pic.png', 'kiwi_') ) @skip_if(not host.is_macos(), 'not macos') def test_list_libraries_macos(self): expected_libs = [ 'fat_32_fruits.a', 'fat_32_fruits.so', 'fat_64_fruits.a', 'fat_64_fruits.so', 'fat_all_fruits.a', 'fat_all_fruits.so', 'fat_fruits.a', 'fat_fruits.so', 'libarm64.a', 'libarm64.so', 'libarmv7.a', 'libarmv7.so', 'libi386.a', 'libi386.so', 'libx86_64.a', 'libx86_64.so', 'thin_fruits_arm64.a', 'thin_fruits_arm64.so', 'thin_fruits_armv7.a', 'thin_fruits_armv7.so', 'thin_fruits_i386.a', 'thin_fruits_i386.so', 'thin_fruits_x86_64.a', 'thin_fruits_x86_64.so', ] self.assertEqual( expected_libs, library.list_libraries(self.data_dir(platform_specific = True), relative = True) ) @skip_if(not host.is_linux(), 'not linux') def test_list_libraries_macos(self): self.maxDiff = None expected_libs = [ 'fat_32_fruits.a', 'fat_32_fruits.so', 'fat_64_fruits.a', 'fat_64_fruits.so', 'fat_all_fruits.a', 'fat_all_fruits.so', 'libarm64.a', 'libarm64.so', 'libarmv7.a', 'libarmv7.so', 'libi386.a', 'libi386.so', 'libx86_64.a', 'libx86_64.so', 'thin_fruits_arm64.a', 'thin_fruits_arm64.so', 'thin_fruits_armv7.a', 'thin_fruits_armv7.so', 'thin_fruits_i386.a', 'thin_fruits_i386.so', 'thin_fruits_x86_64.a', 'thin_fruits_x86_64.so', ] self.assertEqual( expected_libs, library.list_libraries(self.data_dir(platform_specific = True)) ) def test_relative_rpath(self): self.assertEqual( '../lib/libx.so', library.relative_rpath('/foo/bar/bin/pngfix', '/foo/bar/lib/libx.so') ) self.assertEqual( '', library.relative_rpath('/foo/bar/lib/liby.so', '/foo/bar/lib/libx.so') )