test_build_ext.py revision 1f70b878c4b890c66bdb90d8c9ddb59dee0b48df
188e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlimport sys 288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlimport os 388e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlfrom StringIO import StringIO 4a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussorenimport textwrap 588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 688e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlfrom distutils.core import Extension, Distribution 788e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlfrom distutils.command.build_ext import build_ext 8b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadéfrom distutils import sysconfig 91369900619d943d05342e7b781f1f3fb45ece4c9Tarek Ziadéfrom distutils.tests import support 10053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deilyfrom distutils.errors import (DistutilsSetupError, CompileError, 11053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily DistutilsPlatformError) 1288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 1388e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlimport unittest 1488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlfrom test import test_support 1588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 166f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé# http://bugs.python.org/issue4373 176f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé# Don't load the xx module more than once. 186f1d93149505c5b69578549a440175c5b32942b7Tarek ZiadéALREADY_TESTED = False 196f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé 20a52f1c62eb8cce9fb7f78687b854d1d8c4dbe39fNeil Schemenauer 219e47ce49a06075adbc391e04b4457707fa3892a7Tarek Ziadéclass BuildExtTestCase(support.TempdirManager, 229e47ce49a06075adbc391e04b4457707fa3892a7Tarek Ziadé support.LoggingSilencer, 239e47ce49a06075adbc391e04b4457707fa3892a7Tarek Ziadé unittest.TestCase): 2488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl def setUp(self): 25dda92f7f02dbc0de94112599129d9d93192278d9Tarek Ziadé super(BuildExtTestCase, self).setUp() 2604612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo self.tmp_dir = self.mkdtemp() 2704612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo self.xx_created = False 2804612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo sys.path.append(self.tmp_dir) 2904612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo self.addCleanup(sys.path.remove, self.tmp_dir) 30c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo if sys.version > "2.6": 31c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo import site 32c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo self.old_user_base = site.USER_BASE 33c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo site.USER_BASE = self.mkdtemp() 34c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo from distutils.command import build_ext 35c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo build_ext.USER_BASE = site.USER_BASE 36ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé 37ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé def tearDown(self): 3804612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo if self.xx_created: 39ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé test_support.unload('xx') 40ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé # XXX on Windows the test leaves a directory 41ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé # with xx module in TEMP 42ef253ac84e6fd11770ff78c56015a0e61c991fc4Tarek Ziadé super(BuildExtTestCase, self).tearDown() 4388e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 4488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl def test_build_ext(self): 456f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé global ALREADY_TESTED 4604612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo support.copy_xxmodule_c(self.tmp_dir) 4704612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo self.xx_created = True 4888e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') 4988e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl xx_ext = Extension('xx', [xx_c]) 5088e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) 5188e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl dist.package_dir = self.tmp_dir 5288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl cmd = build_ext(dist) 5304612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo support.fixup_build_ext(cmd) 5488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl cmd.build_lib = self.tmp_dir 5588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl cmd.build_temp = self.tmp_dir 5688e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 5788e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl old_stdout = sys.stdout 5888e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl if not test_support.verbose: 5988e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl # silence compiler output 6088e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl sys.stdout = StringIO() 6188e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl try: 6288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl cmd.ensure_finalized() 6388e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl cmd.run() 6488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl finally: 6588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl sys.stdout = old_stdout 6688e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 676f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé if ALREADY_TESTED: 6857bc6da7c4327aa870fbf5292c1b05a9ac3bfe19Serhiy Storchaka self.skipTest('Already tested in %s' % ALREADY_TESTED) 696f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé else: 7057bc6da7c4327aa870fbf5292c1b05a9ac3bfe19Serhiy Storchaka ALREADY_TESTED = type(self).__name__ 716f1d93149505c5b69578549a440175c5b32942b7Tarek Ziadé 7288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl import xx 7388e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 7488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl for attr in ('error', 'foo', 'new', 'roj'): 752623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertTrue(hasattr(xx, attr)) 7688e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 772623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(xx.foo(2, 5), 7) 782623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(xx.foo(13,15), 28) 792623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(xx.new().demo(), None) 8072121c6c302d0e177d3f738f51685e0664343cccSerhiy Storchaka if test_support.HAVE_DOCSTRINGS: 8172121c6c302d0e177d3f738f51685e0664343cccSerhiy Storchaka doc = 'This is a template module just for instruction.' 8272121c6c302d0e177d3f738f51685e0664343cccSerhiy Storchaka self.assertEqual(xx.__doc__, doc) 8325a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertIsInstance(xx.Null(), xx.Null) 8425a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertIsInstance(xx.Str(), xx.Str) 8588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 860d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé def test_solaris_enable_shared(self): 870d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé dist = Distribution({'name': 'xx'}) 880d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé cmd = build_ext(dist) 890d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé old = sys.platform 900d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé 910d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé sys.platform = 'sunos' # fooling finalize_options 92b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé from distutils.sysconfig import _config_vars 93b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé old_var = _config_vars.get('Py_ENABLE_SHARED') 94b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé _config_vars['Py_ENABLE_SHARED'] = 1 950d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé try: 960d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé cmd.ensure_finalized() 970d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé finally: 980d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé sys.platform = old 990d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé if old_var is None: 100b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé del _config_vars['Py_ENABLE_SHARED'] 1010d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé else: 102b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé _config_vars['Py_ENABLE_SHARED'] = old_var 1030d4fd3493eb95a49ac0dee5c8607b1426432ab83Tarek Ziadé 104972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # make sure we get some library dirs under solaris 10525a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertGreater(len(cmd.library_dirs), 0) 1069e47ce49a06075adbc391e04b4457707fa3892a7Tarek Ziadé 10757bc6da7c4327aa870fbf5292c1b05a9ac3bfe19Serhiy Storchaka @unittest.skipIf(sys.version < '2.6', 10857bc6da7c4327aa870fbf5292c1b05a9ac3bfe19Serhiy Storchaka 'site.USER_SITE was introduced in 2.6') 109c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo def test_user_site(self): 110c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo import site 111c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo dist = Distribution({'name': 'xx'}) 112c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo cmd = build_ext(dist) 113c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 114c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo # making sure the user option is there 115c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo options = [name for name, short, label in 116c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo cmd.user_options] 117c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo self.assertIn('user', options) 118c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 119c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo # setting a value 120c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo cmd.user = 1 121c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 122c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo # setting user based lib and include 123c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo lib = os.path.join(site.USER_BASE, 'lib') 124c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo incl = os.path.join(site.USER_BASE, 'include') 125c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo os.mkdir(lib) 126c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo os.mkdir(incl) 127c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 128c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo cmd.ensure_finalized() 129c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 130c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo # see if include_dirs and library_dirs were set 131c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo self.assertIn(lib, cmd.library_dirs) 132c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo self.assertIn(lib, cmd.rpath) 133c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo self.assertIn(incl, cmd.include_dirs) 134c811fb2d56e3c5847ac5c5a6d59bbc8b75e8effaÉric Araujo 135d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé def test_finalize_options(self): 136d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # Make sure Python's include directories (for Python.h, pyconfig.h, 137d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # etc.) are in the include search path. 138b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé modules = [Extension('foo', ['xxx'])] 139d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé dist = Distribution({'name': 'xx', 'ext_modules': modules}) 140d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 141d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 142d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 143b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé py_include = sysconfig.get_python_inc() 14425a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertIn(py_include, cmd.include_dirs) 145d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 146b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé plat_py_include = sysconfig.get_python_inc(plat_specific=1) 14725a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertIn(plat_py_include, cmd.include_dirs) 148d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 149d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure cmd.libraries is turned into a list 150d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # if it's a string 151d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 152e897a7472ded10a29ffcf046d021cd7fdc1ac94eÉric Araujo cmd.libraries = 'my_lib, other_lib lastlib' 153d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 154e897a7472ded10a29ffcf046d021cd7fdc1ac94eÉric Araujo self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib']) 155d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 156d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure cmd.library_dirs is turned into a list 157d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # if it's a string 158d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 159e897a7472ded10a29ffcf046d021cd7fdc1ac94eÉric Araujo cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep 160d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 161c82da813c1406bc7e3878bf1d960d4765bcb0d89Éric Araujo self.assertIn('my_lib_dir', cmd.library_dirs) 162c82da813c1406bc7e3878bf1d960d4765bcb0d89Éric Araujo self.assertIn('other_lib_dir', cmd.library_dirs) 163d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 164d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure rpath is turned into a list 165e897a7472ded10a29ffcf046d021cd7fdc1ac94eÉric Araujo # if it's a string 166d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 167e897a7472ded10a29ffcf046d021cd7fdc1ac94eÉric Araujo cmd.rpath = 'one%stwo' % os.pathsep 168d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 1692623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.rpath, ['one', 'two']) 170d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 171d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # XXX more tests to perform for win32 172d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 173d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure define is turned into 2-tuples 174d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # strings if they are ','-separated strings 175d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 176d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.define = 'one,two' 177d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 1782623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) 179d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 180d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure undef is turned into a list of 181d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # strings if they are ','-separated strings 182d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 183d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.undef = 'one,two' 184d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 1852623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.undef, ['one', 'two']) 186d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 187d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # make sure swig_opts is turned into a list 188d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 189d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.swig_opts = None 190d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 1912623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.swig_opts, []) 192d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 193d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 194d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.swig_opts = '1 2' 195d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 1962623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.swig_opts, ['1', '2']) 197d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 198d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé def test_check_extensions_list(self): 199d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé dist = Distribution() 200d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 201d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.finalize_options() 202d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 203d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé #'extensions' option must be a list of Extension instances 204d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, 'foo') 205d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 206d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # each element of 'ext_modules' option must be an 207d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # Extension instance or 2-tuple 208d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts = [('bar', 'foo', 'bar'), 'foo'] 209d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 210d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 211d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # first element of each tuple in 'ext_modules' 212d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # must be the extension name (a string) and match 213d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # a python dotted-separated name 214d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts = [('foo-bar', '')] 215d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 216d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 217d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # second element of each tuple in 'ext_modules' 218d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # must be a ary (build info) 219d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts = [('foo.bar', '')] 220d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 221d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 222d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # ok this one should pass 223d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', 224d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 'some': 'bar'})] 225d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.check_extensions_list(exts) 226d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé ext = exts[0] 22725a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertIsInstance(ext, Extension) 228d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 229d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # check_extensions_list adds in ext the values passed 230d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # when they are in ('include_dirs', 'library_dirs', 'libraries' 231d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # 'extra_objects', 'extra_compile_args', 'extra_link_args') 2322623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(ext.libraries, 'foo') 23325a23efcda0dc3e245eefa8c9a3f96b4baee6303Serhiy Storchaka self.assertFalse(hasattr(ext, 'some')) 234d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 235d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé # 'macros' element of build info dict must be 1- or 2-tuple 236d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', 237d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 'some': 'bar', 'macros': [('1', '2', '3'), 'foo']})] 238d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) 239d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 240d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé exts[0][1]['macros'] = [('1', '2'), ('3',)] 241d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.check_extensions_list(exts) 2422623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(exts[0].undef_macros, ['3']) 2432623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(exts[0].define_macros, [('1', '2')]) 244d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 245d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé def test_get_source_files(self): 246b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé modules = [Extension('foo', ['xxx'])] 247d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé dist = Distribution({'name': 'xx', 'ext_modules': modules}) 248d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 249d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.ensure_finalized() 2502623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.get_source_files(), ['xxx']) 251d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 252972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé def test_compiler_option(self): 253972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # cmd.compiler is an option and 254972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # should not be overriden by a compiler instance 255972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # when the command is run 256972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé dist = Distribution() 257972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd = build_ext(dist) 258972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.compiler = 'unix' 259972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.ensure_finalized() 260972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.run() 2612623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(cmd.compiler, 'unix') 262972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé 263d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé def test_get_outputs(self): 264972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé tmp_dir = self.mkdtemp() 265972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé c_file = os.path.join(tmp_dir, 'foo.c') 2666633a6606b935fa1160293029f59eb892e7aed4fHirokazu Yamamoto self.write_file(c_file, 'void initfoo(void) {};\n') 267b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext = Extension('foo', [c_file]) 268972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé dist = Distribution({'name': 'xx', 269972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé 'ext_modules': [ext]}) 270d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd = build_ext(dist) 27104612d60929d5cda8d4cd215dfa2fc050d20b530Éric Araujo support.fixup_build_ext(cmd) 272d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé cmd.ensure_finalized() 2732623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(len(cmd.get_outputs()), 1) 274d5d83424d235783ddaa1a98a82278805d05c437bTarek Ziadé 275972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.build_lib = os.path.join(self.tmp_dir, 'build') 276972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.build_temp = os.path.join(self.tmp_dir, 'tempt') 277972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé 278972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # issue #5977 : distutils build_ext.get_outputs 279972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé # returns wrong result with --inplace 280cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé other_tmp_dir = os.path.realpath(self.mkdtemp()) 281cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé old_wd = os.getcwd() 282cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé os.chdir(other_tmp_dir) 283cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé try: 284cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé cmd.inplace = 1 285cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé cmd.run() 286cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé so_file = cmd.get_outputs()[0] 287cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé finally: 288cbb4f9ef58ec7673f7c64b16496879b914b0972aTarek Ziadé os.chdir(old_wd) 2892623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertTrue(os.path.exists(so_file)) 2902623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(os.path.splitext(so_file)[-1], 2912623a37852153363335956afab010cb0beb7e74eEzio Melotti sysconfig.get_config_var('SO')) 292972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé so_dir = os.path.dirname(so_file) 2932623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(so_dir, other_tmp_dir) 294b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.compiler = None 295972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.inplace = 0 296972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé cmd.run() 297972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé so_file = cmd.get_outputs()[0] 2982623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertTrue(os.path.exists(so_file)) 2992623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(os.path.splitext(so_file)[-1], 3002623a37852153363335956afab010cb0beb7e74eEzio Melotti sysconfig.get_config_var('SO')) 301972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé so_dir = os.path.dirname(so_file) 3022623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(so_dir, cmd.build_lib) 303972480d999b83f5d245cb4662122e9d25c54701eTarek Ziadé 3047d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé # inplace = 0, cmd.package = 'bar' 30565ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé build_py = cmd.get_finalized_command('build_py') 30665ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé build_py.package_dir = {'': 'bar'} 3077d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé path = cmd.get_ext_fullpath('foo') 3083fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé # checking that the last directory is the build_dir 3097d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé path = os.path.split(path)[0] 3102623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(path, cmd.build_lib) 3117d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé 3127d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé # inplace = 1, cmd.package = 'bar' 3137d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé cmd.inplace = 1 3147d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé other_tmp_dir = os.path.realpath(self.mkdtemp()) 3157d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé old_wd = os.getcwd() 3167d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé os.chdir(other_tmp_dir) 3177d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé try: 3187d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé path = cmd.get_ext_fullpath('foo') 3197d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé finally: 3207d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé os.chdir(old_wd) 3217d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé # checking that the last directory is bar 3227d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé path = os.path.split(path)[0] 3237d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé lastdir = os.path.split(path)[-1] 3242623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(lastdir, 'bar') 3257d7127dd84189bf9325ef3fc5f3c18359fa34f30Tarek Ziadé 32665ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé def test_ext_fullpath(self): 3278c40001175f354b6e05d38a7f403afb5686c6013Tarek Ziadé ext = sysconfig.get_config_vars()['SO'] 32865ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé dist = Distribution() 3293fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé cmd = build_ext(dist) 3303fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé cmd.inplace = 1 3313fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé cmd.distribution.package_dir = {'': 'src'} 3323fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé cmd.distribution.packages = ['lxml', 'lxml.html'] 3333fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé curdir = os.getcwd() 3348c40001175f354b6e05d38a7f403afb5686c6013Tarek Ziadé wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 3353fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé path = cmd.get_ext_fullpath('lxml.etree') 3362623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 3373fbcc60eb859b00f4310e028da0ba6edba35f7c8Tarek Ziadé 33865ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé # building lxml.etree not inplace 33965ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé cmd.inplace = 0 34065ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé cmd.build_lib = os.path.join(curdir, 'tmpdir') 3418c40001175f354b6e05d38a7f403afb5686c6013Tarek Ziadé wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) 34265ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé path = cmd.get_ext_fullpath('lxml.etree') 3432623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 34465ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé 34565ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé # building twisted.runner.portmap not inplace 34665ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé build_py = cmd.get_finalized_command('build_py') 34765ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé build_py.package_dir = {} 34865ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] 34965ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé path = cmd.get_ext_fullpath('twisted.runner.portmap') 35065ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', 3518c40001175f354b6e05d38a7f403afb5686c6013Tarek Ziadé 'portmap' + ext) 3522623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 35365ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé 35465ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé # building twisted.runner.portmap inplace 35565ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé cmd.inplace = 1 35665ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé path = cmd.get_ext_fullpath('twisted.runner.portmap') 3578c40001175f354b6e05d38a7f403afb5686c6013Tarek Ziadé wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) 3582623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 35965ec61ed06d7b28da05fa834c65ffa7c13005d2bTarek Ziadé 360b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé def test_build_ext_inplace(self): 361b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') 362b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé etree_ext = Extension('lxml.etree', [etree_c]) 363b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) 364e670e5ad5b7ef6b464fb264b688d96b9b9f71b53Tarek Ziadé cmd = build_ext(dist) 365b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.ensure_finalized() 366b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.inplace = 1 367b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.distribution.package_dir = {'': 'src'} 368b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.distribution.packages = ['lxml', 'lxml.html'] 369b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé curdir = os.getcwd() 370b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext = sysconfig.get_config_var("SO") 371b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 372b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé path = cmd.get_ext_fullpath('lxml.etree') 3732623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 374b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé 375b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé def test_setuptools_compat(self): 3765501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé import distutils.core, distutils.extension, distutils.command.build_ext 3775501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé saved_ext = distutils.extension.Extension 3785501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé try: 3793f5d146323fe306de7ddccb2506a7161554cc330Florent Xicluna # on some platforms, it loads the deprecated "dl" module 3803f5d146323fe306de7ddccb2506a7161554cc330Florent Xicluna test_support.import_module('setuptools_build_ext', deprecated=True) 3813f5d146323fe306de7ddccb2506a7161554cc330Florent Xicluna 3825501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé # theses import patch Distutils' Extension class 3835501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé from setuptools_build_ext import build_ext as setuptools_build_ext 3845501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé from setuptools_extension import Extension 3855501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé 3865501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') 3875501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé etree_ext = Extension('lxml.etree', [etree_c]) 3885501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) 3895501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé cmd = setuptools_build_ext(dist) 3905501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé cmd.ensure_finalized() 3915501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé cmd.inplace = 1 3925501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé cmd.distribution.package_dir = {'': 'src'} 3935501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé cmd.distribution.packages = ['lxml', 'lxml.html'] 3945501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé curdir = os.getcwd() 3955501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé ext = sysconfig.get_config_var("SO") 3965501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) 3975501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé path = cmd.get_ext_fullpath('lxml.etree') 3982623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(wanted, path) 3995501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé finally: 4005501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé # restoring Distutils' Extension class otherwise its broken 4015501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé distutils.extension.Extension = saved_ext 4025501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé distutils.core.Extension = saved_ext 4035501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé distutils.command.build_ext.Extension = saved_ext 404b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé 405b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé def test_build_ext_path_with_os_sep(self): 406b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé dist = Distribution({'name': 'UpdateManager'}) 407b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd = build_ext(dist) 408b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.ensure_finalized() 409b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext = sysconfig.get_config_var("SO") 410b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext_name = os.path.join('UpdateManager', 'fdsend') 411b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext_path = cmd.get_ext_fullpath(ext_name) 412b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) 4132623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(ext_path, wanted) 414b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé 41557bc6da7c4327aa870fbf5292c1b05a9ac3bfe19Serhiy Storchaka @unittest.skipUnless(sys.platform == 'win32', 'these tests require Windows') 416b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé def test_build_ext_path_cross_platform(self): 417b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé dist = Distribution({'name': 'UpdateManager'}) 418b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd = build_ext(dist) 419b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé cmd.ensure_finalized() 420b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext = sysconfig.get_config_var("SO") 421b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé # this needs to work even under win32 422b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext_name = 'UpdateManager/fdsend' 423b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé ext_path = cmd.get_ext_fullpath(ext_name) 424b30868a391b85d24b7d1abe41c137a9d75bfcebcTarek Ziadé wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) 4252623a37852153363335956afab010cb0beb7e74eEzio Melotti self.assertEqual(ext_path, wanted) 426e670e5ad5b7ef6b464fb264b688d96b9b9f71b53Tarek Ziadé 427a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') 428053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily def test_deployment_target_default(self): 429053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # Issue 9516: Test that, in the absence of the environment variable, 430053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # an extension module is compiled with the same deployment target as 431053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # the interpreter. 432053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily self._try_compile_deployment_target('==', None) 433a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 434053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') 435053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily def test_deployment_target_too_low(self): 436053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # Issue 9516: Test that an extension module is not allowed to be 437053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # compiled with a deployment target less than that of the interpreter. 438053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily self.assertRaises(DistutilsPlatformError, 439053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily self._try_compile_deployment_target, '>', '10.1') 440053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily 441053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') 442053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily def test_deployment_target_higher_ok(self): 443053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # Issue 9516: Test that an extension module can be compiled with a 444053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # deployment target higher than that of the interpreter: the ext 445053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # module may depend on some newer OS feature. 446053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') 447053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily if deptarget: 448053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # increment the minor version number (i.e. 10.6 -> 10.7) 449053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily deptarget = [int(x) for x in deptarget.split('.')] 450053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily deptarget[-1] += 1 451053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily deptarget = '.'.join(str(i) for i in deptarget) 452053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily self._try_compile_deployment_target('<', deptarget) 453053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily 454053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily def _try_compile_deployment_target(self, operator, target): 455a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren orig_environ = os.environ 456a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren os.environ = orig_environ.copy() 457a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren self.addCleanup(setattr, os, 'environ', orig_environ) 458a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 459053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily if target is None: 460053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): 461053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily del os.environ['MACOSX_DEPLOYMENT_TARGET'] 462053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily else: 463053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily os.environ['MACOSX_DEPLOYMENT_TARGET'] = target 464a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 465a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') 466a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 467a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren with open(deptarget_c, 'w') as fp: 468a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren fp.write(textwrap.dedent('''\ 469a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren #include <AvailabilityMacros.h> 470a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 471a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren int dummy; 472a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 473053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED 474053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily #else 475a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren #error "Unexpected target" 476053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily #endif 477a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 478053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily ''' % operator)) 479a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 480053c6ad6b7ee88d9076a91f47aa53dc7155d00ceNed Deily # get the deployment target that the interpreter was built with 481a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') 4821f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily target = tuple(map(int, target.split('.')[0:2])) 4831f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily # format the target value as defined in the Apple 4841f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily # Availability Macros. We can't use the macro names since 4851f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily # at least one value we test with will not exist yet. 4861f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily if target[1] < 10: 4871f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily # for 10.1 through 10.9.x -> "10n0" 4881f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily target = '%02d%01d0' % target 4891f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily else: 4901f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily # for 10.10 and beyond -> "10nn00" 4911f70b878c4b890c66bdb90d8c9ddb59dee0b48dfNed Deily target = '%02d%02d00' % target 492a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren deptarget_ext = Extension( 493a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 'deptarget', 494a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren [deptarget_c], 495a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren extra_compile_args=['-DTARGET=%s'%(target,)], 496a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren ) 497a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren dist = Distribution({ 498a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 'name': 'deptarget', 499a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 'ext_modules': [deptarget_ext] 500a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren }) 501a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren dist.package_dir = self.tmp_dir 502a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren cmd = build_ext(dist) 503a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren cmd.build_lib = self.tmp_dir 504a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren cmd.build_temp = self.tmp_dir 505a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 506a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren try: 507a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren cmd.ensure_finalized() 508a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren cmd.run() 509a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren except CompileError: 510a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren self.fail("Wrong deployment target during compilation") 511a70286b71d6b98c14275c26f6ca1f0507c1bc56bRonald Oussoren 51288e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandldef test_suite(): 5135501e6a7da371a851478a939d974ecebbc84e2ddTarek Ziadé return unittest.makeSuite(BuildExtTestCase) 51488e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl 51588e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandlif __name__ == '__main__': 51688e2acf038b717199655d8206e4a5deaa0a0eb1aGeorg Brandl test_support.run_unittest(test_suite()) 517