diff options
author | Harmen Stoppels <me@harmenstoppels.nl> | 2024-03-14 08:54:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-14 08:54:47 +0100 |
commit | c38ef72b0668b02a566ce7f5cee114f776ccc9b6 (patch) | |
tree | 44f01f0658143dba3a3671dbe94e11775b9d4940 | |
parent | 7d67d9ece4c79916162a90965532acd6dfb3abe6 (diff) | |
download | spack-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.py | 37 | ||||
-rw-r--r-- | lib/spack/spack/test/compilers/basics.py | 50 |
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]) |