18
17
# Don't load the xx module more than once.
19
18
ALREADY_TESTED = False
21
def _get_source_filename():
22
srcdir = sysconfig.get_config_var('srcdir')
24
return os.path.join(sysconfig.project_base, 'Modules', 'xxmodule.c')
25
return os.path.join(srcdir, 'Modules', 'xxmodule.c')
27
_XX_MODULE_PATH = _get_source_filename()
29
21
class BuildExtTestCase(support.TempdirManager,
30
22
support.LoggingSilencer,
31
23
unittest.TestCase):
33
# Create a simple test environment
34
# Note that we're making changes to sys.path
35
25
super(BuildExtTestCase, self).setUp()
36
self.tmp_dir = tempfile.mkdtemp(prefix="pythontest_")
37
if os.path.exists(_XX_MODULE_PATH):
38
self.sys_path = sys.path[:]
39
sys.path.append(self.tmp_dir)
40
shutil.copy(_XX_MODULE_PATH, self.tmp_dir)
26
self.tmp_dir = self.mkdtemp()
27
self.xx_created = False
28
sys.path.append(self.tmp_dir)
29
self.addCleanup(sys.path.remove, self.tmp_dir)
30
if sys.version > "2.6":
32
self.old_user_base = site.USER_BASE
33
site.USER_BASE = self.mkdtemp()
34
from distutils.command import build_ext
35
build_ext.USER_BASE = site.USER_BASE
42
37
def tearDown(self):
43
# Get everything back to normal
44
if os.path.exists(_XX_MODULE_PATH):
45
39
test_support.unload('xx')
46
sys.path[:] = self.sys_path
47
40
# XXX on Windows the test leaves a directory
48
41
# with xx module in TEMP
49
shutil.rmtree(self.tmp_dir, os.name == 'nt' or
50
sys.platform == 'cygwin')
51
42
super(BuildExtTestCase, self).tearDown()
53
def _fixup_command(self, cmd):
54
# When Python was build with --enable-shared, -L. is not good enough
55
# to find the libpython<blah>.so. This is because regrtest runs it
56
# under a tempdir, not in the top level where the .so lives. By the
57
# time we've gotten here, Python's already been chdir'd to the
60
# To further add to the fun, we can't just add library_dirs to the
61
# Extension() instance because that doesn't get plumbed through to the
62
# final compiler command.
63
if (sysconfig.get_config_var('Py_ENABLE_SHARED') and
64
not sys.platform.startswith('win')):
65
runshared = sysconfig.get_config_var('RUNSHARED')
67
cmd.library_dirs = ['.']
69
name, equals, value = runshared.partition('=')
70
cmd.library_dirs = value.split(os.pathsep)
72
@unittest.skipIf(not os.path.exists(_XX_MODULE_PATH),
73
'xxmodule.c not found')
74
44
def test_build_ext(self):
75
45
global ALREADY_TESTED
46
support.copy_xxmodule_c(self.tmp_dir)
47
self.xx_created = True
76
48
xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
77
49
xx_ext = Extension('xx', [xx_c])
78
50
dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
79
51
dist.package_dir = self.tmp_dir
80
52
cmd = build_ext(dist)
81
self._fixup_command(cmd)
83
# On Windows, we must build a debug version iff running
84
# a debug build of Python
85
cmd.debug = sys.executable.endswith("_d.exe")
53
support.fixup_build_ext(cmd)
86
54
cmd.build_lib = self.tmp_dir
87
55
cmd.build_temp = self.tmp_dir
135
103
# make sure we get some library dirs under solaris
136
104
self.assertTrue(len(cmd.library_dirs) > 0)
106
def test_user_site(self):
107
# site.USER_SITE was introduced in 2.6
108
if sys.version < '2.6':
112
dist = Distribution({'name': 'xx'})
113
cmd = build_ext(dist)
115
# making sure the user option is there
116
options = [name for name, short, label in
118
self.assertIn('user', options)
123
# setting user based lib and include
124
lib = os.path.join(site.USER_BASE, 'lib')
125
incl = os.path.join(site.USER_BASE, 'include')
129
cmd.ensure_finalized()
131
# see if include_dirs and library_dirs were set
132
self.assertIn(lib, cmd.library_dirs)
133
self.assertIn(lib, cmd.rpath)
134
self.assertIn(incl, cmd.include_dirs)
138
136
def test_finalize_options(self):
139
137
# Make sure Python's include directories (for Python.h, pyconfig.h,
140
138
# etc.) are in the include search path.
153
150
# make sure cmd.libraries is turned into a list
154
151
# if it's a string
155
152
cmd = build_ext(dist)
156
cmd.libraries = 'my_lib'
153
cmd.libraries = 'my_lib, other_lib lastlib'
157
154
cmd.finalize_options()
158
self.assertEqual(cmd.libraries, ['my_lib'])
155
self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib'])
160
157
# make sure cmd.library_dirs is turned into a list
161
158
# if it's a string
162
159
cmd = build_ext(dist)
163
cmd.library_dirs = 'my_lib_dir'
160
cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep
164
161
cmd.finalize_options()
165
self.assertTrue('my_lib_dir' in cmd.library_dirs)
162
self.assertIn('my_lib_dir', cmd.library_dirs)
163
self.assertIn('other_lib_dir', cmd.library_dirs)
167
165
# make sure rpath is turned into a list
168
# if it's a list of os.pathsep's paths
169
167
cmd = build_ext(dist)
170
cmd.rpath = os.pathsep.join(['one', 'two'])
168
cmd.rpath = 'one%stwo' % os.pathsep
171
169
cmd.finalize_options()
172
170
self.assertEqual(cmd.rpath, ['one', 'two'])
432
427
self.assertEqual(ext_path, wanted)
434
429
@unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX')
435
def test_deployment_target(self):
436
self._try_compile_deployment_target()
430
def test_deployment_target_default(self):
431
# Issue 9516: Test that, in the absence of the environment variable,
432
# an extension module is compiled with the same deployment target as
434
self._try_compile_deployment_target('==', None)
436
@unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX')
437
def test_deployment_target_too_low(self):
438
# Issue 9516: Test that an extension module is not allowed to be
439
# compiled with a deployment target less than that of the interpreter.
440
self.assertRaises(DistutilsPlatformError,
441
self._try_compile_deployment_target, '>', '10.1')
443
@unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX')
444
def test_deployment_target_higher_ok(self):
445
# Issue 9516: Test that an extension module can be compiled with a
446
# deployment target higher than that of the interpreter: the ext
447
# module may depend on some newer OS feature.
448
deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
450
# increment the minor version number (i.e. 10.6 -> 10.7)
451
deptarget = [int(x) for x in deptarget.split('.')]
453
deptarget = '.'.join(str(i) for i in deptarget)
454
self._try_compile_deployment_target('<', deptarget)
456
def _try_compile_deployment_target(self, operator, target):
438
457
orig_environ = os.environ
439
458
os.environ = orig_environ.copy()
440
459
self.addCleanup(setattr, os, 'environ', orig_environ)
442
os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1'
443
self._try_compile_deployment_target()
446
def _try_compile_deployment_target(self):
462
if os.environ.get('MACOSX_DEPLOYMENT_TARGET'):
463
del os.environ['MACOSX_DEPLOYMENT_TARGET']
465
os.environ['MACOSX_DEPLOYMENT_TARGET'] = target
447
467
deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c')
449
469
with open(deptarget_c, 'w') as fp: