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
|
# Put CXX first since it has the most linking issues
|
||||||
# And because it has flags that affect linking
|
# 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()
|
||||||
link_dirs = self._get_compiler_link_paths(exe_paths)
|
|
||||||
|
|
||||||
all_required_libs = list(self.required_libs) + Compiler._all_compiler_rpath_libraries
|
all_required_libs = list(self.required_libs) + Compiler._all_compiler_rpath_libraries
|
||||||
return list(paths_containing_libs(link_dirs, all_required_libs))
|
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
|
# By default every compiler returns the empty list
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _get_compiler_link_paths(self, paths):
|
def _get_compiler_link_paths(self):
|
||||||
first_compiler = next((c for c in paths if c), None)
|
cc = self.cc if self.cc else self.cxx
|
||||||
if not first_compiler:
|
if not cc or not self.verbose_flag:
|
||||||
return []
|
# Cannot determine implicit link paths without a compiler / verbose flag
|
||||||
if not self.verbose_flag:
|
|
||||||
# In this case there is no mechanism to learn what link directories
|
|
||||||
# are used by the compiler
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# What flag types apply to first_compiler, in what order
|
# What flag types apply to first_compiler, in what order
|
||||||
flags = ["cppflags", "ldflags"]
|
if cc == self.cc:
|
||||||
if first_compiler == self.cc:
|
flags = ["cflags", "cppflags", "ldflags"]
|
||||||
flags = ["cflags"] + flags
|
|
||||||
elif first_compiler == self.cxx:
|
|
||||||
flags = ["cxxflags"] + flags
|
|
||||||
else:
|
else:
|
||||||
flags.append("fflags")
|
flags = ["cxxflags", "cppflags", "ldflags"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tmpdir = tempfile.mkdtemp(prefix="spack-implicit-link-info")
|
tmpdir = tempfile.mkdtemp(prefix="spack-implicit-link-info")
|
||||||
fout = os.path.join(tmpdir, "output")
|
fout = os.path.join(tmpdir, "output")
|
||||||
fin = os.path.join(tmpdir, "main.c")
|
fin = os.path.join(tmpdir, "main.c")
|
||||||
|
|
||||||
with open(fin, "w+") as csource:
|
with open(fin, "w") as csource:
|
||||||
csource.write(
|
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_type in flags:
|
||||||
for flag in self.flags.get(flag_type, []):
|
cc_exe.add_default_arg(*self.flags.get(flag_type, []))
|
||||||
compiler_exe.add_default_arg(flag)
|
|
||||||
|
|
||||||
output = ""
|
|
||||||
with self.compiler_environment():
|
with self.compiler_environment():
|
||||||
output = str(
|
output = cc_exe(self.verbose_flag, fin, "-o", fout, output=str, error=str)
|
||||||
compiler_exe(self.verbose_flag, fin, "-o", fout, output=str, error=str)
|
|
||||||
) # str for py2
|
|
||||||
return _parse_non_system_link_dirs(output)
|
return _parse_non_system_link_dirs(output)
|
||||||
except spack.util.executable.ProcessError as pe:
|
except spack.util.executable.ProcessError as pe:
|
||||||
tty.debug("ProcessError: Command exited with non-zero status: " + pe.long_message)
|
tty.debug("ProcessError: Command exited with non-zero status: " + pe.long_message)
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
import spack.spec
|
import spack.spec
|
||||||
import spack.util.environment
|
import spack.util.environment
|
||||||
from spack.compiler import Compiler
|
from spack.compiler import Compiler
|
||||||
from spack.util.executable import ProcessError
|
from spack.util.executable import Executable, ProcessError
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
@ -138,11 +138,11 @@ def __init__(self):
|
|||||||
environment={},
|
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
|
# Mock os.path.isdir so the link paths don't have to exist
|
||||||
old_isdir = os.path.isdir
|
old_isdir = os.path.isdir
|
||||||
os.path.isdir = lambda x: True
|
os.path.isdir = lambda x: True
|
||||||
ret = super()._get_compiler_link_paths(paths)
|
ret = super()._get_compiler_link_paths()
|
||||||
os.path.isdir = old_isdir
|
os.path.isdir = old_isdir
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@ -197,37 +197,37 @@ def call_compiler(exe, *args, **kwargs):
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"exe,flagname",
|
"exe,flagname",
|
||||||
[
|
[
|
||||||
("cxx", ""),
|
|
||||||
("cxx", "cxxflags"),
|
("cxx", "cxxflags"),
|
||||||
("cxx", "cppflags"),
|
("cxx", "cppflags"),
|
||||||
("cxx", "ldflags"),
|
("cxx", "ldflags"),
|
||||||
("cc", ""),
|
|
||||||
("cc", "cflags"),
|
("cc", "cflags"),
|
||||||
("cc", "cppflags"),
|
("cc", "cppflags"),
|
||||||
("fc", ""),
|
|
||||||
("fc", "fflags"),
|
|
||||||
("f77", "fflags"),
|
|
||||||
("f77", "cppflags"),
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.enable_compiler_link_paths
|
@pytest.mark.enable_compiler_link_paths
|
||||||
def test_get_compiler_link_paths(monkeypatch, exe, flagname):
|
def test_get_compiler_link_paths(monkeypatch, exe, flagname):
|
||||||
# create fake compiler that emits mock verbose output
|
# create fake compiler that emits mock verbose output
|
||||||
compiler = MockCompiler()
|
compiler = MockCompiler()
|
||||||
monkeypatch.setattr(spack.util.executable.Executable, "__call__", call_compiler)
|
monkeypatch.setattr(Executable, "__call__", call_compiler)
|
||||||
|
|
||||||
# Grab executable path to test
|
if exe == "cxx":
|
||||||
paths = [getattr(compiler, exe)]
|
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
|
# Test without flags
|
||||||
dirs = compiler._get_compiler_link_paths(paths)
|
assert compiler._get_compiler_link_paths() == no_flag_dirs
|
||||||
assert dirs == no_flag_dirs
|
|
||||||
|
|
||||||
if flagname:
|
if flagname:
|
||||||
# set flags and test
|
# set flags and test
|
||||||
setattr(compiler, "flags", {flagname: ["--correct-flag"]})
|
compiler.flags = {flagname: ["--correct-flag"]}
|
||||||
dirs = compiler._get_compiler_link_paths(paths)
|
assert compiler._get_compiler_link_paths() == flag_dirs
|
||||||
assert dirs == flag_dirs
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_compiler_link_paths_no_path():
|
def test_get_compiler_link_paths_no_path():
|
||||||
@ -236,17 +236,13 @@ def test_get_compiler_link_paths_no_path():
|
|||||||
compiler.cxx = None
|
compiler.cxx = None
|
||||||
compiler.f77 = None
|
compiler.f77 = None
|
||||||
compiler.fc = None
|
compiler.fc = None
|
||||||
|
assert compiler._get_compiler_link_paths() == []
|
||||||
dirs = compiler._get_compiler_link_paths([compiler.cxx])
|
|
||||||
assert dirs == []
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_compiler_link_paths_no_verbose_flag():
|
def test_get_compiler_link_paths_no_verbose_flag():
|
||||||
compiler = MockCompiler()
|
compiler = MockCompiler()
|
||||||
compiler._verbose_flag = None
|
compiler._verbose_flag = None
|
||||||
|
assert compiler._get_compiler_link_paths() == []
|
||||||
dirs = compiler._get_compiler_link_paths([compiler.cxx])
|
|
||||||
assert dirs == []
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.not_on_windows("Not supported on Windows (yet)")
|
@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)
|
monkeypatch.setattr(spack.util.module_cmd, "module", module)
|
||||||
|
|
||||||
compiler = MockCompiler()
|
compiler = MockCompiler()
|
||||||
|
compiler.cc = gcc
|
||||||
compiler.environment = {"set": {"ENV_SET": "1"}}
|
compiler.environment = {"set": {"ENV_SET": "1"}}
|
||||||
compiler.modules = ["turn_on"]
|
compiler.modules = ["turn_on"]
|
||||||
|
|
||||||
dirs = compiler._get_compiler_link_paths([gcc])
|
assert compiler._get_compiler_link_paths() == no_flag_dirs
|
||||||
assert dirs == no_flag_dirs
|
|
||||||
|
|
||||||
|
|
||||||
# Get the desired flag from the specified compiler spec.
|
# Get the desired flag from the specified compiler spec.
|
||||||
@ -824,7 +820,7 @@ def module(*args):
|
|||||||
def _call(*args, **kwargs):
|
def _call(*args, **kwargs):
|
||||||
raise ProcessError("Failed intentionally")
|
raise ProcessError("Failed intentionally")
|
||||||
|
|
||||||
monkeypatch.setattr(spack.util.executable.Executable, "__call__", _call)
|
monkeypatch.setattr(Executable, "__call__", _call)
|
||||||
|
|
||||||
# Run and no change to environment
|
# Run and no change to environment
|
||||||
compilers = spack.compilers.get_compilers([compiler_dict])
|
compilers = spack.compilers.get_compilers([compiler_dict])
|
||||||
|
Loading…
Reference in New Issue
Block a user