1
1
import contextlib
2
+ import glob
2
3
import importlib
3
- import os
4
+ import os . path
4
5
import platform
5
6
import re
6
7
import shutil
7
8
import site
9
+ import subprocess
8
10
import sys
9
11
import tempfile
10
12
import textwrap
13
+ import time
11
14
from distutils import sysconfig
12
15
from distutils .command .build_ext import build_ext
13
16
from distutils .core import Distribution
@@ -51,6 +54,9 @@ def user_site_dir(request):
51
54
site .USER_BASE = orig_user_base
52
55
build_ext .USER_BASE = orig_user_base
53
56
57
+ if sys .platform == 'cygwin' :
58
+ time .sleep (1 )
59
+
54
60
55
61
@contextlib .contextmanager
56
62
def safe_extension_import (name , path ):
@@ -86,11 +92,35 @@ class TestBuildExt(TempdirManager):
86
92
def build_ext (self , * args , ** kwargs ):
87
93
return build_ext (* args , ** kwargs )
88
94
89
- def test_build_ext (self ):
95
+ @pytest .mark .parametrize ("copy_so" , [False ])
96
+ def test_build_ext (self , copy_so ):
90
97
missing_compiler_executable ()
91
98
copy_xxmodule_c (self .tmp_dir )
92
99
xx_c = os .path .join (self .tmp_dir , 'xxmodule.c' )
93
100
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
+ )
94
124
dist = Distribution ({'name' : 'xx' , 'ext_modules' : [xx_ext ]})
95
125
dist .package_dir = self .tmp_dir
96
126
cmd = self .build_ext (dist )
@@ -109,10 +139,13 @@ def test_build_ext(self):
109
139
sys .stdout = old_stdout
110
140
111
141
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' )
113
146
114
147
@staticmethod
115
- def _test_xx ():
148
+ def _test_xx (copy_so ):
116
149
import xx
117
150
118
151
for attr in ('error' , 'foo' , 'new' , 'roj' ):
@@ -127,6 +160,28 @@ def _test_xx():
127
160
assert isinstance (xx .Null (), xx .Null )
128
161
assert isinstance (xx .Str (), xx .Str )
129
162
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
+
130
185
def test_solaris_enable_shared (self ):
131
186
dist = Distribution ({'name' : 'xx' })
132
187
cmd = self .build_ext (dist )
0 commit comments