summaryrefslogtreecommitdiff
path: root/var
diff options
context:
space:
mode:
Diffstat (limited to 'var')
-rw-r--r--var/spack/repos/builtin/packages/python/package.py88
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)