17db96d56Sopenharmony_ci"""Tests for distutils.sysconfig.""" 27db96d56Sopenharmony_ciimport contextlib 37db96d56Sopenharmony_ciimport os 47db96d56Sopenharmony_ciimport shutil 57db96d56Sopenharmony_ciimport subprocess 67db96d56Sopenharmony_ciimport sys 77db96d56Sopenharmony_ciimport textwrap 87db96d56Sopenharmony_ciimport unittest 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_cifrom distutils import sysconfig 117db96d56Sopenharmony_cifrom distutils.ccompiler import get_default_compiler 127db96d56Sopenharmony_cifrom distutils.tests import support 137db96d56Sopenharmony_cifrom test.support import run_unittest, swap_item, requires_subprocess, is_wasi 147db96d56Sopenharmony_cifrom test.support.os_helper import TESTFN 157db96d56Sopenharmony_cifrom test.support.warnings_helper import check_warnings 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ciclass SysconfigTestCase(support.EnvironGuard, unittest.TestCase): 197db96d56Sopenharmony_ci def setUp(self): 207db96d56Sopenharmony_ci super(SysconfigTestCase, self).setUp() 217db96d56Sopenharmony_ci self.makefile = None 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci def tearDown(self): 247db96d56Sopenharmony_ci if self.makefile is not None: 257db96d56Sopenharmony_ci os.unlink(self.makefile) 267db96d56Sopenharmony_ci self.cleanup_testfn() 277db96d56Sopenharmony_ci super(SysconfigTestCase, self).tearDown() 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci def cleanup_testfn(self): 307db96d56Sopenharmony_ci if os.path.isfile(TESTFN): 317db96d56Sopenharmony_ci os.remove(TESTFN) 327db96d56Sopenharmony_ci elif os.path.isdir(TESTFN): 337db96d56Sopenharmony_ci shutil.rmtree(TESTFN) 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") 367db96d56Sopenharmony_ci def test_get_config_h_filename(self): 377db96d56Sopenharmony_ci config_h = sysconfig.get_config_h_filename() 387db96d56Sopenharmony_ci self.assertTrue(os.path.isfile(config_h), config_h) 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci def test_get_python_lib(self): 417db96d56Sopenharmony_ci # XXX doesn't work on Linux when Python was never installed before 427db96d56Sopenharmony_ci #self.assertTrue(os.path.isdir(lib_dir), lib_dir) 437db96d56Sopenharmony_ci # test for pythonxx.lib? 447db96d56Sopenharmony_ci self.assertNotEqual(sysconfig.get_python_lib(), 457db96d56Sopenharmony_ci sysconfig.get_python_lib(prefix=TESTFN)) 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci def test_get_config_vars(self): 487db96d56Sopenharmony_ci cvars = sysconfig.get_config_vars() 497db96d56Sopenharmony_ci self.assertIsInstance(cvars, dict) 507db96d56Sopenharmony_ci self.assertTrue(cvars) 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") 537db96d56Sopenharmony_ci def test_srcdir(self): 547db96d56Sopenharmony_ci # See Issues #15322, #15364. 557db96d56Sopenharmony_ci srcdir = sysconfig.get_config_var('srcdir') 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci self.assertTrue(os.path.isabs(srcdir), srcdir) 587db96d56Sopenharmony_ci self.assertTrue(os.path.isdir(srcdir), srcdir) 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci if sysconfig.python_build: 617db96d56Sopenharmony_ci # The python executable has not been installed so srcdir 627db96d56Sopenharmony_ci # should be a full source checkout. 637db96d56Sopenharmony_ci Python_h = os.path.join(srcdir, 'Include', 'Python.h') 647db96d56Sopenharmony_ci self.assertTrue(os.path.exists(Python_h), Python_h) 657db96d56Sopenharmony_ci # <srcdir>/PC/pyconfig.h always exists even if unused on POSIX. 667db96d56Sopenharmony_ci pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') 677db96d56Sopenharmony_ci self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) 687db96d56Sopenharmony_ci pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') 697db96d56Sopenharmony_ci self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) 707db96d56Sopenharmony_ci elif os.name == 'posix': 717db96d56Sopenharmony_ci self.assertEqual( 727db96d56Sopenharmony_ci os.path.dirname(sysconfig.get_makefile_filename()), 737db96d56Sopenharmony_ci srcdir) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci def test_srcdir_independent_of_cwd(self): 767db96d56Sopenharmony_ci # srcdir should be independent of the current working directory 777db96d56Sopenharmony_ci # See Issues #15322, #15364. 787db96d56Sopenharmony_ci srcdir = sysconfig.get_config_var('srcdir') 797db96d56Sopenharmony_ci cwd = os.getcwd() 807db96d56Sopenharmony_ci try: 817db96d56Sopenharmony_ci os.chdir('..') 827db96d56Sopenharmony_ci srcdir2 = sysconfig.get_config_var('srcdir') 837db96d56Sopenharmony_ci finally: 847db96d56Sopenharmony_ci os.chdir(cwd) 857db96d56Sopenharmony_ci self.assertEqual(srcdir, srcdir2) 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci def customize_compiler(self): 887db96d56Sopenharmony_ci # make sure AR gets caught 897db96d56Sopenharmony_ci class compiler: 907db96d56Sopenharmony_ci compiler_type = 'unix' 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci def set_executables(self, **kw): 937db96d56Sopenharmony_ci self.exes = kw 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci sysconfig_vars = { 967db96d56Sopenharmony_ci 'AR': 'sc_ar', 977db96d56Sopenharmony_ci 'CC': 'sc_cc', 987db96d56Sopenharmony_ci 'CXX': 'sc_cxx', 997db96d56Sopenharmony_ci 'ARFLAGS': '--sc-arflags', 1007db96d56Sopenharmony_ci 'CFLAGS': '--sc-cflags', 1017db96d56Sopenharmony_ci 'CCSHARED': '--sc-ccshared', 1027db96d56Sopenharmony_ci 'LDSHARED': 'sc_ldshared', 1037db96d56Sopenharmony_ci 'SHLIB_SUFFIX': 'sc_shutil_suffix', 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci # On macOS, disable _osx_support.customize_compiler() 1067db96d56Sopenharmony_ci 'CUSTOMIZED_OSX_COMPILER': 'True', 1077db96d56Sopenharmony_ci } 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci comp = compiler() 1107db96d56Sopenharmony_ci with contextlib.ExitStack() as cm: 1117db96d56Sopenharmony_ci for key, value in sysconfig_vars.items(): 1127db96d56Sopenharmony_ci cm.enter_context(swap_item(sysconfig._config_vars, key, value)) 1137db96d56Sopenharmony_ci sysconfig.customize_compiler(comp) 1147db96d56Sopenharmony_ci 1157db96d56Sopenharmony_ci return comp 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci @unittest.skipUnless(get_default_compiler() == 'unix', 1187db96d56Sopenharmony_ci 'not testing if default compiler is not unix') 1197db96d56Sopenharmony_ci def test_customize_compiler(self): 1207db96d56Sopenharmony_ci # Make sure that sysconfig._config_vars is initialized 1217db96d56Sopenharmony_ci sysconfig.get_config_vars() 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_ci os.environ['AR'] = 'env_ar' 1247db96d56Sopenharmony_ci os.environ['CC'] = 'env_cc' 1257db96d56Sopenharmony_ci os.environ['CPP'] = 'env_cpp' 1267db96d56Sopenharmony_ci os.environ['CXX'] = 'env_cxx --env-cxx-flags' 1277db96d56Sopenharmony_ci os.environ['LDSHARED'] = 'env_ldshared' 1287db96d56Sopenharmony_ci os.environ['LDFLAGS'] = '--env-ldflags' 1297db96d56Sopenharmony_ci os.environ['ARFLAGS'] = '--env-arflags' 1307db96d56Sopenharmony_ci os.environ['CFLAGS'] = '--env-cflags' 1317db96d56Sopenharmony_ci os.environ['CPPFLAGS'] = '--env-cppflags' 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci comp = self.customize_compiler() 1347db96d56Sopenharmony_ci self.assertEqual(comp.exes['archiver'], 1357db96d56Sopenharmony_ci 'env_ar --env-arflags') 1367db96d56Sopenharmony_ci self.assertEqual(comp.exes['preprocessor'], 1377db96d56Sopenharmony_ci 'env_cpp --env-cppflags') 1387db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler'], 1397db96d56Sopenharmony_ci 'env_cc --sc-cflags --env-cflags --env-cppflags') 1407db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler_so'], 1417db96d56Sopenharmony_ci ('env_cc --sc-cflags ' 1427db96d56Sopenharmony_ci '--env-cflags ''--env-cppflags --sc-ccshared')) 1437db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler_cxx'], 1447db96d56Sopenharmony_ci 'env_cxx --env-cxx-flags') 1457db96d56Sopenharmony_ci self.assertEqual(comp.exes['linker_exe'], 1467db96d56Sopenharmony_ci 'env_cc') 1477db96d56Sopenharmony_ci self.assertEqual(comp.exes['linker_so'], 1487db96d56Sopenharmony_ci ('env_ldshared --env-ldflags --env-cflags' 1497db96d56Sopenharmony_ci ' --env-cppflags')) 1507db96d56Sopenharmony_ci self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci del os.environ['AR'] 1537db96d56Sopenharmony_ci del os.environ['CC'] 1547db96d56Sopenharmony_ci del os.environ['CPP'] 1557db96d56Sopenharmony_ci del os.environ['CXX'] 1567db96d56Sopenharmony_ci del os.environ['LDSHARED'] 1577db96d56Sopenharmony_ci del os.environ['LDFLAGS'] 1587db96d56Sopenharmony_ci del os.environ['ARFLAGS'] 1597db96d56Sopenharmony_ci del os.environ['CFLAGS'] 1607db96d56Sopenharmony_ci del os.environ['CPPFLAGS'] 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci comp = self.customize_compiler() 1637db96d56Sopenharmony_ci self.assertEqual(comp.exes['archiver'], 1647db96d56Sopenharmony_ci 'sc_ar --sc-arflags') 1657db96d56Sopenharmony_ci self.assertEqual(comp.exes['preprocessor'], 1667db96d56Sopenharmony_ci 'sc_cc -E') 1677db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler'], 1687db96d56Sopenharmony_ci 'sc_cc --sc-cflags') 1697db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler_so'], 1707db96d56Sopenharmony_ci 'sc_cc --sc-cflags --sc-ccshared') 1717db96d56Sopenharmony_ci self.assertEqual(comp.exes['compiler_cxx'], 1727db96d56Sopenharmony_ci 'sc_cxx') 1737db96d56Sopenharmony_ci self.assertEqual(comp.exes['linker_exe'], 1747db96d56Sopenharmony_ci 'sc_cc') 1757db96d56Sopenharmony_ci self.assertEqual(comp.exes['linker_so'], 1767db96d56Sopenharmony_ci 'sc_ldshared') 1777db96d56Sopenharmony_ci self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci def test_parse_makefile_base(self): 1807db96d56Sopenharmony_ci self.makefile = TESTFN 1817db96d56Sopenharmony_ci fd = open(self.makefile, 'w') 1827db96d56Sopenharmony_ci try: 1837db96d56Sopenharmony_ci fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB'" '\n') 1847db96d56Sopenharmony_ci fd.write('VAR=$OTHER\nOTHER=foo') 1857db96d56Sopenharmony_ci finally: 1867db96d56Sopenharmony_ci fd.close() 1877db96d56Sopenharmony_ci d = sysconfig.parse_makefile(self.makefile) 1887db96d56Sopenharmony_ci self.assertEqual(d, {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'", 1897db96d56Sopenharmony_ci 'OTHER': 'foo'}) 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci def test_parse_makefile_literal_dollar(self): 1927db96d56Sopenharmony_ci self.makefile = TESTFN 1937db96d56Sopenharmony_ci fd = open(self.makefile, 'w') 1947db96d56Sopenharmony_ci try: 1957db96d56Sopenharmony_ci fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=\$$LIB'" '\n') 1967db96d56Sopenharmony_ci fd.write('VAR=$OTHER\nOTHER=foo') 1977db96d56Sopenharmony_ci finally: 1987db96d56Sopenharmony_ci fd.close() 1997db96d56Sopenharmony_ci d = sysconfig.parse_makefile(self.makefile) 2007db96d56Sopenharmony_ci self.assertEqual(d, {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'", 2017db96d56Sopenharmony_ci 'OTHER': 'foo'}) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci def test_sysconfig_module(self): 2057db96d56Sopenharmony_ci import sysconfig as global_sysconfig 2067db96d56Sopenharmony_ci self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), 2077db96d56Sopenharmony_ci sysconfig.get_config_var('CFLAGS')) 2087db96d56Sopenharmony_ci self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), 2097db96d56Sopenharmony_ci sysconfig.get_config_var('LDFLAGS')) 2107db96d56Sopenharmony_ci 2117db96d56Sopenharmony_ci @unittest.skipIf(sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'), 2127db96d56Sopenharmony_ci 'compiler flags customized') 2137db96d56Sopenharmony_ci def test_sysconfig_compiler_vars(self): 2147db96d56Sopenharmony_ci # On OS X, binary installers support extension module building on 2157db96d56Sopenharmony_ci # various levels of the operating system with differing Xcode 2167db96d56Sopenharmony_ci # configurations. This requires customization of some of the 2177db96d56Sopenharmony_ci # compiler configuration directives to suit the environment on 2187db96d56Sopenharmony_ci # the installed machine. Some of these customizations may require 2197db96d56Sopenharmony_ci # running external programs and, so, are deferred until needed by 2207db96d56Sopenharmony_ci # the first extension module build. With Python 3.3, only 2217db96d56Sopenharmony_ci # the Distutils version of sysconfig is used for extension module 2227db96d56Sopenharmony_ci # builds, which happens earlier in the Distutils tests. This may 2237db96d56Sopenharmony_ci # cause the following tests to fail since no tests have caused 2247db96d56Sopenharmony_ci # the global version of sysconfig to call the customization yet. 2257db96d56Sopenharmony_ci # The solution for now is to simply skip this test in this case. 2267db96d56Sopenharmony_ci # The longer-term solution is to only have one version of sysconfig. 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci import sysconfig as global_sysconfig 2297db96d56Sopenharmony_ci if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): 2307db96d56Sopenharmony_ci self.skipTest('compiler flags customized') 2317db96d56Sopenharmony_ci self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), 2327db96d56Sopenharmony_ci sysconfig.get_config_var('LDSHARED')) 2337db96d56Sopenharmony_ci self.assertEqual(global_sysconfig.get_config_var('CC'), 2347db96d56Sopenharmony_ci sysconfig.get_config_var('CC')) 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ci @requires_subprocess() 2377db96d56Sopenharmony_ci def test_customize_compiler_before_get_config_vars(self): 2387db96d56Sopenharmony_ci # Issue #21923: test that a Distribution compiler 2397db96d56Sopenharmony_ci # instance can be called without an explicit call to 2407db96d56Sopenharmony_ci # get_config_vars(). 2417db96d56Sopenharmony_ci with open(TESTFN, 'w') as f: 2427db96d56Sopenharmony_ci f.writelines(textwrap.dedent('''\ 2437db96d56Sopenharmony_ci from distutils.core import Distribution 2447db96d56Sopenharmony_ci config = Distribution().get_command_obj('config') 2457db96d56Sopenharmony_ci # try_compile may pass or it may fail if no compiler 2467db96d56Sopenharmony_ci # is found but it should not raise an exception. 2477db96d56Sopenharmony_ci rc = config.try_compile('int x;') 2487db96d56Sopenharmony_ci ''')) 2497db96d56Sopenharmony_ci p = subprocess.Popen([str(sys.executable), TESTFN], 2507db96d56Sopenharmony_ci stdout=subprocess.PIPE, 2517db96d56Sopenharmony_ci stderr=subprocess.STDOUT, 2527db96d56Sopenharmony_ci universal_newlines=True) 2537db96d56Sopenharmony_ci outs, errs = p.communicate() 2547db96d56Sopenharmony_ci self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_cidef test_suite(): 2587db96d56Sopenharmony_ci suite = unittest.TestSuite() 2597db96d56Sopenharmony_ci suite.addTest(unittest.TestLoader().loadTestsFromTestCase(SysconfigTestCase)) 2607db96d56Sopenharmony_ci return suite 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ciif __name__ == '__main__': 2647db96d56Sopenharmony_ci run_unittest(test_suite()) 265