11import contextlib
2+ import glob
23import importlib
3- import os
4+ import os . path
45import platform
56import re
67import shutil
78import site
9+ import subprocess
810import sys
911import tempfile
1012import textwrap
13+ import time
1114from distutils import sysconfig
1215from distutils .command .build_ext import build_ext
1316from distutils .core import Distribution
@@ -51,6 +54,9 @@ def user_site_dir(request):
5154 site .USER_BASE = orig_user_base
5255 build_ext .USER_BASE = orig_user_base
5356
57+ if sys .platform == 'cygwin' :
58+ time .sleep (1 )
59+
5460
5561@contextlib .contextmanager
5662def safe_extension_import (name , path ):
@@ -86,11 +92,35 @@ class TestBuildExt(TempdirManager):
8692 def build_ext (self , * args , ** kwargs ):
8793 return build_ext (* args , ** kwargs )
8894
89- def test_build_ext (self ):
95+ @pytest .mark .parametrize ("copy_so" , [False ])
96+ def test_build_ext (self , copy_so ):
9097 missing_compiler_executable ()
9198 copy_xxmodule_c (self .tmp_dir )
9299 xx_c = os .path .join (self .tmp_dir , 'xxmodule.c' )
93100 xx_ext = Extension ('xx' , [xx_c ])
101+ if sys .platform != "win32" :
102+ if not copy_so :
103+ xx_ext = Extension (
104+ 'xx' ,
105+ [xx_c ],
106+ library_dirs = ['/usr/lib' ],
107+ libraries = ['z' ],
108+ runtime_library_dirs = ['/usr/lib' ],
109+ )
110+ elif sys .platform == 'linux' :
111+ libz_so = {
112+ os .path .realpath (name ) for name in glob .iglob ('/usr/lib*/libz.so*' )
113+ }
114+ libz_so = sorted (libz_so , key = lambda lib_path : len (lib_path ))
115+ shutil .copyfile (libz_so [- 1 ], '/tmp/libxx_z.so' )
116+
117+ xx_ext = Extension (
118+ 'xx' ,
119+ [xx_c ],
120+ library_dirs = ['/tmp' ],
121+ libraries = ['xx_z' ],
122+ runtime_library_dirs = ['/tmp' ],
123+ )
94124 dist = Distribution ({'name' : 'xx' , 'ext_modules' : [xx_ext ]})
95125 dist .package_dir = self .tmp_dir
96126 cmd = self .build_ext (dist )
@@ -109,10 +139,13 @@ def test_build_ext(self):
109139 sys .stdout = old_stdout
110140
111141 with safe_extension_import ('xx' , self .tmp_dir ):
112- self ._test_xx ()
142+ self ._test_xx (copy_so )
143+
144+ if sys .platform == 'linux' and copy_so :
145+ os .unlink ('/tmp/libxx_z.so' )
113146
114147 @staticmethod
115- def _test_xx ():
148+ def _test_xx (copy_so ):
116149 import xx
117150
118151 for attr in ('error' , 'foo' , 'new' , 'roj' ):
@@ -127,6 +160,28 @@ def _test_xx():
127160 assert isinstance (xx .Null (), xx .Null )
128161 assert isinstance (xx .Str (), xx .Str )
129162
163+ if sys .platform == 'linux' :
164+ so_headers = subprocess .check_output (
165+ ["readelf" , "-d" , xx .__file__ ], universal_newlines = True
166+ )
167+ import pprint
168+
169+ pprint .pprint (so_headers )
170+ rpaths = [
171+ rpath
172+ for line in so_headers .split ("\n " )
173+ if "RPATH" in line or "RUNPATH" in line
174+ for rpath in line .split ()[2 ][1 :- 1 ].split (":" )
175+ ]
176+ if not copy_so :
177+ pprint .pprint (rpaths )
178+ # Linked against a library in /usr/lib{,64}
179+ assert "/usr/lib" not in rpaths and "/usr/lib64" not in rpaths
180+ else :
181+ # Linked against a library in /tmp
182+ assert "/tmp" in rpaths
183+ # The import is the real test here
184+
130185 def test_solaris_enable_shared (self ):
131186 dist = Distribution ({'name' : 'xx' })
132187 cmd = self .build_ext (dist )
0 commit comments