summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarmen Stoppels <me@harmenstoppels.nl>2024-03-14 08:54:47 +0100
committerGitHub <noreply@github.com>2024-03-14 08:54:47 +0100
commitc38ef72b0668b02a566ce7f5cee114f776ccc9b6 (patch)
tree44f01f0658143dba3a3671dbe94e11775b9d4940
parent7d67d9ece4c79916162a90965532acd6dfb3abe6 (diff)
downloadspack-c38ef72b0668b02a566ce7f5cee114f776ccc9b6.tar.gz
spack-c38ef72b0668b02a566ce7f5cee114f776ccc9b6.tar.bz2
spack-c38ef72b0668b02a566ce7f5cee114f776ccc9b6.tar.xz
spack-c38ef72b0668b02a566ce7f5cee114f776ccc9b6.zip
compiler.py: simplify implicit link dir bits (#43078)
-rw-r--r--lib/spack/spack/compiler.py37
-rw-r--r--lib/spack/spack/test/compilers/basics.py50
2 files changed, 36 insertions, 51 deletions
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index 30511d90db..d735845d86 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -389,8 +389,7 @@ class Compiler:
# Put CXX first since it has the most linking issues
# And because it has flags that affect linking
- exe_paths = [x for x in [self.cxx, self.cc, self.fc, self.f77] if x]
- link_dirs = self._get_compiler_link_paths(exe_paths)
+ link_dirs = self._get_compiler_link_paths()
all_required_libs = list(self.required_libs) + Compiler._all_compiler_rpath_libraries
return list(paths_containing_libs(link_dirs, all_required_libs))
@@ -403,43 +402,33 @@ class Compiler:
# By default every compiler returns the empty list
return []
- def _get_compiler_link_paths(self, paths):
- first_compiler = next((c for c in paths if c), None)
- if not first_compiler:
- return []
- if not self.verbose_flag:
- # In this case there is no mechanism to learn what link directories
- # are used by the compiler
+ def _get_compiler_link_paths(self):
+ cc = self.cc if self.cc else self.cxx
+ if not cc or not self.verbose_flag:
+ # Cannot determine implicit link paths without a compiler / verbose flag
return []
# What flag types apply to first_compiler, in what order
- flags = ["cppflags", "ldflags"]
- if first_compiler == self.cc:
- flags = ["cflags"] + flags
- elif first_compiler == self.cxx:
- flags = ["cxxflags"] + flags
+ if cc == self.cc:
+ flags = ["cflags", "cppflags", "ldflags"]
else:
- flags.append("fflags")
+ flags = ["cxxflags", "cppflags", "ldflags"]
try:
tmpdir = tempfile.mkdtemp(prefix="spack-implicit-link-info")
fout = os.path.join(tmpdir, "output")
fin = os.path.join(tmpdir, "main.c")
- with open(fin, "w+") as csource:
+ with open(fin, "w") as csource:
csource.write(
- "int main(int argc, char* argv[]) { " "(void)argc; (void)argv; return 0; }\n"
+ "int main(int argc, char* argv[]) { (void)argc; (void)argv; return 0; }\n"
)
- compiler_exe = spack.util.executable.Executable(first_compiler)
+ cc_exe = spack.util.executable.Executable(cc)
for flag_type in flags:
- for flag in self.flags.get(flag_type, []):
- compiler_exe.add_default_arg(flag)
+ cc_exe.add_default_arg(*self.flags.get(flag_type, []))
- output = ""
with self.compiler_environment():
- output = str(
- compiler_exe(self.verbose_flag, fin, "-o", fout, output=str, error=str)
- ) # str for py2
+ output = cc_exe(self.verbose_flag, fin, "-o", fout, output=str, error=str)
return _parse_non_system_link_dirs(output)
except spack.util.executable.ProcessError as pe:
tty.debug("ProcessError: Command exited with non-zero status: " + pe.long_message)
diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py
index 0bb26644a3..60cef60d72 100644
--- a/lib/spack/spack/test/compilers/basics.py
+++ b/lib/spack/spack/test/compilers/basics.py
@@ -15,7 +15,7 @@ import spack.compilers
import spack.spec
import spack.util.environment
from spack.compiler import Compiler
-from spack.util.executable import ProcessError
+from spack.util.executable import Executable, ProcessError
@pytest.fixture()
@@ -138,11 +138,11 @@ class MockCompiler(Compiler):
environment={},
)
- def _get_compiler_link_paths(self, paths):
+ def _get_compiler_link_paths(self):
# Mock os.path.isdir so the link paths don't have to exist
old_isdir = os.path.isdir
os.path.isdir = lambda x: True
- ret = super()._get_compiler_link_paths(paths)
+ ret = super()._get_compiler_link_paths()
os.path.isdir = old_isdir
return ret
@@ -197,37 +197,37 @@ def call_compiler(exe, *args, **kwargs):
@pytest.mark.parametrize(
"exe,flagname",
[
- ("cxx", ""),
("cxx", "cxxflags"),
("cxx", "cppflags"),
("cxx", "ldflags"),
- ("cc", ""),
("cc", "cflags"),
("cc", "cppflags"),
- ("fc", ""),
- ("fc", "fflags"),
- ("f77", "fflags"),
- ("f77", "cppflags"),
],
)
@pytest.mark.enable_compiler_link_paths
def test_get_compiler_link_paths(monkeypatch, exe, flagname):
# create fake compiler that emits mock verbose output
compiler = MockCompiler()
- monkeypatch.setattr(spack.util.executable.Executable, "__call__", call_compiler)
-
- # Grab executable path to test
- paths = [getattr(compiler, exe)]
+ monkeypatch.setattr(Executable, "__call__", call_compiler)
+
+ if exe == "cxx":
+ compiler.cc = None
+ compiler.fc = None
+ compiler.f77 = None
+ elif exe == "cc":
+ compiler.cxx = None
+ compiler.fc = None
+ compiler.f77 = None
+ else:
+ assert False
# Test without flags
- dirs = compiler._get_compiler_link_paths(paths)
- assert dirs == no_flag_dirs
+ assert compiler._get_compiler_link_paths() == no_flag_dirs
if flagname:
# set flags and test
- setattr(compiler, "flags", {flagname: ["--correct-flag"]})
- dirs = compiler._get_compiler_link_paths(paths)
- assert dirs == flag_dirs
+ compiler.flags = {flagname: ["--correct-flag"]}
+ assert compiler._get_compiler_link_paths() == flag_dirs
def test_get_compiler_link_paths_no_path():
@@ -236,17 +236,13 @@ def test_get_compiler_link_paths_no_path():
compiler.cxx = None
compiler.f77 = None
compiler.fc = None
-
- dirs = compiler._get_compiler_link_paths([compiler.cxx])
- assert dirs == []
+ assert compiler._get_compiler_link_paths() == []
def test_get_compiler_link_paths_no_verbose_flag():
compiler = MockCompiler()
compiler._verbose_flag = None
-
- dirs = compiler._get_compiler_link_paths([compiler.cxx])
- assert dirs == []
+ assert compiler._get_compiler_link_paths() == []
@pytest.mark.not_on_windows("Not supported on Windows (yet)")
@@ -275,11 +271,11 @@ fi
monkeypatch.setattr(spack.util.module_cmd, "module", module)
compiler = MockCompiler()
+ compiler.cc = gcc
compiler.environment = {"set": {"ENV_SET": "1"}}
compiler.modules = ["turn_on"]
- dirs = compiler._get_compiler_link_paths([gcc])
- assert dirs == no_flag_dirs
+ assert compiler._get_compiler_link_paths() == no_flag_dirs
# Get the desired flag from the specified compiler spec.
@@ -824,7 +820,7 @@ fi
def _call(*args, **kwargs):
raise ProcessError("Failed intentionally")
- monkeypatch.setattr(spack.util.executable.Executable, "__call__", _call)
+ monkeypatch.setattr(Executable, "__call__", _call)
# Run and no change to environment
compilers = spack.compilers.get_compilers([compiler_dict])