Updated python: pass LDSHARED to dependants' setup scripts.

This commit is contained in:
Sergey Kosukhin 2016-12-08 13:39:10 +01:00
parent ec855df071
commit 3ba88a7509

View File

@ -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 @@ def install(self, spec, prefix):
make()
make('install')
self.save_distutils_data(prefix)
self.filter_compilers(prefix)
# TODO:
@ -172,6 +176,84 @@ def install(self, spec, prefix):
# >>> 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 @@ def setup_dependent_package(self, module, ext_spec):
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)