compiler.py: simplify implicit link dir bits (#43078)
This commit is contained in:
parent
7d67d9ece4
commit
c38ef72b06
@ -389,8 +389,7 @@ def implicit_rpaths(self):
|
||||
|
||||
# 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 @@ def required_libs(self):
|
||||
# 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)
|
||||
|
@ -15,7 +15,7 @@
|
||||
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 @@ def __init__(self):
|
||||
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)
|
||||
monkeypatch.setattr(Executable, "__call__", call_compiler)
|
||||
|
||||
# Grab executable path to test
|
||||
paths = [getattr(compiler, exe)]
|
||||
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 @@ def module(*args):
|
||||
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 @@ def module(*args):
|
||||
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])
|
||||
|
Loading…
Reference in New Issue
Block a user