summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/build_environment.py2
-rw-r--r--lib/spack/spack/compiler.py26
-rw-r--r--lib/spack/spack/compilers/clang.py79
-rw-r--r--var/spack/repos/builtin/packages/icu4c/package.py3
-rw-r--r--var/spack/repos/builtin/packages/qt/package.py1
5 files changed, 104 insertions, 7 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 15fb943ca4..792cd09eb8 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -223,6 +223,8 @@ def set_compiler_environment_variables(pkg, env):
for mod in compiler.modules:
load_module(mod)
+ compiler.setup_custom_environment(env)
+
return env
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index a77991e4dc..fc663ea646 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -114,9 +114,15 @@ class Compiler(object):
def __init__(self, cspec, operating_system,
paths, modules=[], alias=None, **kwargs):
+ self.operating_system = operating_system
+ self.spec = cspec
+ self.modules = modules
+ self.alias = alias
+
def check(exe):
if exe is None:
return None
+ exe = self._find_full_path(exe)
_verify_executables(exe)
return exe
@@ -138,11 +144,6 @@ class Compiler(object):
if value is not None:
self.flags[flag] = value.split()
- self.operating_system = operating_system
- self.spec = cspec
- self.modules = modules
- self.alias = alias
-
@property
def version(self):
return self.spec.version
@@ -269,6 +270,21 @@ class Compiler(object):
successful.reverse()
return dict(((v, p, s), path) for v, p, s, path in successful)
+ def _find_full_path(self, path):
+ """Return the actual path for a tool.
+
+ Some toolchains use forwarding executables (particularly Xcode-based
+ toolchains) which can be manipulated by external environment variables.
+ This method should be used to extract the actual path used for a tool
+ by finding out the end executable the forwarding executables end up
+ running.
+ """
+ return path
+
+ def setup_custom_environment(self, env):
+ """Set any environment variables necessary to use the compiler."""
+ pass
+
def __repr__(self):
"""Return a string representation of the compiler toolchain."""
return self.__str__()
diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py
index f7f1bf106b..34eec4ea7b 100644
--- a/lib/spack/spack/compilers/clang.py
+++ b/lib/spack/spack/compilers/clang.py
@@ -23,11 +23,14 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import re
+import os
+import spack
import spack.compiler as cpr
from spack.compiler import *
from spack.util.executable import *
import llnl.util.tty as tty
from spack.version import ver
+from shutil import copytree, ignore_patterns
class Clang(Compiler):
@@ -107,3 +110,79 @@ class Clang(Compiler):
cpr._version_cache[comp] = ver
return cpr._version_cache[comp]
+
+ def _find_full_path(self, path):
+ basename = os.path.basename(path)
+
+ if not self.is_apple or basename not in ('clang', 'clang++'):
+ return super(Clang, self)._find_full_path(path)
+
+ xcrun = Executable('xcrun')
+ full_path = xcrun('-f', basename, output=str)
+ return full_path.strip()
+
+ def setup_custom_environment(self, env):
+ """Set the DEVELOPER_DIR environment for the Xcode toolchain.
+
+ On macOS, not all buildsystems support querying CC and CXX for the
+ compilers to use and instead query the Xcode toolchain for what
+ compiler to run. This side-steps the spack wrappers. In order to inject
+ spack into this setup, we need to copy (a subset of) Xcode.app and
+ replace the compiler executables with symlinks to the spack wrapper.
+ Currently, the stage is used to store the Xcode.app copies. We then set
+ the 'DEVELOPER_DIR' environment variables to cause the xcrun and
+ related tools to use this Xcode.app.
+ """
+ super(Clang, self).setup_custom_environment(env)
+
+ if not self.is_apple:
+ return
+
+ xcode_select = Executable('xcode-select')
+ real_root = xcode_select('--print-path', output=str).strip()
+ real_root = os.path.dirname(os.path.dirname(real_root))
+ developer_root = os.path.join(spack.stage_path,
+ 'xcode-select',
+ self.name,
+ str(self.version))
+ xcode_link = os.path.join(developer_root, 'Xcode.app')
+
+ if not os.path.exists(developer_root):
+ tty.warn('Copying Xcode from %s to %s in order to add spack '
+ 'wrappers to it. Please do not interrupt.'
+ % (real_root, developer_root))
+
+ # We need to make a new Xcode.app instance, but with symlinks to
+ # the spack wrappers for the compilers it ships. This is necessary
+ # because some projects insist on just asking xcrun and related
+ # tools where the compiler runs. These tools are very hard to trick
+ # as they do realpath and end up ignoring the symlinks in a
+ # "softer" tree of nothing but symlinks in the right places.
+ copytree(real_root, developer_root, symlinks=True,
+ ignore=ignore_patterns('AppleTV*.platform',
+ 'Watch*.platform',
+ 'iPhone*.platform',
+ 'Documentation',
+ 'swift*'))
+
+ real_dirs = [
+ 'Toolchains/XcodeDefault.xctoolchain/usr/bin',
+ 'usr/bin',
+ ]
+
+ bins = ['c++', 'c89', 'c99', 'cc', 'clang', 'clang++', 'cpp']
+
+ for real_dir in real_dirs:
+ dev_dir = os.path.join(developer_root,
+ 'Contents',
+ 'Developer',
+ real_dir)
+ for fname in os.listdir(dev_dir):
+ if fname in bins:
+ os.unlink(os.path.join(dev_dir, fname))
+ os.symlink(os.path.join(spack.build_env_path, 'cc'),
+ os.path.join(dev_dir, fname))
+
+ os.symlink(developer_root, xcode_link)
+
+ env.set('DEVELOPER_DIR', xcode_link)
diff --git a/var/spack/repos/builtin/packages/icu4c/package.py b/var/spack/repos/builtin/packages/icu4c/package.py
index 848ebfdeac..e2fcb7bd5f 100644
--- a/var/spack/repos/builtin/packages/icu4c/package.py
+++ b/var/spack/repos/builtin/packages/icu4c/package.py
@@ -42,7 +42,8 @@ class Icu4c(Package):
def install(self, spec, prefix):
with working_dir('source'):
- configure('--prefix={0}'.format(prefix))
+ configure('--prefix={0}'.format(prefix),
+ '--enable-rpath')
make()
make('check')
diff --git a/var/spack/repos/builtin/packages/qt/package.py b/var/spack/repos/builtin/packages/qt/package.py
index 2dba05ce13..f04f05ec89 100644
--- a/var/spack/repos/builtin/packages/qt/package.py
+++ b/var/spack/repos/builtin/packages/qt/package.py
@@ -183,7 +183,6 @@ class Qt(Package):
'-no-xcb-xlib',
'-no-pulseaudio',
'-no-alsa',
- '-no-gtkstyle',
])
if '@4' in self.spec and sys.platform == 'darwin':