blob: 0aa99babee4c5fb97f07d743360de3b35e0774c3 [file] [log] [blame]
Georg Brandlb533e262008-05-25 18:19:30 +00001import sys
2import os
Georg Brandlb533e262008-05-25 18:19:30 +00003import shutil
4from io import StringIO
Ronald Oussoren222e89a2011-05-15 16:46:11 +02005import textwrap
Georg Brandlb533e262008-05-25 18:19:30 +00006
Barry Warsaw8cf4eae2010-10-16 01:04:07 +00007from distutils.core import Distribution
Georg Brandlb533e262008-05-25 18:19:30 +00008from distutils.command.build_ext import build_ext
Tarek Ziadé36797272010-07-22 12:50:05 +00009from distutils import sysconfig
Tarek Ziadéc1375d52009-02-14 14:35:51 +000010from distutils.tests.support import TempdirManager
Tarek Ziadéb2e36f12009-03-31 22:37:55 +000011from distutils.tests.support import LoggingSilencer
12from distutils.extension import Extension
Barry Warsaw8cf4eae2010-10-16 01:04:07 +000013from distutils.errors import (
14 CompileError, DistutilsSetupError, UnknownFileError)
Georg Brandlb533e262008-05-25 18:19:30 +000015
16import unittest
17from test import support
Éric Araujo70ec44a2010-11-06 02:44:43 +000018from test.support import run_unittest
Georg Brandlb533e262008-05-25 18:19:30 +000019
Christian Heimes3e7e0692008-11-25 21:21:32 +000020# http://bugs.python.org/issue4373
21# Don't load the xx module more than once.
22ALREADY_TESTED = False
23
Neil Schemenauerd8f63bb2009-02-06 21:42:05 +000024def _get_source_filename():
25 srcdir = sysconfig.get_config_var('srcdir')
26 return os.path.join(srcdir, 'Modules', 'xxmodule.c')
27
Tarek Ziadé36797272010-07-22 12:50:05 +000028class BuildExtTestCase(TempdirManager,
29 LoggingSilencer,
30 unittest.TestCase):
Georg Brandlb533e262008-05-25 18:19:30 +000031 def setUp(self):
32 # Create a simple test environment
33 # Note that we're making changes to sys.path
Tarek Ziadé38e3d512009-02-27 12:58:56 +000034 super(BuildExtTestCase, self).setUp()
Tarek Ziadéc1375d52009-02-14 14:35:51 +000035 self.tmp_dir = self.mkdtemp()
Tarek Ziadé36797272010-07-22 12:50:05 +000036 self.sys_path = sys.path, sys.path[:]
37 sys.path.append(self.tmp_dir)
38 shutil.copy(_get_source_filename(), self.tmp_dir)
Tarek Ziadé38e3d512009-02-27 12:58:56 +000039 if sys.version > "2.6":
40 import site
41 self.old_user_base = site.USER_BASE
42 site.USER_BASE = self.mkdtemp()
43 from distutils.command import build_ext
44 build_ext.USER_BASE = site.USER_BASE
Georg Brandlb533e262008-05-25 18:19:30 +000045
Barry Warsaw8cf4eae2010-10-16 01:04:07 +000046 def _fixup_command(self, cmd):
47 # When Python was build with --enable-shared, -L. is not good enough
48 # to find the libpython<blah>.so. This is because regrtest runs it
49 # under a tempdir, not in the top level where the .so lives. By the
50 # time we've gotten here, Python's already been chdir'd to the
51 # tempdir.
52 #
53 # To further add to the fun, we can't just add library_dirs to the
54 # Extension() instance because that doesn't get plumbed through to the
55 # final compiler command.
Barry Warsaw4ebfdf02010-10-22 17:17:51 +000056 if (sysconfig.get_config_var('Py_ENABLE_SHARED') and
57 not sys.platform.startswith('win')):
Éric Araujo68fc9aa2010-10-21 23:02:07 +000058 runshared = sysconfig.get_config_var('RUNSHARED')
59 if runshared is None:
60 cmd.library_dirs = ['.']
61 else:
62 name, equals, value = runshared.partition('=')
63 cmd.library_dirs = value.split(os.pathsep)
Barry Warsaw8cf4eae2010-10-16 01:04:07 +000064
Georg Brandlb533e262008-05-25 18:19:30 +000065 def test_build_ext(self):
Christian Heimes3e7e0692008-11-25 21:21:32 +000066 global ALREADY_TESTED
Georg Brandlb533e262008-05-25 18:19:30 +000067 xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
68 xx_ext = Extension('xx', [xx_c])
69 dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
70 dist.package_dir = self.tmp_dir
71 cmd = build_ext(dist)
Barry Warsaw8cf4eae2010-10-16 01:04:07 +000072 self._fixup_command(cmd)
Thomas Heller84b7f0c2008-05-26 11:51:44 +000073 if os.name == "nt":
74 # On Windows, we must build a debug version iff running
75 # a debug build of Python
76 cmd.debug = sys.executable.endswith("_d.exe")
Georg Brandlb533e262008-05-25 18:19:30 +000077 cmd.build_lib = self.tmp_dir
78 cmd.build_temp = self.tmp_dir
79
80 old_stdout = sys.stdout
81 if not support.verbose:
82 # silence compiler output
83 sys.stdout = StringIO()
84 try:
85 cmd.ensure_finalized()
86 cmd.run()
87 finally:
88 sys.stdout = old_stdout
89
Christian Heimes3e7e0692008-11-25 21:21:32 +000090 if ALREADY_TESTED:
91 return
92 else:
93 ALREADY_TESTED = True
94
Georg Brandlb533e262008-05-25 18:19:30 +000095 import xx
96
97 for attr in ('error', 'foo', 'new', 'roj'):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000098 self.assertTrue(hasattr(xx, attr))
Georg Brandlb533e262008-05-25 18:19:30 +000099
Ezio Melottib3aedd42010-11-20 19:04:17 +0000100 self.assertEqual(xx.foo(2, 5), 7)
101 self.assertEqual(xx.foo(13,15), 28)
102 self.assertEqual(xx.new().demo(), None)
Georg Brandlb533e262008-05-25 18:19:30 +0000103 doc = 'This is a template module just for instruction.'
Ezio Melottib3aedd42010-11-20 19:04:17 +0000104 self.assertEqual(xx.__doc__, doc)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000105 self.assertTrue(isinstance(xx.Null(), xx.Null))
106 self.assertTrue(isinstance(xx.Str(), xx.Str))
Georg Brandlb533e262008-05-25 18:19:30 +0000107
Tarek Ziadé36797272010-07-22 12:50:05 +0000108 def tearDown(self):
109 # Get everything back to normal
110 support.unload('xx')
111 sys.path = self.sys_path[0]
112 sys.path[:] = self.sys_path[1]
113 if sys.version > "2.6":
114 import site
115 site.USER_BASE = self.old_user_base
116 from distutils.command import build_ext
117 build_ext.USER_BASE = self.old_user_base
118 super(BuildExtTestCase, self).tearDown()
119
Tarek Ziadé5874ef12009-02-05 22:56:14 +0000120 def test_solaris_enable_shared(self):
121 dist = Distribution({'name': 'xx'})
122 cmd = build_ext(dist)
123 old = sys.platform
124
125 sys.platform = 'sunos' # fooling finalize_options
Tarek Ziadé36797272010-07-22 12:50:05 +0000126 from distutils.sysconfig import _config_vars
127 old_var = _config_vars.get('Py_ENABLE_SHARED')
128 _config_vars['Py_ENABLE_SHARED'] = 1
Tarek Ziadé5874ef12009-02-05 22:56:14 +0000129 try:
130 cmd.ensure_finalized()
131 finally:
132 sys.platform = old
133 if old_var is None:
Tarek Ziadé36797272010-07-22 12:50:05 +0000134 del _config_vars['Py_ENABLE_SHARED']
Tarek Ziadé5874ef12009-02-05 22:56:14 +0000135 else:
Tarek Ziadé36797272010-07-22 12:50:05 +0000136 _config_vars['Py_ENABLE_SHARED'] = old_var
Tarek Ziadé5874ef12009-02-05 22:56:14 +0000137
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000138 # make sure we get some library dirs under solaris
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000139 self.assertTrue(len(cmd.library_dirs) > 0)
Tarek Ziadé5874ef12009-02-05 22:56:14 +0000140
Tarek Ziadé38e3d512009-02-27 12:58:56 +0000141 def test_user_site(self):
142 # site.USER_SITE was introduced in 2.6
143 if sys.version < '2.6':
144 return
145
146 import site
147 dist = Distribution({'name': 'xx'})
148 cmd = build_ext(dist)
149
Tarek Ziadébe720e02009-05-09 11:55:12 +0000150 # making sure the user option is there
Tarek Ziadé38e3d512009-02-27 12:58:56 +0000151 options = [name for name, short, lable in
152 cmd.user_options]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000153 self.assertTrue('user' in options)
Tarek Ziadé38e3d512009-02-27 12:58:56 +0000154
155 # setting a value
156 cmd.user = 1
157
158 # setting user based lib and include
159 lib = os.path.join(site.USER_BASE, 'lib')
160 incl = os.path.join(site.USER_BASE, 'include')
161 os.mkdir(lib)
162 os.mkdir(incl)
163
164 # let's run finalize
165 cmd.ensure_finalized()
166
167 # see if include_dirs and library_dirs
168 # were set
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000169 self.assertTrue(lib in cmd.library_dirs)
170 self.assertTrue(lib in cmd.rpath)
171 self.assertTrue(incl in cmd.include_dirs)
Tarek Ziadé38e3d512009-02-27 12:58:56 +0000172
Tarek Ziadéb2e36f12009-03-31 22:37:55 +0000173 def test_optional_extension(self):
174
175 # this extension will fail, but let's ignore this failure
176 # with the optional argument.
177 modules = [Extension('foo', ['xxx'], optional=False)]
178 dist = Distribution({'name': 'xx', 'ext_modules': modules})
179 cmd = build_ext(dist)
180 cmd.ensure_finalized()
Tarek Ziadé30911292009-03-31 22:50:54 +0000181 self.assertRaises((UnknownFileError, CompileError),
182 cmd.run) # should raise an error
Tarek Ziadéb2e36f12009-03-31 22:37:55 +0000183
184 modules = [Extension('foo', ['xxx'], optional=True)]
185 dist = Distribution({'name': 'xx', 'ext_modules': modules})
186 cmd = build_ext(dist)
187 cmd.ensure_finalized()
188 cmd.run() # should pass
189
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000190 def test_finalize_options(self):
191 # Make sure Python's include directories (for Python.h, pyconfig.h,
192 # etc.) are in the include search path.
193 modules = [Extension('foo', ['xxx'], optional=False)]
194 dist = Distribution({'name': 'xx', 'ext_modules': modules})
195 cmd = build_ext(dist)
196 cmd.finalize_options()
197
Tarek Ziadé36797272010-07-22 12:50:05 +0000198 from distutils import sysconfig
199 py_include = sysconfig.get_python_inc()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000200 self.assertTrue(py_include in cmd.include_dirs)
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000201
Tarek Ziadé36797272010-07-22 12:50:05 +0000202 plat_py_include = sysconfig.get_python_inc(plat_specific=1)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000203 self.assertTrue(plat_py_include in cmd.include_dirs)
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000204
205 # make sure cmd.libraries is turned into a list
206 # if it's a string
207 cmd = build_ext(dist)
208 cmd.libraries = 'my_lib'
209 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000210 self.assertEqual(cmd.libraries, ['my_lib'])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000211
212 # make sure cmd.library_dirs is turned into a list
213 # if it's a string
214 cmd = build_ext(dist)
215 cmd.library_dirs = 'my_lib_dir'
216 cmd.finalize_options()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000217 self.assertTrue('my_lib_dir' in cmd.library_dirs)
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000218
219 # make sure rpath is turned into a list
220 # if it's a list of os.pathsep's paths
221 cmd = build_ext(dist)
222 cmd.rpath = os.pathsep.join(['one', 'two'])
223 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000224 self.assertEqual(cmd.rpath, ['one', 'two'])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000225
226 # XXX more tests to perform for win32
227
228 # make sure define is turned into 2-tuples
229 # strings if they are ','-separated strings
230 cmd = build_ext(dist)
231 cmd.define = 'one,two'
232 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000233 self.assertEqual(cmd.define, [('one', '1'), ('two', '1')])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000234
235 # make sure undef is turned into a list of
236 # strings if they are ','-separated strings
237 cmd = build_ext(dist)
238 cmd.undef = 'one,two'
239 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000240 self.assertEqual(cmd.undef, ['one', 'two'])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000241
242 # make sure swig_opts is turned into a list
243 cmd = build_ext(dist)
244 cmd.swig_opts = None
245 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000246 self.assertEqual(cmd.swig_opts, [])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000247
248 cmd = build_ext(dist)
249 cmd.swig_opts = '1 2'
250 cmd.finalize_options()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000251 self.assertEqual(cmd.swig_opts, ['1', '2'])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000252
253 def test_check_extensions_list(self):
254 dist = Distribution()
255 cmd = build_ext(dist)
256 cmd.finalize_options()
257
258 #'extensions' option must be a list of Extension instances
Barry Warsaw8cf4eae2010-10-16 01:04:07 +0000259 self.assertRaises(DistutilsSetupError,
260 cmd.check_extensions_list, 'foo')
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000261
262 # each element of 'ext_modules' option must be an
263 # Extension instance or 2-tuple
264 exts = [('bar', 'foo', 'bar'), 'foo']
265 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)
266
267 # first element of each tuple in 'ext_modules'
268 # must be the extension name (a string) and match
269 # a python dotted-separated name
270 exts = [('foo-bar', '')]
271 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)
272
273 # second element of each tuple in 'ext_modules'
274 # must be a ary (build info)
275 exts = [('foo.bar', '')]
276 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)
277
278 # ok this one should pass
279 exts = [('foo.bar', {'sources': [''], 'libraries': 'foo',
280 'some': 'bar'})]
281 cmd.check_extensions_list(exts)
282 ext = exts[0]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000283 self.assertTrue(isinstance(ext, Extension))
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000284
285 # check_extensions_list adds in ext the values passed
286 # when they are in ('include_dirs', 'library_dirs', 'libraries'
287 # 'extra_objects', 'extra_compile_args', 'extra_link_args')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000288 self.assertEqual(ext.libraries, 'foo')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000289 self.assertTrue(not hasattr(ext, 'some'))
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000290
291 # 'macros' element of build info dict must be 1- or 2-tuple
292 exts = [('foo.bar', {'sources': [''], 'libraries': 'foo',
293 'some': 'bar', 'macros': [('1', '2', '3'), 'foo']})]
294 self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts)
295
296 exts[0][1]['macros'] = [('1', '2'), ('3',)]
297 cmd.check_extensions_list(exts)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000298 self.assertEqual(exts[0].undef_macros, ['3'])
299 self.assertEqual(exts[0].define_macros, [('1', '2')])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000300
301 def test_get_source_files(self):
302 modules = [Extension('foo', ['xxx'], optional=False)]
303 dist = Distribution({'name': 'xx', 'ext_modules': modules})
304 cmd = build_ext(dist)
305 cmd.ensure_finalized()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000306 self.assertEqual(cmd.get_source_files(), ['xxx'])
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000307
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000308 def test_compiler_option(self):
309 # cmd.compiler is an option and
310 # should not be overriden by a compiler instance
311 # when the command is run
312 dist = Distribution()
313 cmd = build_ext(dist)
314 cmd.compiler = 'unix'
315 cmd.ensure_finalized()
316 cmd.run()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000317 self.assertEqual(cmd.compiler, 'unix')
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000318
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000319 def test_get_outputs(self):
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000320 tmp_dir = self.mkdtemp()
321 c_file = os.path.join(tmp_dir, 'foo.c')
Victor Stinner3e2b7172010-11-09 09:32:19 +0000322 self.write_file(c_file, 'void PyInit_foo(void) {}\n')
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000323 ext = Extension('foo', [c_file], optional=False)
324 dist = Distribution({'name': 'xx',
325 'ext_modules': [ext]})
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000326 cmd = build_ext(dist)
Barry Warsaw8cf4eae2010-10-16 01:04:07 +0000327 self._fixup_command(cmd)
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000328 cmd.ensure_finalized()
Ezio Melottib3aedd42010-11-20 19:04:17 +0000329 self.assertEqual(len(cmd.get_outputs()), 1)
Tarek Ziadé06fbee12009-05-10 10:34:01 +0000330
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000331 if os.name == "nt":
332 cmd.debug = sys.executable.endswith("_d.exe")
333
334 cmd.build_lib = os.path.join(self.tmp_dir, 'build')
335 cmd.build_temp = os.path.join(self.tmp_dir, 'tempt')
336
337 # issue #5977 : distutils build_ext.get_outputs
338 # returns wrong result with --inplace
Tarek Ziadé4210c6e2009-05-14 20:20:47 +0000339 other_tmp_dir = os.path.realpath(self.mkdtemp())
340 old_wd = os.getcwd()
341 os.chdir(other_tmp_dir)
342 try:
343 cmd.inplace = 1
344 cmd.run()
345 so_file = cmd.get_outputs()[0]
346 finally:
347 os.chdir(old_wd)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000348 self.assertTrue(os.path.exists(so_file))
Barry Warsaw35f3a2c2010-09-03 18:30:30 +0000349 so_ext = sysconfig.get_config_var('SO')
350 self.assertTrue(so_file.endswith(so_ext))
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000351 so_dir = os.path.dirname(so_file)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000352 self.assertEqual(so_dir, other_tmp_dir)
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000353
354 cmd.inplace = 0
Tarek Ziadé36797272010-07-22 12:50:05 +0000355 cmd.compiler = None
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000356 cmd.run()
357 so_file = cmd.get_outputs()[0]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000358 self.assertTrue(os.path.exists(so_file))
Barry Warsaw35f3a2c2010-09-03 18:30:30 +0000359 self.assertTrue(so_file.endswith(so_ext))
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000360 so_dir = os.path.dirname(so_file)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000361 self.assertEqual(so_dir, cmd.build_lib)
Tarek Ziadéff0e5002009-05-12 17:14:01 +0000362
Tarek Ziadé822eb842009-05-19 16:22:57 +0000363 # inplace = 0, cmd.package = 'bar'
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000364 build_py = cmd.get_finalized_command('build_py')
365 build_py.package_dir = {'': 'bar'}
Tarek Ziadé822eb842009-05-19 16:22:57 +0000366 path = cmd.get_ext_fullpath('foo')
Tarek Ziadé0156f912009-06-29 16:19:22 +0000367 # checking that the last directory is the build_dir
Tarek Ziadé822eb842009-05-19 16:22:57 +0000368 path = os.path.split(path)[0]
Ezio Melottib3aedd42010-11-20 19:04:17 +0000369 self.assertEqual(path, cmd.build_lib)
Tarek Ziadé822eb842009-05-19 16:22:57 +0000370
371 # inplace = 1, cmd.package = 'bar'
372 cmd.inplace = 1
373 other_tmp_dir = os.path.realpath(self.mkdtemp())
374 old_wd = os.getcwd()
375 os.chdir(other_tmp_dir)
376 try:
377 path = cmd.get_ext_fullpath('foo')
378 finally:
379 os.chdir(old_wd)
380 # checking that the last directory is bar
381 path = os.path.split(path)[0]
382 lastdir = os.path.split(path)[-1]
Ezio Melottib3aedd42010-11-20 19:04:17 +0000383 self.assertEqual(lastdir, 'bar')
Tarek Ziadé822eb842009-05-19 16:22:57 +0000384
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000385 def test_ext_fullpath(self):
Tarek Ziadéb7815e32009-07-10 09:14:31 +0000386 ext = sysconfig.get_config_vars()['SO']
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000387 # building lxml.etree inplace
388 #etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c')
389 #etree_ext = Extension('lxml.etree', [etree_c])
390 #dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]})
391 dist = Distribution()
Tarek Ziadé0156f912009-06-29 16:19:22 +0000392 cmd = build_ext(dist)
393 cmd.inplace = 1
394 cmd.distribution.package_dir = {'': 'src'}
395 cmd.distribution.packages = ['lxml', 'lxml.html']
396 curdir = os.getcwd()
Tarek Ziadéb7815e32009-07-10 09:14:31 +0000397 wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext)
Tarek Ziadé0156f912009-06-29 16:19:22 +0000398 path = cmd.get_ext_fullpath('lxml.etree')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000399 self.assertEqual(wanted, path)
Tarek Ziadé0156f912009-06-29 16:19:22 +0000400
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000401 # building lxml.etree not inplace
402 cmd.inplace = 0
403 cmd.build_lib = os.path.join(curdir, 'tmpdir')
Tarek Ziadéb7815e32009-07-10 09:14:31 +0000404 wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext)
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000405 path = cmd.get_ext_fullpath('lxml.etree')
Ezio Melottib3aedd42010-11-20 19:04:17 +0000406 self.assertEqual(wanted, path)
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000407
408 # building twisted.runner.portmap not inplace
409 build_py = cmd.get_finalized_command('build_py')
410 build_py.package_dir = {}
411 cmd.distribution.packages = ['twisted', 'twisted.runner.portmap']
412 path = cmd.get_ext_fullpath('twisted.runner.portmap')
413 wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner',
Tarek Ziadéb7815e32009-07-10 09:14:31 +0000414 'portmap' + ext)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000415 self.assertEqual(wanted, path)
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000416
417 # building twisted.runner.portmap inplace
418 cmd.inplace = 1
419 path = cmd.get_ext_fullpath('twisted.runner.portmap')
Tarek Ziadéb7815e32009-07-10 09:14:31 +0000420 wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000421 self.assertEqual(wanted, path)
Tarek Ziadée10d6de2009-07-03 08:33:28 +0000422
Ronald Oussoren222e89a2011-05-15 16:46:11 +0200423
424 @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX')
425 def test_deployment_target(self):
426 self._try_compile_deployment_target()
427
428 orig_environ = os.environ
429 os.environ = orig_environ.copy()
430 self.addCleanup(setattr, os, 'environ', orig_environ)
431
432 os.environ['MACOSX_DEPLOYMENT_TARGET']='10.1'
433 self._try_compile_deployment_target()
434
435
436 def _try_compile_deployment_target(self):
437 deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c')
438
439 with open(deptarget_c, 'w') as fp:
440 fp.write(textwrap.dedent('''\
441 #include <AvailabilityMacros.h>
442
443 int dummy;
444
445 #if TARGET != MAC_OS_X_VERSION_MIN_REQUIRED
446 #error "Unexpected target"
447 #endif
448
449 '''))
450
451 target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
452 target = tuple(map(int, target.split('.')))
453 target = '%02d%01d0' % target
454
455 deptarget_ext = Extension(
456 'deptarget',
457 [deptarget_c],
458 extra_compile_args=['-DTARGET=%s'%(target,)],
459 )
460 dist = Distribution({
461 'name': 'deptarget',
462 'ext_modules': [deptarget_ext]
463 })
464 dist.package_dir = self.tmp_dir
465 cmd = build_ext(dist)
466 cmd.build_lib = self.tmp_dir
467 cmd.build_temp = self.tmp_dir
468
469 try:
470 old_stdout = sys.stdout
471 if not support.verbose:
472 # silence compiler output
473 sys.stdout = StringIO()
474 try:
475 cmd.ensure_finalized()
476 cmd.run()
477 finally:
478 sys.stdout = old_stdout
479
480 except CompileError:
481 self.fail("Wrong deployment target during compilation")
482
483
Georg Brandlb533e262008-05-25 18:19:30 +0000484def test_suite():
Neil Schemenauerd8f63bb2009-02-06 21:42:05 +0000485 src = _get_source_filename()
486 if not os.path.exists(src):
Georg Brandlb533e262008-05-25 18:19:30 +0000487 if support.verbose:
Neil Schemenauerd8f63bb2009-02-06 21:42:05 +0000488 print('test_build_ext: Cannot find source code (test'
489 ' must run in python build dir)')
Georg Brandlb533e262008-05-25 18:19:30 +0000490 return unittest.TestSuite()
491 else: return unittest.makeSuite(BuildExtTestCase)
492
493if __name__ == '__main__':
494 support.run_unittest(test_suite())