Specify GCC prefix in LLVM-based compilers (#33146)

* spack.compiler.Compiler: introduce prefix property

We currently don't really have something that gives the GCC install
path, which is used by many LLVM-based compilers (llvm, llvm-amdgpu,
nvhpc, ...) to fix the GCC toolchain once and for all.

This `prefix` property is dynamic in the sense that it queries the
compiler itself. This is necessary because it's not easy to deduce the
install path from the `cc` property (might be a symlink, might be a
filename like `gcc` which works by having the compiler load a module
that sets the PATH variable, might be a generic compiler wrapper based
on environment variables like on cray...).

With this property introduced, we can clean up some recipes that have
the logic repeated for GCC.

* intel-oneapi-compilers: set --gcc-sysroot to %gcc prefix
This commit is contained in:
Harmen Stoppels 2022-10-12 01:45:51 +02:00 committed by GitHub
parent 4b866e8ffc
commit 926dca9e5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 35 deletions

View File

@ -537,6 +537,14 @@ def get_real_version(self):
)
return self.extract_version_from_output(output)
@property
def prefix(self):
"""Query the compiler for its install prefix. This is the install
path as reported by the compiler. Note that paths for cc, cxx, etc
are not enough to find the install prefix of the compiler, since
the can be symlinks, wrappers, or filenames instead of absolute paths."""
raise NotImplementedError("prefix is not implemented for this compiler")
#
# Compiler classes have methods for querying the version of
# specific compiler executables. This is used when discovering compilers.

View File

@ -6,8 +6,11 @@
import os
import re
from llnl.util.filesystem import ancestor
import spack.compiler
import spack.compilers.apple_clang as apple_clang
import spack.util.executable
from spack.version import ver
@ -196,3 +199,21 @@ def f77_version(cls, f77):
@property
def stdcxx_libs(self):
return ("-lstdc++",)
@property
def prefix(self):
# GCC reports its install prefix when running ``-print-search-dirs``
# on the first line ``install: <prefix>``.
cc = spack.util.executable.Executable(self.cc)
with self.compiler_environment():
gcc_output = cc("-print-search-dirs", output=str, error=str)
for line in gcc_output.splitlines():
if line.startswith("install:"):
gcc_prefix = line.split(":")[1].strip()
# Go from <prefix>/lib/gcc/<triplet>/<version>/ to <prefix>
return ancestor(gcc_prefix, 4)
raise RuntimeError(
"could not find install prefix of GCC from output:\n\t{}".format(gcc_output)
)

View File

@ -5,6 +5,7 @@
import platform
import spack.compilers
from spack.build_environment import dso_suffix
from spack.package import *
@ -113,6 +114,15 @@ class IntelOneapiCompilers(IntelOneApiPackage):
depends_on("patchelf", type="build")
# TODO: effectively gcc is a direct dependency of intel-oneapi-compilers, but we
# cannot express that properly. For now, add conflicts for non-gcc compilers
# instead.
for __compiler in spack.compilers.supported_compilers():
if __compiler != "gcc":
conflicts(
"%{0}".format(__compiler), msg="intel-oneapi-compilers must be installed with %gcc"
)
if platform.system() == "Linux":
for v in linux_versions:
version(v["version"], expand=False, **v["cpp"])
@ -186,7 +196,9 @@ def extend_config_flags(self):
# TODO: it is unclear whether we should really use all elements of
# _ld_library_path because it looks like the only rpath that needs to be
# injected is self.component_prefix.linux.compiler.lib.intel64_lin.
flags = " ".join(["-Wl,-rpath,{0}".format(d) for d in self._ld_library_path()])
flags_list = ["-Wl,-rpath,{}".format(d) for d in self._ld_library_path()]
flags_list.append("--gcc-toolchain={}".format(self.compiler.prefix))
flags = " ".join(flags_list)
for cmp in [
"icx",
"icpx",

View File

@ -234,18 +234,7 @@ def cmake_args(self):
# Get the GCC prefix for LLVM.
if self.compiler.name == "gcc":
compiler = Executable(self.compiler.cc)
gcc_output = compiler("-print-search-dirs", output=str, error=str)
gcc_prefix = ""
for line in gcc_output.splitlines():
if line.startswith("install:"):
# Get path and strip any whitespace
# (causes oddity with ancestor)
gcc_prefix = line.split(":")[1].strip()
gcc_prefix = ancestor(gcc_prefix, 4)
break
args.append(self.define("GCC_INSTALL_PREFIX", gcc_prefix))
args.append(self.define("GCC_INSTALL_PREFIX", self.compiler.prefix))
return args

View File

@ -582,17 +582,7 @@ def cmake_args(self):
cmake_args.append("-DLIBOMP_USE_ARGOBOTS=ON")
if self.compiler.name == "gcc":
compiler = Executable(self.compiler.cc)
gcc_output = compiler("-print-search-dirs", output=str, error=str)
for line in gcc_output.splitlines():
if line.startswith("install:"):
# Get path and strip any whitespace
# (causes oddity with ancestor)
gcc_prefix = line.split(":")[1].strip()
gcc_prefix = ancestor(gcc_prefix, 4)
break
cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix))
cmake_args.append(define("GCC_INSTALL_PREFIX", self.compiler.prefix))
# if spec.satisfies("platform=cray") or spec.satisfies("platform=linux"):
# cmake_args.append("-DCMAKE_BUILD_WITH_INSTALL_RPATH=1")

View File

@ -721,17 +721,7 @@ def cmake_args(self):
cmake_args.append(from_variant("LIBOMP_TSAN_SUPPORT", "omp_tsan"))
if self.compiler.name == "gcc":
compiler = Executable(self.compiler.cc)
gcc_output = compiler("-print-search-dirs", output=str, error=str)
for line in gcc_output.splitlines():
if line.startswith("install:"):
# Get path and strip any whitespace
# (causes oddity with ancestor)
gcc_prefix = line.split(":")[1].strip()
gcc_prefix = ancestor(gcc_prefix, 4)
break
cmake_args.append(define("GCC_INSTALL_PREFIX", gcc_prefix))
cmake_args.append(define("GCC_INSTALL_PREFIX", self.compiler.prefix))
if self.spec.satisfies("~code_signing platform=darwin"):
cmake_args.append(define("LLDB_USE_SYSTEM_DEBUGSERVER", True))