diff options
Diffstat (limited to 'var')
-rw-r--r-- | var/spack/repos/builtin/packages/python/package.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py index 2eab9fa558..b5c11ee527 100644 --- a/var/spack/repos/builtin/packages/python/package.py +++ b/var/spack/repos/builtin/packages/python/package.py @@ -22,12 +22,14 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## +import ast import os import re from contextlib import closing import spack import llnl.util.tty as tty +import yaml from llnl.util.lang import match_predicate from spack import * from spack.util.environment import * @@ -132,6 +134,8 @@ class Python(Package): make() make('install') + self.save_distutils_data(prefix) + self.filter_compilers(prefix) # TODO: @@ -172,6 +176,84 @@ class Python(Package): # >>> import Tkinter # >>> Tkinter._test() + def save_distutils_data(self, prefix): + """ + Run before changing automatically generated contents of the + _sysconfigdata.py, which is used by distutils to figure out what + executables to use while compiling and linking extensions. If we build + extensions with spack those executables should be spack's wrappers. + Spack partially covers this by setting environment variables that + are also accounted for by distutils. Currently there is one more known + variable that must be set, which is LDSHARED, so the method saves its + autogenerated value to pass it to the dependant package's setup script. + """ + + input_filename = None + for filename in [join_path(lib_dir, + 'python{0}'.format(self.version.up_to(2)), + '_sysconfigdata.py') + for lib_dir in [prefix.lib, prefix.lib64]]: + if os.path.isfile(filename): + input_filename = filename + break + + if not input_filename: + return + + input_dict = None + + try: + with open(input_filename) as input_file: + match = re.search(r'build_time_vars\s*=\s*(?P<dict>{.*})', + input_file.read(), + flags=re.DOTALL) + + if match: + input_dict = ast.literal_eval(match.group('dict')) + except (IOError, SyntaxError): + pass + + if not input_dict: + return + + vars_to_save = ['LDSHARED'] + saved_vars = {} + + for var_name in vars_to_save: + if var_name in input_dict: + saved_vars[var_name] = input_dict[var_name] + + if len(saved_vars) > 0: + try: + output_filename = join_path( + spack.store.layout.metadata_path(self.spec), + 'sysconfig.yaml') + with open(output_filename, 'w') as output_file: + yaml.dump(saved_vars, stream=output_file, + default_flow_style=False) + except (yaml.YAMLError, IOError): + pass + + setattr(self, '_distutils_data_cache', saved_vars) + + def load_distutils_data(self): + if not hasattr(self, '_distutils_data_cache'): + input_filename = join_path( + spack.store.layout.metadata_path(self.spec), + 'sysconfig.yaml') + if os.path.isfile(input_filename): + try: + with open(input_filename) as input_file: + setattr(self, '_distutils_data_cache', + yaml.load(input_file)) + except (yaml.YAMLError, IOError): + pass + + if not hasattr(self, '_distutils_data_cache'): + setattr(self, '_distutils_data_cache', None) + + return self._distutils_data_cache + def filter_compilers(self, prefix): """Run after install to tell the configuration files and Makefiles to use the compilers that Spack built the package with. @@ -268,6 +350,12 @@ class Python(Package): module.python = Executable(python_path) module.setup_py = Executable(python_path + ' setup.py --no-user-cfg') + distutils_data = self.load_distutils_data() + + if distutils_data: + for key, value in distutils_data.iteritems(): + module.setup_py.add_default_env(key, value) + # Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs. module.python_lib_dir = join_path(ext_spec.prefix, self.python_lib_dir) |