From 212299a0213ec3bc46cda1835fd9d5dbc1e5922b Mon Sep 17 00:00:00 2001 From: Greg Becker Date: Tue, 30 Jun 2020 12:46:20 -0500 Subject: [PATCH] Cray compiler: fix implicit rpaths for classic versions (#17310) * check link dirs for existence --- lib/spack/spack/compiler.py | 4 ++++ lib/spack/spack/test/compilers/basics.py | 10 +++++++- lib/spack/spack/test/conftest.py | 30 +++++++++++++++--------- lib/spack/spack/test/link_paths.py | 9 ++++++- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 0982682081..9f3c4dc1c7 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -152,6 +152,10 @@ def _parse_non_system_link_dirs(string): """ link_dirs = _parse_link_paths(string) + # Remove directories that do not exist. Some versions of the Cray compiler + # report nonexistent directories + link_dirs = [d for d in link_dirs if os.path.isdir(d)] + # Return set of directories containing needed compiler libs, minus # system paths. Note that 'filter_system_paths' only checks for an # exact match, while 'in_system_subdirectory' checks if a path contains diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 9840b9f9af..0888a66c6c 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -159,7 +159,13 @@ def __init__(self): default_compiler_entry['paths']['f77']], environment={}) - _get_compiler_link_paths = Compiler._get_compiler_link_paths + def _get_compiler_link_paths(self, paths): + # 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(MockCompiler, self)._get_compiler_link_paths(paths) + os.path.isdir = old_isdir + return ret @property def name(self): @@ -222,6 +228,7 @@ def call_compiler(exe, *args, **kwargs): ('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() @@ -261,6 +268,7 @@ def test_get_compiler_link_paths_no_verbose_flag(): assert dirs == [] +@pytest.mark.enable_compiler_link_paths def test_get_compiler_link_paths_load_env(working_env, monkeypatch, tmpdir): gcc = str(tmpdir.join('gcc')) with open(gcc, 'w') as f: diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 98f82ca027..0c5689ee53 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -619,18 +619,26 @@ def dirs_with_libfiles(tmpdir_factory): @pytest.fixture(scope='function', autouse=True) -def disable_compiler_execution(monkeypatch): - def noop(*args): - return [] +def disable_compiler_execution(monkeypatch, request): + """ + This fixture can be disabled for tests of the compiler link path + functionality by:: - # Compiler.determine_implicit_rpaths actually runs the compiler. So this - # replaces that function with a noop that simulates finding no implicit - # RPATHs - monkeypatch.setattr( - spack.compiler.Compiler, - '_get_compiler_link_paths', - noop - ) + @pytest.mark.enable_compiler_link_paths + + If a test is marked in that way this is a no-op.""" + if 'enable_compiler_link_paths' not in request.keywords: + def noop(*args): + return [] + + # Compiler.determine_implicit_rpaths actually runs the compiler. So + # replace that function with a noop that simulates finding no implicit + # RPATHs + monkeypatch.setattr( + spack.compiler.Compiler, + '_get_compiler_link_paths', + noop + ) @pytest.fixture(scope='function') diff --git a/lib/spack/spack/test/link_paths.py b/lib/spack/spack/test/link_paths.py index 4ae0a35cf8..79a69942aa 100644 --- a/lib/spack/spack/test/link_paths.py +++ b/lib/spack/spack/test/link_paths.py @@ -2,7 +2,7 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - +import pytest import os import spack.paths @@ -13,6 +13,13 @@ 'compiler_verbose_output') +@pytest.fixture(autouse=True) +def allow_nonexistent_paths(monkeypatch): + # Allow nonexistent paths to be detected as part of the output + # for testing purposes. + monkeypatch.setattr(os.path, 'isdir', lambda x: True) + + def check_link_paths(filename, paths): with open(os.path.join(datadir, filename)) as file: output = file.read()