1import config.base 2 3import os 4 5class Configure(config.base.Configure): 6 def __init__(self, framework): 7 config.base.Configure.__init__(self, framework) 8 self.headerPrefix = '' 9 self.substPrefix = '' 10 self.include = None 11 self.lib = None 12 self.isShared = False 13 return 14 15 def __str__(self): 16 return '' 17 18 def setupDependencies(self, framework): 19 config.base.Configure.setupDependencies(self, framework) 20 self.compilers = framework.require('config.compilers', self) 21 self.headers = framework.require('config.headers', self) 22 self.libraries = framework.require('config.libraries', self) 23 return 24 25 def configureDisutils(self): 26 '''Check that disutils.sysconfig is functional, and can return the required config vars''' 27 try: 28 try: 29 import distutils.sysconfig 30 except ImportError as e: 31 self.logPrint('Error importing distutils.sysconfig: '+str(e)) 32 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 33 34 try: 35 distutils.sysconfig.get_python_inc() 36 distutils.sysconfig.get_python_inc(1) 37 except distutils.sysconfig.DistutilsPlatformError as e: 38 self.logPrint('Error finding Python include directories: '+str(e)) 39 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 40 41 try: 42 distutils.sysconfig.get_config_var('LDFLAGS') 43 distutils.sysconfig.get_config_var('LIBS') 44 distutils.sysconfig.get_config_var('SYSLIBS') 45 except distutils.sysconfig.DistutilsPlatformError as e: 46 self.logPrint('Error finding Python libraries: '+str(e)) 47 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 48 49 try: 50 distutils.sysconfig.get_config_var('LIBDIR') 51 distutils.sysconfig.get_config_var('LIBPL') 52 distutils.sysconfig.get_config_var('LDLIBRARY') 53 distutils.sysconfig.get_config_var('SO') 54 except distutils.sysconfig.DistutilsPlatformError as e: 55 self.logPrint('Error finding Python shared library: '+str(e)) 56 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 57 58 try: 59 distutils.sysconfig.get_config_var('BINDIR') 60 distutils.sysconfig.get_config_var('PYTHON') 61 except distutils.sysconfig.DistutilsPlatformError as e: 62 self.logPrint('Error finding Python executable: '+str(e)) 63 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 64 except Exception as e: 65 self.logPrint('I do not know what went wrong: '+str(e)) 66 raise RuntimeError('Python is not fully installed. Perhaps python-devel package missing? Please consult your packing system.') 67 return 68 69 def checkInclude(self, includeDir): 70 '''Check that Python.h is present''' 71 oldFlags = self.compilers.CPPFLAGS 72 self.compilers.CPPFLAGS += ' '+' '.join([self.headers.getIncludeArgument(inc) for inc in includeDir]) 73 found = self.checkPreprocess('#include <Python.h>\n') 74 self.compilers.CPPFLAGS = oldFlags 75 return found 76 77 def checkPythonLink(self, includes, body, cleanup = 1, codeBegin = None, codeEnd = None, shared = 0): 78 '''Analogous to checkLink(), but the Python includes and libraries are automatically provided''' 79 success = 0 80 oldFlags = self.compilers.CPPFLAGS 81 oldLibs = self.compilers.LIBS 82 self.compilers.CPPFLAGS += ' '+' '.join([self.headers.getIncludeArgument(inc) for inc in self.include]) 83 self.compilers.LIBS = ' '.join([self.libraries.getLibArgument(lib) for lib in self.lib])+' '+self.compilers.LIBS 84 if self.checkLink(includes, body, cleanup, codeBegin, codeEnd, shared): 85 success = 1 86 self.compilers.CPPFLAGS = oldFlags 87 self.compilers.LIBS = oldLibs 88 return success 89 90 def configurePythonLibraries(self): 91 import distutils.sysconfig 92 93 # Check for Python headers 94 inc = [distutils.sysconfig.get_python_inc(), distutils.sysconfig.get_python_inc(1)] 95 if not self.checkInclude(inc): 96 raise RuntimeError('Unable to locate Python headers') 97 self.include = inc 98 # Check for Python dynamic library 99 dylib = distutils.sysconfig.get_config_var('LDLIBRARY') 100 if not dylib: 101 raise RuntimeError('LDLIBRARY variable is missing from disutils database'); 102 libDirs = [distutils.sysconfig.get_config_var('LIBDIR'), 103 distutils.sysconfig.get_config_var('LIBPL'), 104 os.path.join('/System', 'Library', 'Frameworks'), 105 os.path.join('/Library', 'Frameworks')] 106 lib = None 107 for libDir in libDirs: 108 if not libDir: continue 109 lib = os.path.join(libDir, dylib) 110 if os.path.isfile(lib): 111 break 112 if lib is None: 113 raise RuntimeError("Cannot locate Python dynamic libraries"); 114 # Remove any version numbers from the library name 115 if distutils.sysconfig.get_config_var('SO'): 116 ext = distutils.sysconfig.get_config_var('SO') 117 if os.path.isfile(lib.split(ext)[0]+ext): 118 lib = lib.split(ext)[0]+ext 119 # Add any additional libraries needed for the link 120 self.lib = [lib] 121 if distutils.sysconfig.get_config_var('LIBS'): 122 flags = distutils.sysconfig.get_config_var('LIBS') 123 if distutils.sysconfig.get_config_var('LDFLAGS'): 124 flags = distutils.sysconfig.get_config_var('LDFLAGS')+' '+flags 125 self.lib.extend(self.splitLibs(flags)) 126 if distutils.sysconfig.get_config_var('SYSLIBS'): 127 self.lib.extend(self.splitLibs(distutils.sysconfig.get_config_var('SYSLIBS'))) 128 # Verify that the Python library is a shared library 129 try: 130 self.isShared = self.libraries.checkShared('#include <Python.h>\n', 'Py_Initialize', 'Py_IsInitialized', 'Py_Finalize', checkLink = self.checkPythonLink, libraries = self.lib, initArgs = '', noCheckArg = 1) 131 except RuntimeError as e: 132 raise RuntimeError('Python shared library check failed, probably due to inability to link Python libraries or a bad interaction with the shared linker.\nSuggest running with --with-python=0 if you do not need Python. Otherwise send configure.log to petsc-maint@mcs.anl.gov') 133 return 134 135 def setOutput(self): 136 '''Add defines and substitutions 137 - PYTHON_INCLUDE and PYTHON_LIB are command line arguments for the compile and link 138 - PYTHON_INCLUDE_DIR is the directory containing mpi.h 139 - PYTHON_LIBRARY is the list of Python libraries''' 140 if self.include: 141 self.addMakeMacro('PYTHON_INCLUDE', ' '.join(['-I'+inc for inc in self.include])) 142 self.addSubstitution('PYTHON_INCLUDE', ' '.join(['-I'+inc for inc in self.include])) 143 self.addSubstitution('PYTHON_INCLUDE_DIR', self.include[0]) 144 else: 145 self.addSubstitution('PYTHON_INCLUDE', '') 146 self.addSubstitution('PYTHON_INCLUDE_DIR', '') 147 if self.lib: 148 self.addMakeMacro('PYTHON_LIB', ' '.join(map(self.libraries.getLibArgument, self.lib))) 149 self.addSubstitution('PYTHON_LIB', ' '.join(map(self.libraries.getLibArgument, self.lib))) 150 self.addSubstitution('PYTHON_LIBRARY', self.lib) 151 else: 152 self.addSubstitution('PYTHON_LIB', '') 153 self.addSubstitution('PYTHON_LIBRARY', '') 154 return 155 156 def configure(self): 157 self.executeTest(self.configureDisutils) 158 self.executeTest(self.configurePythonLibraries) 159 self.setOutput() 160 return 161