From fc457b032e004361c6b681d7661259d9565ed866 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 3 Jul 2024 06:44:14 -0600 Subject: [PATCH 01/22] Revert ab957d5b9e867058303e1efc8c257e60fd0e5890 --- lib/spack/env/cc | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/lib/spack/env/cc b/lib/spack/env/cc index d9a10f2a515ac2..ffaa9944df2626 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -233,21 +233,12 @@ fi command="${0##*/}" comp="CC" -vcheck_flags="" case "$command" in cpp) mode=cpp debug_flags="-g" ;; cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe|craycc) - # Edge case for Intel's oneAPI compilers when using the legacy classic compilers: - # Pass flags to disable deprecation warnings to vcheck mode, since the warnings - # to stderr confuse tools that parse the output of compiler version checks. - case ${SPACK_CXXFLAGS} in - *"-diag-disable=10441"* ) - vcheck_flags="-diag-disable=10441" - ;; - esac command="$SPACK_CC" language="C" comp="CC" @@ -255,14 +246,6 @@ case "$command" in debug_flags="-g" ;; c++|CC|g++|clang++|armclang++|icpc|icpx|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++|crayCC) - # Edge case for Intel's oneAPI compilers when using the legacy classic compilers: - # Pass flags to disable deprecation warnings to vcheck mode, since the warnings - # to stderr confuse tools that parse the output of compiler version checks. - case ${SPACK_CXXFLAGS} in - *"-diag-disable=10441"* ) - vcheck_flags="-diag-disable=10441" - ;; - esac command="$SPACK_CXX" language="C++" comp="CXX" @@ -270,14 +253,6 @@ case "$command" in debug_flags="-g" ;; ftn|f90|fc|f95|gfortran|flang|armflang|ifort|ifx|pgfortran|nvfortran|xlf90|xlf90_r|nagfor|frt|amdflang|crayftn) - # Edge case for Intel's oneAPI compilers when using the legacy classic compilers: - # Pass flags to disable deprecation warnings to vcheck mode, since the warnings - # to stderr confuse tools that parse the output of compiler version checks. - case ${SPACK_CXXFLAGS} in - *"-diag-disable=10441"* ) - vcheck_flags="-diag-disable=10441" - ;; - esac command="$SPACK_FC" language="Fortran 90" comp="FC" @@ -390,7 +365,7 @@ unset IFS export PATH="$new_dirs" if [ "$mode" = vcheck ]; then - exec "${command}" ${vcheck_flags} "$@" + exec "${command}" "$@" fi # Darwin's linker has a -r argument that merges object files together. From a3c4cca2651bc534fefd8dcdea5fa576b1d69437 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 3 Jul 2024 15:38:01 -0600 Subject: [PATCH 02/22] Alternative implementation of ALWAYS flags --- lib/spack/env/cc | 12 +++++++++++- lib/spack/spack/compilers/intel.py | 11 +++++++++++ lib/spack/spack/compilers/oneapi.py | 11 +++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/spack/env/cc b/lib/spack/env/cc index ffaa9944df2626..cd67c8b2b6388f 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -233,10 +233,12 @@ fi command="${0##*/}" comp="CC" +vcheck_flags="" case "$command" in cpp) mode=cpp debug_flags="-g" + vcheck_flags="${SPACK_ALWAYS_CPPFLAGS}" ;; cc|c89|c99|gcc|clang|armclang|icc|icx|pgcc|nvc|xlc|xlc_r|fcc|amdclang|cl.exe|craycc) command="$SPACK_CC" @@ -244,6 +246,7 @@ case "$command" in comp="CC" lang_flags=C debug_flags="-g" + vcheck_flags="${SPACK_ALWAYS_CFLAGS}" ;; c++|CC|g++|clang++|armclang++|icpc|icpx|pgc++|nvc++|xlc++|xlc++_r|FCC|amdclang++|crayCC) command="$SPACK_CXX" @@ -251,6 +254,7 @@ case "$command" in comp="CXX" lang_flags=CXX debug_flags="-g" + vcheck_flags="${SPACK_ALWAYS_CXXFLAGS}" ;; ftn|f90|fc|f95|gfortran|flang|armflang|ifort|ifx|pgfortran|nvfortran|xlf90|xlf90_r|nagfor|frt|amdflang|crayftn) command="$SPACK_FC" @@ -258,6 +262,7 @@ case "$command" in comp="FC" lang_flags=F debug_flags="-g" + vcheck_flags="${SPACK_ALWAYS_FFLAGS}" ;; f77|xlf|xlf_r|pgf77) command="$SPACK_F77" @@ -265,6 +270,7 @@ case "$command" in comp="F77" lang_flags=F debug_flags="-g" + vcheck_flags="${SPACK_ALWAYS_FFLAGS}" ;; ld|ld.gold|ld.lld) mode=ld @@ -365,7 +371,7 @@ unset IFS export PATH="$new_dirs" if [ "$mode" = vcheck ]; then - exec "${command}" "$@" + exec "${command}" ${vcheck_flags} "$@" fi # Darwin's linker has a -r argument that merges object files together. @@ -722,6 +728,7 @@ case "$mode" in cc|ccld) case $lang_flags in F) + extend spack_flags_list SPACK_ALWAYS_FFLAGS extend spack_flags_list SPACK_FFLAGS ;; esac @@ -731,6 +738,7 @@ esac # C preprocessor flags come before any C/CXX flags case "$mode" in cpp|as|cc|ccld) + extend spack_flags_list SPACK_ALWAYS_CPPFLAGS extend spack_flags_list SPACK_CPPFLAGS ;; esac @@ -741,9 +749,11 @@ case "$mode" in cc|ccld) case $lang_flags in C) + extend spack_flags_list SPACK_ALWAYS_CFLAGS extend spack_flags_list SPACK_CFLAGS ;; CXX) + extend spack_flags_list SPACK_ALWAYS_CXXFLAGS extend spack_flags_list SPACK_CXXFLAGS ;; esac diff --git a/lib/spack/spack/compilers/intel.py b/lib/spack/spack/compilers/intel.py index c7b0d8033c6eaa..023248b86e57e5 100644 --- a/lib/spack/spack/compilers/intel.py +++ b/lib/spack/spack/compilers/intel.py @@ -126,3 +126,14 @@ def fc_pic_flag(self): @property def stdcxx_libs(self): return ("-cxxlib",) + + def setup_custom_environment(self, pkg, env): + # Edge cases for Intel's oneAPI compilers when using the legacy classic compilers: + # Always pass flags to disable deprecation warnings, since these warnings can + # confuse tools that parse the output of compiler commands (e.g. version checks). + if self.cc and self.cc.endswith("icc") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_CFLAGS", "-diag-disable=10441") + if self.cxx and self.cxx.endswith("icpc") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_CXXFLAGS", "-diag-disable=10441") + if self.fc and self.fc.endswith("ifort") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_FFLAGS", "-diag-disable=10448") diff --git a/lib/spack/spack/compilers/oneapi.py b/lib/spack/spack/compilers/oneapi.py index ecba99081a4b95..fd8908be13bca8 100644 --- a/lib/spack/spack/compilers/oneapi.py +++ b/lib/spack/spack/compilers/oneapi.py @@ -9,6 +9,7 @@ from llnl.util import tty from spack.compiler import Compiler +from spack.version import Version class Oneapi(Compiler): @@ -138,6 +139,16 @@ def setup_custom_environment(self, pkg, env): if self.cxx: env.prepend_path("PATH", dirname(self.cxx)) + # Edge cases for Intel's oneAPI compilers when using the legacy classic compilers: + # Always pass flags to disable deprecation warnings, since these warnings can + # confuse tools that parse the output of compiler commands (e.g. version checks). + if self.cc and self.cc.endswith("icc") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_CFLAGS", "-diag-disable=10441") + if self.cxx and self.cxx.endswith("icpc") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_CXXFLAGS", "-diag-disable=10441") + if self.fc and self.fc.endswith("ifort") and self.real_version >= Version("2021"): + env.append_flags("SPACK_ALWAYS_FFLAGS", "-diag-disable=10448") + # 2024 release bumped the libsycl version because of an ABI # change, 2024 compilers are required. You will see this # error: From 97789df6a92160205c75256b8dccc0e46dc4cdd7 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Tue, 23 Jul 2024 14:24:36 +0200 Subject: [PATCH 03/22] Fix formatting in lib/spack/spack/test/compilers/basics.py From 2bf305f51822ec356cebd641b744c2f8f4462296 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Tue, 23 Jul 2024 22:31:40 +0200 Subject: [PATCH 04/22] Fix next formatting error in lib/spack/spack/test/compilers/basics.py --- lib/spack/spack/test/compilers/basics.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 2c46d434d1ad3f..86781ce9a1d27f 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -957,3 +957,17 @@ def test_compiler_environment(working_env): ) with compiler.compiler_environment(): assert os.environ["TEST"] == "yes" + + +def test_compiler_environment_always_flags(working_env): + """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the compiler environment""" + compiler = Compiler( + "oneapi@=2023.2.0", + operating_system="ubuntu22.04", + target="x86_64", + paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], + ) + with compiler.compiler_environment(): + assert os.environ["SPACK_ALWAYS_CFLAGS"] == "-diag-disable=10441" + assert os.environ["SPACK_ALWAYS_CXXFLAGS"] == "-diag-disable=10441" + assert os.environ["SPACK_ALWAYS_FCFLAGS"] == "-diag-disable=10448" From 27af4d6aa32fa1c682dd1e182b14d71bc276537d Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 14:35:33 +0200 Subject: [PATCH 05/22] Proper testing of environment modifications for Intel and Oneapi always flags --- lib/spack/spack/test/compilers/basics.py | 58 +++++++++++++++++++++--- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 86781ce9a1d27f..feef18300ab1bd 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -16,7 +16,11 @@ import spack.util.environment import spack.util.module_cmd from spack.compiler import Compiler +from spack.compilers.intel import Intel +from spack.compilers.oneapi import Oneapi from spack.util.executable import Executable, ProcessError +from spack.util.environment import EnvironmentModifications +from spack.version import Version @pytest.fixture() @@ -959,15 +963,55 @@ def test_compiler_environment(working_env): assert os.environ["TEST"] == "yes" -def test_compiler_environment_always_flags(working_env): - """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the compiler environment""" - compiler = Compiler( +def test_compiler_environment_always_flags_oneapi(working_env): + """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the Oneapi compiler environment""" + + class MockOneapiCompiler(Oneapi): + @property + def version(self): + return Version("2023.2.0") + + with spack.config.override("config:install_missing_compilers", True): + with spack.concretize.disable_compiler_existence_check(): + s = spack.spec.Spec("zlib%oneapi@=2023.2.0").concretized() + pkg = spack.package.Package(s) + + compiler = MockOneapiCompiler( "oneapi@=2023.2.0", operating_system="ubuntu22.04", target="x86_64", paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], ) - with compiler.compiler_environment(): - assert os.environ["SPACK_ALWAYS_CFLAGS"] == "-diag-disable=10441" - assert os.environ["SPACK_ALWAYS_CXXFLAGS"] == "-diag-disable=10441" - assert os.environ["SPACK_ALWAYS_FCFLAGS"] == "-diag-disable=10448" + env = EnvironmentModifications() + compiler.setup_custom_environment(pkg, env) + shell_modifications = env.shell_modifications() + assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications + + +def test_compiler_environment_always_flags_intel(working_env): + """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the Intel compiler environment""" + + class MockIntelCompiler(Intel): + @property + def version(self): + return Version("2023.2.0") + + with spack.config.override("config:install_missing_compilers", True): + with spack.concretize.disable_compiler_existence_check(): + s = spack.spec.Spec("zlib%intel@=2023.2.0").concretized() + pkg = spack.package.Package(s) + + compiler = MockIntelCompiler( + "intel@=2023.2.0", + operating_system="ubuntu22.04", + target="x86_64", + paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], + ) + env = EnvironmentModifications() + compiler.setup_custom_environment(pkg, env) + shell_modifications = env.shell_modifications() + assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications From e9317d483f18e57fb9e0bedcbe404b772b780488 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 14:42:44 +0200 Subject: [PATCH 06/22] Fix formatting errors in lib/spack/spack/test/compilers/basics.py --- lib/spack/spack/test/compilers/basics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index feef18300ab1bd..78c06367abca54 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -18,8 +18,8 @@ from spack.compiler import Compiler from spack.compilers.intel import Intel from spack.compilers.oneapi import Oneapi -from spack.util.executable import Executable, ProcessError from spack.util.environment import EnvironmentModifications +from spack.util.executable import Executable, ProcessError from spack.version import Version From 9196d6c0565666a985859329f536096ce2ae52cd Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 15:08:06 +0200 Subject: [PATCH 07/22] Fix compiler for gcc-runtime in newly added tests (envmods intel/oneapi always flags) --- lib/spack/spack/test/compilers/basics.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 78c06367abca54..9af6f97089f2a7 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -973,7 +973,7 @@ def version(self): with spack.config.override("config:install_missing_compilers", True): with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%oneapi@=2023.2.0").concretized() + s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^gcc-runtime%gcc").concretized() pkg = spack.package.Package(s) compiler = MockOneapiCompiler( @@ -1000,7 +1000,7 @@ def version(self): with spack.config.override("config:install_missing_compilers", True): with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%intel@=2023.2.0").concretized() + s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc").concretized() pkg = spack.package.Package(s) compiler = MockIntelCompiler( From 1a0fe52a0767eb456e890999803280138132a74c Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Mon, 29 Jul 2024 12:55:09 +0200 Subject: [PATCH 08/22] Pin gcc to 10.2.1 in new tests in lib/spack/spack/test/compilers/basics.py --- lib/spack/spack/test/compilers/basics.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 9af6f97089f2a7..8a15b3cb78bfa8 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -964,7 +964,8 @@ def test_compiler_environment(working_env): def test_compiler_environment_always_flags_oneapi(working_env): - """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the Oneapi compiler environment""" + """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Oneapi compiler + environment""" class MockOneapiCompiler(Oneapi): @property @@ -973,7 +974,7 @@ def version(self): with spack.config.override("config:install_missing_compilers", True): with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^gcc-runtime%gcc").concretized() + s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^intel-oneapi-runtime%gcc@10.2.1").concretized() pkg = spack.package.Package(s) compiler = MockOneapiCompiler( @@ -991,7 +992,8 @@ def version(self): def test_compiler_environment_always_flags_intel(working_env): - """Test whether flags labeled as "ALWAYS_*FLAGS" are set in the Intel compiler environment""" + """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Intel compiler + environment""" class MockIntelCompiler(Intel): @property @@ -1000,7 +1002,7 @@ def version(self): with spack.config.override("config:install_missing_compilers", True): with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc").concretized() + s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() pkg = spack.package.Package(s) compiler = MockIntelCompiler( From 6a56139c0707d559e70e268ba9ebd4862c54ebfd Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Sun, 4 Aug 2024 18:34:12 -0600 Subject: [PATCH 09/22] Fix formatting in lib/spack/spack/test/compilers/basics.py From 5b2b3902becdc32d9e1b3ac627892d0d494b631d Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Tue, 23 Jul 2024 22:31:40 +0200 Subject: [PATCH 10/22] Fix next formatting error in lib/spack/spack/test/compilers/basics.py From 1969277b409997ab86cfee93546b1dff627d86b1 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 14:35:33 +0200 Subject: [PATCH 11/22] Proper testing of environment modifications for Intel and Oneapi always flags From c4863c6370fcccf48234900bbaaab994fac5b842 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 14:42:44 +0200 Subject: [PATCH 12/22] Fix formatting errors in lib/spack/spack/test/compilers/basics.py From a5c6c70e061cc6fddf06be699da1f7edc6165c12 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 24 Jul 2024 15:08:06 +0200 Subject: [PATCH 13/22] Fix compiler for gcc-runtime in newly added tests (envmods intel/oneapi always flags) From b84e234bae664a5957e4c4e40af7945bca585208 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Mon, 29 Jul 2024 12:55:09 +0200 Subject: [PATCH 14/22] Pin gcc to 10.2.1 in new tests in lib/spack/spack/test/compilers/basics.py From 2285722495eec94a2cf99e09728cfd853ebe538a Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Sun, 4 Aug 2024 18:34:12 -0600 Subject: [PATCH 15/22] Fix formatting in lib/spack/spack/test/compilers/basics.py From aef88bd0938fd53b3cadfd7c22cedd6fd507f66c Mon Sep 17 00:00:00 2001 From: Peter Josef Scheibel Date: Tue, 6 Aug 2024 11:23:12 -0700 Subject: [PATCH 16/22] use more-generic tests --- lib/spack/env/cc | 83 +++++++++++++---------- lib/spack/spack/test/build_environment.py | 17 +++++ lib/spack/spack/test/cc.py | 9 +++ lib/spack/spack/test/compilers/basics.py | 60 ---------------- 4 files changed, 72 insertions(+), 97 deletions(-) diff --git a/lib/spack/env/cc b/lib/spack/env/cc index cd67c8b2b6388f..a9dcb3a58b3914 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -174,6 +174,46 @@ preextend() { unset IFS } +execute() { + # dump the full command if the caller supplies SPACK_TEST_COMMAND=dump-args + if [ -n "${SPACK_TEST_COMMAND=}" ]; then + case "$SPACK_TEST_COMMAND" in + dump-args) + IFS="$lsep" + for arg in $full_command_list; do + echo "$arg" + done + unset IFS + exit + ;; + dump-env-*) + var=${SPACK_TEST_COMMAND#dump-env-} + eval "printf '%s\n' \"\$0: \$var: \$$var\"" + ;; + *) + die "Unknown test command: '$SPACK_TEST_COMMAND'" + ;; + esac + fi + + # + # Write the input and output commands to debug logs if it's asked for. + # + if [ "$SPACK_DEBUG" = TRUE ]; then + input_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.in.log" + output_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.out.log" + echo "[$mode] $command $input_command" >> "$input_log" + IFS="$lsep" + echo "[$mode] "$full_command_list >> "$output_log" + unset IFS + fi + + # Execute the full command, preserving spaces with IFS set + # to the alarm bell separator. + IFS="$lsep"; exec $full_command_list + exit +} + # Fail with a clear message if the input contains any bell characters. if eval "[ \"\${*#*${lsep}}\" != \"\$*\" ]"; then die "Compiler command line contains our separator ('${lsep}'). Cannot parse." @@ -371,7 +411,11 @@ unset IFS export PATH="$new_dirs" if [ "$mode" = vcheck ]; then - exec "${command}" ${vcheck_flags} "$@" + full_command_list="$command" + args="$@" + extend full_command_list vcheck_flags + extend full_command_list args + execute fi # Darwin's linker has a -r argument that merges object files together. @@ -943,39 +987,4 @@ if [ -n "$SPACK_CCACHE_BINARY" ]; then esac fi -# dump the full command if the caller supplies SPACK_TEST_COMMAND=dump-args -if [ -n "${SPACK_TEST_COMMAND=}" ]; then - case "$SPACK_TEST_COMMAND" in - dump-args) - IFS="$lsep" - for arg in $full_command_list; do - echo "$arg" - done - unset IFS - exit - ;; - dump-env-*) - var=${SPACK_TEST_COMMAND#dump-env-} - eval "printf '%s\n' \"\$0: \$var: \$$var\"" - ;; - *) - die "Unknown test command: '$SPACK_TEST_COMMAND'" - ;; - esac -fi - -# -# Write the input and output commands to debug logs if it's asked for. -# -if [ "$SPACK_DEBUG" = TRUE ]; then - input_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.in.log" - output_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_DEBUG_LOG_ID.out.log" - echo "[$mode] $command $input_command" >> "$input_log" - IFS="$lsep" - echo "[$mode] "$full_command_list >> "$output_log" - unset IFS -fi - -# Execute the full command, preserving spaces with IFS set -# to the alarm bell separator. -IFS="$lsep"; exec $full_command_list +execute diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index cb47ee5977ca1e..cc85ca69d439b7 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -286,6 +286,23 @@ def platform_pathsep(pathlist): assert name not in os.environ +def test_compiler_custom_env(monkeypatch): + def custom_env(pkg, env): + env.prepend_path("PATH", "/test/path/element/custom-env/") + env.prepend_path("LD_LIBRARY_PATH", "/test/path/element/custom-env/") + env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1") + + # Monkeypatch a pkg.compiler.environment with the required modifications + pkg = spack.spec.Spec("cmake").concretized().package + monkeypatch.setattr(pkg.compiler, "setup_custom_environment", custom_env) + # Trigger the modifications + spack.build_environment.setup_package(pkg, False) + + # Note: trailing slash may be stripped by internal logic + assert "/test/path/element/custom-env" in os.environ["PATH"] + assert "--custom-env-flag1" in os.environ["ENV_CUSTOM_CC_FLAGS"] + + def test_external_config_env(mock_packages, mutable_config, working_env): cmake_config = { "externals": [ diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py index dfff73811ab9ce..bf119d2d509add 100644 --- a/lib/spack/spack/test/cc.py +++ b/lib/spack/spack/test/cc.py @@ -355,6 +355,15 @@ def test_fc_flags(wrapper_environment, wrapper_flags): ) +def test_always_cflags(wrapper_environment, wrapper_flags): + with set_env(SPACK_ALWAYS_CFLAGS="-always1 -always2"): + check_args( + cc, + ["-v", "--cmd-line-v-opt"], + [real_cc] + ["-always1", "-always2"] + ["-v", "--cmd-line-v-opt"], + ) + + def test_Wl_parsing(wrapper_environment): check_args( cc, diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py index 8a15b3cb78bfa8..2c46d434d1ad3f 100644 --- a/lib/spack/spack/test/compilers/basics.py +++ b/lib/spack/spack/test/compilers/basics.py @@ -16,11 +16,7 @@ import spack.util.environment import spack.util.module_cmd from spack.compiler import Compiler -from spack.compilers.intel import Intel -from spack.compilers.oneapi import Oneapi -from spack.util.environment import EnvironmentModifications from spack.util.executable import Executable, ProcessError -from spack.version import Version @pytest.fixture() @@ -961,59 +957,3 @@ def test_compiler_environment(working_env): ) with compiler.compiler_environment(): assert os.environ["TEST"] == "yes" - - -def test_compiler_environment_always_flags_oneapi(working_env): - """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Oneapi compiler - environment""" - - class MockOneapiCompiler(Oneapi): - @property - def version(self): - return Version("2023.2.0") - - with spack.config.override("config:install_missing_compilers", True): - with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^intel-oneapi-runtime%gcc@10.2.1").concretized() - pkg = spack.package.Package(s) - - compiler = MockOneapiCompiler( - "oneapi@=2023.2.0", - operating_system="ubuntu22.04", - target="x86_64", - paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], - ) - env = EnvironmentModifications() - compiler.setup_custom_environment(pkg, env) - shell_modifications = env.shell_modifications() - assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications - - -def test_compiler_environment_always_flags_intel(working_env): - """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Intel compiler - environment""" - - class MockIntelCompiler(Intel): - @property - def version(self): - return Version("2023.2.0") - - with spack.config.override("config:install_missing_compilers", True): - with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() - pkg = spack.package.Package(s) - - compiler = MockIntelCompiler( - "intel@=2023.2.0", - operating_system="ubuntu22.04", - target="x86_64", - paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], - ) - env = EnvironmentModifications() - compiler.setup_custom_environment(pkg, env) - shell_modifications = env.shell_modifications() - assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications From 9637680260261fcb73293dc0add9556e91d8cead Mon Sep 17 00:00:00 2001 From: Peter Josef Scheibel Date: Tue, 6 Aug 2024 12:08:24 -0700 Subject: [PATCH 17/22] missing needed fixtures for test --- lib/spack/spack/test/build_environment.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index cc85ca69d439b7..660320b92aed52 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -286,16 +286,14 @@ def platform_pathsep(pathlist): assert name not in os.environ -def test_compiler_custom_env(monkeypatch): +def test_compiler_custom_env(config, mock_packages, monkeypatch, working_env): def custom_env(pkg, env): env.prepend_path("PATH", "/test/path/element/custom-env/") env.prepend_path("LD_LIBRARY_PATH", "/test/path/element/custom-env/") env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1") - # Monkeypatch a pkg.compiler.environment with the required modifications pkg = spack.spec.Spec("cmake").concretized().package monkeypatch.setattr(pkg.compiler, "setup_custom_environment", custom_env) - # Trigger the modifications spack.build_environment.setup_package(pkg, False) # Note: trailing slash may be stripped by internal logic From 447f5b8ba0e8ce346522569d3308994bf1c5178e Mon Sep 17 00:00:00 2001 From: Peter Josef Scheibel Date: Tue, 6 Aug 2024 12:49:08 -0700 Subject: [PATCH 18/22] make test more portable --- lib/spack/spack/test/build_environment.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index 660320b92aed52..a7cd5f9609e17e 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -6,6 +6,7 @@ import os import platform import posixpath +import sys import pytest @@ -287,9 +288,13 @@ def platform_pathsep(pathlist): def test_compiler_custom_env(config, mock_packages, monkeypatch, working_env): + if sys.platform == "win32": + test_path = r"C:\test\path\element\custom-env\\" + else: + test_path = r"/test/path/element/custom-env/" + def custom_env(pkg, env): env.prepend_path("PATH", "/test/path/element/custom-env/") - env.prepend_path("LD_LIBRARY_PATH", "/test/path/element/custom-env/") env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1") pkg = spack.spec.Spec("cmake").concretized().package @@ -297,7 +302,7 @@ def custom_env(pkg, env): spack.build_environment.setup_package(pkg, False) # Note: trailing slash may be stripped by internal logic - assert "/test/path/element/custom-env" in os.environ["PATH"] + assert test_path[:-1] in os.environ["PATH"] assert "--custom-env-flag1" in os.environ["ENV_CUSTOM_CC_FLAGS"] From 5924ba35baaf12416ee5f943792a8efe4c3004b6 Mon Sep 17 00:00:00 2001 From: Peter Josef Scheibel Date: Tue, 6 Aug 2024 13:32:48 -0700 Subject: [PATCH 19/22] attempt to resolve tension between raw string and trailing backslash --- lib/spack/spack/test/build_environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index a7cd5f9609e17e..1467251987435d 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -289,7 +289,7 @@ def platform_pathsep(pathlist): def test_compiler_custom_env(config, mock_packages, monkeypatch, working_env): if sys.platform == "win32": - test_path = r"C:\test\path\element\custom-env\\" + test_path = r"C:\test\path\element\custom-env" + "\\" else: test_path = r"/test/path/element/custom-env/" From 6e42bc0c9ad4da9993067160840b637733f16f41 Mon Sep 17 00:00:00 2001 From: Peter Josef Scheibel Date: Tue, 6 Aug 2024 15:28:04 -0700 Subject: [PATCH 20/22] fix missing reference --- lib/spack/spack/test/build_environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index 1467251987435d..d06bda58fdbc48 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -294,7 +294,7 @@ def test_compiler_custom_env(config, mock_packages, monkeypatch, working_env): test_path = r"/test/path/element/custom-env/" def custom_env(pkg, env): - env.prepend_path("PATH", "/test/path/element/custom-env/") + env.prepend_path("PATH", test_path) env.append_flags("ENV_CUSTOM_CC_FLAGS", "--custom-env-flag1") pkg = spack.spec.Spec("cmake").concretized().package From 7e8da8684d26fc01e6de91c988c71296b5b35079 Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Tue, 6 Aug 2024 18:05:56 -0600 Subject: [PATCH 21/22] Add inline documentation/comment on new SPACK_ALWAYS_XFLAGS in lib/spack/env/cc --- lib/spack/env/cc | 3 + lib/spack/spack/test/compilers/basics.py.orig | 1028 +++++++++++++++++ lib/spack/spack/test/compilers/basics.py.rej | 17 + 3 files changed, 1048 insertions(+) create mode 100644 lib/spack/spack/test/compilers/basics.py.orig create mode 100644 lib/spack/spack/test/compilers/basics.py.rej diff --git a/lib/spack/env/cc b/lib/spack/env/cc index a9dcb3a58b3914..ccfc14bb89dc53 100755 --- a/lib/spack/env/cc +++ b/lib/spack/env/cc @@ -271,6 +271,9 @@ fi # ld link # ccld compile & link +# Note. SPACK_ALWAYS_XFLAGS are applied for all compiler invocations, +# including version checks (SPACK_XFLAGS variants are not applied +# for version checks). command="${0##*/}" comp="CC" vcheck_flags="" diff --git a/lib/spack/spack/test/compilers/basics.py.orig b/lib/spack/spack/test/compilers/basics.py.orig new file mode 100644 index 00000000000000..397732868e538a --- /dev/null +++ b/lib/spack/spack/test/compilers/basics.py.orig @@ -0,0 +1,1028 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) +"""Test basic behavior of compilers in Spack""" +import os +from copy import copy + +import pytest + +import llnl.util.filesystem as fs + +import spack.compiler +import spack.compilers +import spack.spec +import spack.util.environment +import spack.util.module_cmd +from spack.compiler import Compiler +from spack.compilers.intel import Intel +from spack.compilers.oneapi import Oneapi +from spack.util.environment import EnvironmentModifications +from spack.util.executable import Executable, ProcessError +from spack.version import Version + + +@pytest.fixture() +def make_args_for_version(monkeypatch): + def _factory(version, path="/usr/bin/gcc"): + class MockOs: + pass + + compiler_name = "gcc" + compiler_cls = spack.compilers.class_for_compiler_name(compiler_name) + monkeypatch.setattr(compiler_cls, "cc_version", lambda x: version) + + compiler_id = spack.compilers.CompilerID( + os=MockOs, compiler_name=compiler_name, version=None + ) + variation = spack.compilers.NameVariation(prefix="", suffix="") + return spack.compilers.DetectVersionArgs( + id=compiler_id, variation=variation, language="cc", path=path + ) + + return _factory + + +def test_multiple_conflicting_compiler_definitions(mutable_config): + compiler_def = { + "compiler": { + "flags": {}, + "modules": [], + "paths": {"cc": "cc", "cxx": "cxx", "f77": "null", "fc": "null"}, + "extra_rpaths": [], + "operating_system": "test", + "target": "test", + "environment": {}, + "spec": "clang@0.0.0", + } + } + + compiler_config = [compiler_def, compiler_def] + compiler_config[0]["compiler"]["paths"]["f77"] = "f77" + mutable_config.update_config("compilers", compiler_config) + + arch_spec = spack.spec.ArchSpec(("test", "test", "test")) + cmp = spack.compilers.compiler_for_spec("clang@=0.0.0", arch_spec) + assert cmp.f77 == "f77" + + +def test_get_compiler_duplicates(mutable_config, compiler_factory): + # In this case there is only one instance of the specified compiler in + # the test configuration (so it is not actually a duplicate), but the + # method behaves the same. + cnl_compiler = compiler_factory(spec="gcc@4.5.0", operating_system="CNL") + # CNL compiler has no target attribute, and this is essential to make detection pass + del cnl_compiler["compiler"]["target"] + mutable_config.set( + "compilers", [compiler_factory(spec="gcc@4.5.0", operating_system="SuSE11"), cnl_compiler] + ) + cfg_file_to_duplicates = spack.compilers.get_compiler_duplicates( + "gcc@4.5.0", spack.spec.ArchSpec("cray-CNL-xeon") + ) + + assert len(cfg_file_to_duplicates) == 1 + cfg_file, duplicates = next(iter(cfg_file_to_duplicates.items())) + assert len(duplicates) == 1 + + +@pytest.mark.parametrize( + "input_version,expected_version,expected_error", + [(None, None, "Couldn't get version for compiler /usr/bin/gcc"), ("4.9", "4.9", None)], +) +def test_version_detection_is_empty( + make_args_for_version, input_version, expected_version, expected_error +): + args = make_args_for_version(version=input_version) + result, error = spack.compilers.detect_version(args) + if not error: + assert result.id.version == expected_version + + assert error == expected_error + + +def test_compiler_flags_from_config_are_grouped(): + compiler_entry = { + "spec": "intel@17.0.2", + "operating_system": "foo-os", + "paths": {"cc": "cc-path", "cxx": "cxx-path", "fc": None, "f77": None}, + "flags": {"cflags": "-O0 -foo-flag foo-val"}, + "modules": None, + } + + compiler = spack.compilers.compiler_from_dict(compiler_entry) + assert any(x == "-foo-flag foo-val" for x in compiler.flags["cflags"]) + + +# Test behavior of flags and UnsupportedCompilerFlag. + +# Utility function to test most flags. +default_compiler_entry = { + "spec": "apple-clang@2.0.0", + "operating_system": "foo-os", + "paths": {"cc": "cc-path", "cxx": "cxx-path", "fc": "fc-path", "f77": "f77-path"}, + "flags": {}, + "modules": None, +} + + +# Fake up a mock compiler where everything is defaulted. +class MockCompiler(Compiler): + def __init__(self): + super().__init__( + cspec="badcompiler@1.0.0", + operating_system=default_compiler_entry["operating_system"], + target=None, + paths=[ + default_compiler_entry["paths"]["cc"], + default_compiler_entry["paths"]["cxx"], + default_compiler_entry["paths"]["fc"], + default_compiler_entry["paths"]["f77"], + ], + environment={}, + ) + + @property + def name(self): + return "mockcompiler" + + @property + def version(self): + return "1.0.0" + + _verbose_flag = "--verbose" + + @property + def verbose_flag(self): + return self._verbose_flag + + required_libs = ["libgfortran"] + + +@pytest.mark.not_on_windows("Not supported on Windows (yet)") +def test_implicit_rpaths(dirs_with_libfiles): + lib_to_dirs, all_dirs = dirs_with_libfiles + compiler = MockCompiler() + compiler._compile_c_source_output = "ld " + " ".join(f"-L{d}" for d in all_dirs) + retrieved_rpaths = compiler.implicit_rpaths() + assert set(retrieved_rpaths) == set(lib_to_dirs["libstdc++"] + lib_to_dirs["libgfortran"]) + + +without_flag_output = "ld -L/path/to/first/lib -L/path/to/second/lib64" +with_flag_output = "ld -L/path/to/first/with/flag/lib -L/path/to/second/lib64" + + +def call_compiler(exe, *args, **kwargs): + # This method can replace Executable.__call__ to emulate a compiler that + # changes libraries depending on a flag. + if "--correct-flag" in exe.exe: + return with_flag_output + return without_flag_output + + +@pytest.mark.not_on_windows("Not supported on Windows (yet)") +@pytest.mark.parametrize( + "exe,flagname", + [ + ("cxx", "cxxflags"), + ("cxx", "cppflags"), + ("cxx", "ldflags"), + ("cc", "cflags"), + ("cc", "cppflags"), + ], +) +@pytest.mark.enable_compiler_execution +def test_compile_dummy_c_source_adds_flags(monkeypatch, exe, flagname): + # create fake compiler that emits mock verbose output + compiler = MockCompiler() + 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 + assert compiler._compile_dummy_c_source() == without_flag_output + + if flagname: + # set flags and test + compiler.flags = {flagname: ["--correct-flag"]} + assert compiler._compile_dummy_c_source() == with_flag_output + + +@pytest.mark.enable_compiler_execution +def test_compile_dummy_c_source_no_path(): + compiler = MockCompiler() + compiler.cc = None + compiler.cxx = None + assert compiler._compile_dummy_c_source() is None + + +@pytest.mark.enable_compiler_execution +def test_compile_dummy_c_source_no_verbose_flag(): + compiler = MockCompiler() + compiler._verbose_flag = None + assert compiler._compile_dummy_c_source() is None + + +@pytest.mark.not_on_windows("Not supported on Windows (yet)") +@pytest.mark.enable_compiler_execution +def test_compile_dummy_c_source_load_env(working_env, monkeypatch, tmpdir): + gcc = str(tmpdir.join("gcc")) + with open(gcc, "w") as f: + f.write( + f"""#!/bin/sh +if [ "$ENV_SET" = "1" ] && [ "$MODULE_LOADED" = "1" ]; then + printf '{without_flag_output}' +fi +""" + ) + fs.set_executable(gcc) + + # Set module load to turn compiler on + def module(*args): + if args[0] == "show": + return "" + elif args[0] == "load": + os.environ["MODULE_LOADED"] = "1" + + monkeypatch.setattr(spack.util.module_cmd, "module", module) + + compiler = MockCompiler() + compiler.cc = gcc + compiler.environment = {"set": {"ENV_SET": "1"}} + compiler.modules = ["turn_on"] + + assert compiler._compile_dummy_c_source() == without_flag_output + + +# Get the desired flag from the specified compiler spec. +def flag_value(flag, spec): + compiler = None + if spec is None: + compiler = MockCompiler() + else: + compiler_entry = copy(default_compiler_entry) + compiler_entry["spec"] = spec + compiler = spack.compilers.compiler_from_dict(compiler_entry) + + return getattr(compiler, flag) + + +# Utility function to verify that the expected exception is thrown for +# an unsupported flag. +def unsupported_flag_test(flag, spec=None): + caught_exception = None + try: + flag_value(flag, spec) + except spack.compiler.UnsupportedCompilerFlag: + caught_exception = True + + assert caught_exception and "Expected exception not thrown." + + +# Verify the expected flag value for the give compiler spec. +def supported_flag_test(flag, flag_value_ref, spec=None): + assert flag_value(flag, spec) == flag_value_ref + + +# Tests for UnsupportedCompilerFlag exceptions from default +# implementations of flags. +def test_default_flags(): + supported_flag_test("cc_rpath_arg", "-Wl,-rpath,") + supported_flag_test("cxx_rpath_arg", "-Wl,-rpath,") + supported_flag_test("f77_rpath_arg", "-Wl,-rpath,") + supported_flag_test("fc_rpath_arg", "-Wl,-rpath,") + supported_flag_test("linker_arg", "-Wl,") + unsupported_flag_test("openmp_flag") + unsupported_flag_test("cxx11_flag") + unsupported_flag_test("cxx14_flag") + unsupported_flag_test("cxx17_flag") + supported_flag_test("cxx98_flag", "") + unsupported_flag_test("c99_flag") + unsupported_flag_test("c11_flag") + supported_flag_test("cc_pic_flag", "-fPIC") + supported_flag_test("cxx_pic_flag", "-fPIC") + supported_flag_test("f77_pic_flag", "-fPIC") + supported_flag_test("fc_pic_flag", "-fPIC") + supported_flag_test("debug_flags", ["-g"]) + supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3"]) + + +# Verify behavior of particular compiler definitions. +def test_arm_flags(): + supported_flag_test("openmp_flag", "-fopenmp", "arm@1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "arm@1.0") + supported_flag_test("cxx14_flag", "-std=c++14", "arm@1.0") + supported_flag_test("cxx17_flag", "-std=c++1z", "arm@1.0") + supported_flag_test("c99_flag", "-std=c99", "arm@1.0") + supported_flag_test("c11_flag", "-std=c11", "arm@1.0") + supported_flag_test("cc_pic_flag", "-fPIC", "arm@1.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "arm@1.0") + supported_flag_test("f77_pic_flag", "-fPIC", "arm@1.0") + supported_flag_test("fc_pic_flag", "-fPIC", "arm@1.0") + supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast"], "arm@1.0") + + +def test_cce_flags(): + supported_flag_test("version_argument", "--version", "cce@9.0.1") + supported_flag_test("version_argument", "-V", "cce@9.0.1-classic") + supported_flag_test("openmp_flag", "-fopenmp", "cce@9.0.1") + supported_flag_test("openmp_flag", "-h omp", "cce@9.0.1-classic") + supported_flag_test("openmp_flag", "-h omp", "cce@1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "cce@9.0.1") + supported_flag_test("cxx11_flag", "-h std=c++11", "cce@9.0.1-classic") + supported_flag_test("cxx11_flag", "-h std=c++11", "cce@1.0") + unsupported_flag_test("c99_flag", "cce@8.0") + supported_flag_test("c99_flag", "-std=c99", "cce@9.0.1") + supported_flag_test("c99_flag", "-h c99,noconform,gnu", "cce@8.1") + supported_flag_test("c99_flag", "-h std=c99,noconform,gnu", "cce@8.4") + unsupported_flag_test("c11_flag", "cce@8.4") + supported_flag_test("c11_flag", "-std=c11", "cce@9.0.1") + supported_flag_test("c11_flag", "-h std=c11,noconform,gnu", "cce@8.5") + supported_flag_test("cc_pic_flag", "-h PIC", "cce@1.0") + supported_flag_test("cxx_pic_flag", "-h PIC", "cce@1.0") + supported_flag_test("f77_pic_flag", "-h PIC", "cce@1.0") + supported_flag_test("fc_pic_flag", "-h PIC", "cce@1.0") + supported_flag_test("cc_pic_flag", "-fPIC", "cce@9.1.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "cce@9.1.0") + supported_flag_test("f77_pic_flag", "-fPIC", "cce@9.1.0") + supported_flag_test("fc_pic_flag", "-fPIC", "cce@9.1.0") + supported_flag_test("stdcxx_libs", (), "cce@1.0") + supported_flag_test("debug_flags", ["-g", "-G0", "-G1", "-G2", "-Gfast"], "cce@1.0") + + +def test_apple_clang_flags(): + supported_flag_test("openmp_flag", "-Xpreprocessor -fopenmp", "apple-clang@2.0.0") + unsupported_flag_test("cxx11_flag", "apple-clang@2.0.0") + supported_flag_test("cxx11_flag", "-std=c++11", "apple-clang@4.0.0") + unsupported_flag_test("cxx14_flag", "apple-clang@5.0.0") + supported_flag_test("cxx14_flag", "-std=c++1y", "apple-clang@5.1.0") + supported_flag_test("cxx14_flag", "-std=c++14", "apple-clang@6.1.0") + unsupported_flag_test("cxx17_flag", "apple-clang@6.0.0") + supported_flag_test("cxx17_flag", "-std=c++1z", "apple-clang@6.1.0") + supported_flag_test("c99_flag", "-std=c99", "apple-clang@6.1.0") + unsupported_flag_test("c11_flag", "apple-clang@3.0.0") + supported_flag_test("c11_flag", "-std=c11", "apple-clang@6.1.0") + supported_flag_test("cc_pic_flag", "-fPIC", "apple-clang@2.0.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "apple-clang@2.0.0") + supported_flag_test("f77_pic_flag", "-fPIC", "apple-clang@2.0.0") + supported_flag_test("fc_pic_flag", "-fPIC", "apple-clang@2.0.0") + + +def test_clang_flags(): + supported_flag_test("version_argument", "--version", "clang@foo.bar") + supported_flag_test("openmp_flag", "-fopenmp", "clang@3.3") + unsupported_flag_test("cxx11_flag", "clang@3.2") + supported_flag_test("cxx11_flag", "-std=c++11", "clang@3.3") + unsupported_flag_test("cxx14_flag", "clang@3.3") + supported_flag_test("cxx14_flag", "-std=c++1y", "clang@3.4") + supported_flag_test("cxx14_flag", "-std=c++14", "clang@3.5") + unsupported_flag_test("cxx17_flag", "clang@3.4") + supported_flag_test("cxx17_flag", "-std=c++1z", "clang@3.5") + supported_flag_test("cxx17_flag", "-std=c++17", "clang@5.0") + unsupported_flag_test("cxx20_flag", "clang@4.0") + supported_flag_test("cxx20_flag", "-std=c++2a", "clang@5.0") + supported_flag_test("cxx20_flag", "-std=c++20", "clang@11.0") + unsupported_flag_test("cxx23_flag", "clang@11.0") + supported_flag_test("cxx23_flag", "-std=c++2b", "clang@12.0") + supported_flag_test("cxx23_flag", "-std=c++23", "clang@17.0") + supported_flag_test("c99_flag", "-std=c99", "clang@3.3") + unsupported_flag_test("c11_flag", "clang@2.0") + supported_flag_test("c11_flag", "-std=c11", "clang@6.1.0") + unsupported_flag_test("c23_flag", "clang@8.0") + supported_flag_test("c23_flag", "-std=c2x", "clang@9.0") + supported_flag_test("c23_flag", "-std=c23", "clang@18.0") + supported_flag_test("cc_pic_flag", "-fPIC", "clang@3.3") + supported_flag_test("cxx_pic_flag", "-fPIC", "clang@3.3") + supported_flag_test("f77_pic_flag", "-fPIC", "clang@3.3") + supported_flag_test("fc_pic_flag", "-fPIC", "clang@3.3") + supported_flag_test( + "debug_flags", + [ + "-gcodeview", + "-gdwarf-2", + "-gdwarf-3", + "-gdwarf-4", + "-gdwarf-5", + "-gline-tables-only", + "-gmodules", + "-g", + ], + "clang@3.3", + ) + supported_flag_test( + "opt_flags", + ["-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os", "-Oz", "-Og", "-O", "-O4"], + "clang@3.3", + ) + + +def test_aocc_flags(): + supported_flag_test( + "debug_flags", + [ + "-gcodeview", + "-gdwarf-2", + "-gdwarf-3", + "-gdwarf-4", + "-gdwarf-5", + "-gline-tables-only", + "-gmodules", + "-g", + ], + "aocc@2.2.0", + ) + supported_flag_test( + "opt_flags", + ["-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os", "-Oz", "-Og", "-O", "-O4"], + "aocc@2.2.0", + ) + + supported_flag_test("stdcxx_libs", ("-lstdc++",), "aocc@2.2.0") + supported_flag_test("openmp_flag", "-fopenmp", "aocc@2.2.0") + supported_flag_test("cxx11_flag", "-std=c++11", "aocc@2.2.0") + supported_flag_test("cxx14_flag", "-std=c++14", "aocc@2.2.0") + supported_flag_test("cxx17_flag", "-std=c++17", "aocc@2.2.0") + supported_flag_test("c99_flag", "-std=c99", "aocc@2.2.0") + supported_flag_test("c11_flag", "-std=c11", "aocc@2.2.0") + supported_flag_test("cc_pic_flag", "-fPIC", "aocc@2.2.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "aocc@2.2.0") + supported_flag_test("f77_pic_flag", "-fPIC", "aocc@2.2.0") + supported_flag_test("fc_pic_flag", "-fPIC", "aocc@2.2.0") + supported_flag_test("version_argument", "--version", "aocc@2.2.0") + flg = "-Wno-unused-command-line-argument -mllvm -eliminate-similar-expr=false" + supported_flag_test("cflags", flg, "aocc@3.0.0") + supported_flag_test("cxxflags", flg, "aocc@3.0.0") + supported_flag_test("fflags", flg, "aocc@3.0.0") + + +def test_fj_flags(): + supported_flag_test("openmp_flag", "-Kopenmp", "fj@4.0.0") + supported_flag_test("cxx98_flag", "-std=c++98", "fj@4.0.0") + supported_flag_test("cxx11_flag", "-std=c++11", "fj@4.0.0") + supported_flag_test("cxx14_flag", "-std=c++14", "fj@4.0.0") + supported_flag_test("cxx17_flag", "-std=c++17", "fj@4.0.0") + supported_flag_test("c99_flag", "-std=c99", "fj@4.0.0") + supported_flag_test("c11_flag", "-std=c11", "fj@4.0.0") + supported_flag_test("cc_pic_flag", "-KPIC", "fj@4.0.0") + supported_flag_test("cxx_pic_flag", "-KPIC", "fj@4.0.0") + supported_flag_test("f77_pic_flag", "-KPIC", "fj@4.0.0") + supported_flag_test("fc_pic_flag", "-KPIC", "fj@4.0.0") + supported_flag_test("opt_flags", ["-O0", "-O1", "-O2", "-O3", "-Ofast"], "fj@4.0.0") + supported_flag_test("debug_flags", "-g", "fj@4.0.0") + + +def test_gcc_flags(): + supported_flag_test("openmp_flag", "-fopenmp", "gcc@4.1") + supported_flag_test("cxx98_flag", "", "gcc@5.2") + supported_flag_test("cxx98_flag", "-std=c++98", "gcc@6.0") + unsupported_flag_test("cxx11_flag", "gcc@4.2") + supported_flag_test("cxx11_flag", "-std=c++0x", "gcc@4.3") + supported_flag_test("cxx11_flag", "-std=c++11", "gcc@4.7") + unsupported_flag_test("cxx14_flag", "gcc@4.7") + supported_flag_test("cxx14_flag", "-std=c++1y", "gcc@4.8") + supported_flag_test("cxx14_flag", "-std=c++14", "gcc@4.9") + supported_flag_test("cxx14_flag", "-std=c++14", "gcc@6.0") + unsupported_flag_test("cxx17_flag", "gcc@4.9") + supported_flag_test("cxx17_flag", "-std=c++1z", "gcc@5.0") + supported_flag_test("cxx17_flag", "-std=c++17", "gcc@6.0") + unsupported_flag_test("c99_flag", "gcc@4.4") + supported_flag_test("c99_flag", "-std=c99", "gcc@4.5") + unsupported_flag_test("c11_flag", "gcc@4.6") + supported_flag_test("c11_flag", "-std=c11", "gcc@4.7") + supported_flag_test("cc_pic_flag", "-fPIC", "gcc@4.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "gcc@4.0") + supported_flag_test("f77_pic_flag", "-fPIC", "gcc@4.0") + supported_flag_test("fc_pic_flag", "-fPIC", "gcc@4.0") + supported_flag_test("stdcxx_libs", ("-lstdc++",), "gcc@4.1") + supported_flag_test( + "debug_flags", ["-g", "-gstabs+", "-gstabs", "-gxcoff+", "-gxcoff", "-gvms"], "gcc@4.0" + ) + supported_flag_test( + "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Os", "-Ofast", "-Og"], "gcc@4.0" + ) + + +def test_intel_flags(): + supported_flag_test("openmp_flag", "-openmp", "intel@=15.0") + supported_flag_test("openmp_flag", "-qopenmp", "intel@=16.0") + unsupported_flag_test("cxx11_flag", "intel@=11.0") + supported_flag_test("cxx11_flag", "-std=c++0x", "intel@=12.0") + supported_flag_test("cxx11_flag", "-std=c++11", "intel@=13") + unsupported_flag_test("cxx14_flag", "intel@=14.0") + supported_flag_test("cxx14_flag", "-std=c++1y", "intel@=15.0") + supported_flag_test("cxx14_flag", "-std=c++14", "intel@=15.0.2") + unsupported_flag_test("c99_flag", "intel@=11.0") + supported_flag_test("c99_flag", "-std=c99", "intel@=12.0") + unsupported_flag_test("c11_flag", "intel@=15.0") + supported_flag_test("c11_flag", "-std=c1x", "intel@=16.0") + supported_flag_test("cc_pic_flag", "-fPIC", "intel@=1.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "intel@=1.0") + supported_flag_test("f77_pic_flag", "-fPIC", "intel@=1.0") + supported_flag_test("fc_pic_flag", "-fPIC", "intel@=1.0") + supported_flag_test("stdcxx_libs", ("-cxxlib",), "intel@=1.0") + supported_flag_test("debug_flags", ["-debug", "-g", "-g0", "-g1", "-g2", "-g3"], "intel@=1.0") + supported_flag_test( + "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os"], "intel@=1.0" + ) + + +def test_oneapi_flags(): + supported_flag_test("openmp_flag", "-fiopenmp", "oneapi@=2020.8.0.0827") + supported_flag_test("cxx11_flag", "-std=c++11", "oneapi@=2020.8.0.0827") + supported_flag_test("cxx14_flag", "-std=c++14", "oneapi@=2020.8.0.0827") + supported_flag_test("c99_flag", "-std=c99", "oneapi@=2020.8.0.0827") + supported_flag_test("c11_flag", "-std=c1x", "oneapi@=2020.8.0.0827") + supported_flag_test("cc_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") + supported_flag_test("cxx_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") + supported_flag_test("f77_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") + supported_flag_test("fc_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") + supported_flag_test("stdcxx_libs", ("-cxxlib",), "oneapi@=2020.8.0.0827") + supported_flag_test( + "debug_flags", ["-debug", "-g", "-g0", "-g1", "-g2", "-g3"], "oneapi@=2020.8.0.0827" + ) + supported_flag_test( + "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os"], "oneapi@=2020.8.0.0827" + ) + + +def test_nag_flags(): + supported_flag_test("openmp_flag", "-openmp", "nag@=1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "nag@=1.0") + supported_flag_test("cc_pic_flag", "-fPIC", "nag@=1.0") + supported_flag_test("cxx_pic_flag", "-fPIC", "nag@=1.0") + supported_flag_test("f77_pic_flag", "-PIC", "nag@=1.0") + supported_flag_test("fc_pic_flag", "-PIC", "nag@=1.0") + supported_flag_test("cc_rpath_arg", "-Wl,-rpath,", "nag@=1.0") + supported_flag_test("cxx_rpath_arg", "-Wl,-rpath,", "nag@=1.0") + supported_flag_test("f77_rpath_arg", "-Wl,-Wl,,-rpath,,", "nag@=1.0") + supported_flag_test("fc_rpath_arg", "-Wl,-Wl,,-rpath,,", "nag@=1.0") + supported_flag_test("linker_arg", "-Wl,-Wl,,", "nag@=1.0") + supported_flag_test("debug_flags", ["-g", "-gline", "-g90"], "nag@=1.0") + supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "nag@=1.0") + + +def test_nvhpc_flags(): + supported_flag_test("openmp_flag", "-mp", "nvhpc@=20.9") + supported_flag_test("cxx11_flag", "--c++11", "nvhpc@=20.9") + supported_flag_test("cxx14_flag", "--c++14", "nvhpc@=20.9") + supported_flag_test("cxx17_flag", "--c++17", "nvhpc@=20.9") + supported_flag_test("c99_flag", "-c99", "nvhpc@=20.9") + supported_flag_test("c11_flag", "-c11", "nvhpc@=20.9") + supported_flag_test("cc_pic_flag", "-fpic", "nvhpc@=20.9") + supported_flag_test("cxx_pic_flag", "-fpic", "nvhpc@=20.9") + supported_flag_test("f77_pic_flag", "-fpic", "nvhpc@=20.9") + supported_flag_test("fc_pic_flag", "-fpic", "nvhpc@=20.9") + supported_flag_test("debug_flags", ["-g", "-gopt"], "nvhpc@=20.9") + supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "nvhpc@=20.9") + supported_flag_test("stdcxx_libs", ("-c++libs",), "nvhpc@=20.9") + + +def test_pgi_flags(): + supported_flag_test("openmp_flag", "-mp", "pgi@=1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "pgi@=1.0") + unsupported_flag_test("c99_flag", "pgi@=12.9") + supported_flag_test("c99_flag", "-c99", "pgi@=12.10") + unsupported_flag_test("c11_flag", "pgi@=15.2") + supported_flag_test("c11_flag", "-c11", "pgi@=15.3") + supported_flag_test("cc_pic_flag", "-fpic", "pgi@=1.0") + supported_flag_test("cxx_pic_flag", "-fpic", "pgi@=1.0") + supported_flag_test("f77_pic_flag", "-fpic", "pgi@=1.0") + supported_flag_test("fc_pic_flag", "-fpic", "pgi@=1.0") + supported_flag_test("stdcxx_libs", ("-pgc++libs",), "pgi@=1.0") + supported_flag_test("debug_flags", ["-g", "-gopt"], "pgi@=1.0") + supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "pgi@=1.0") + + +def test_xl_flags(): + supported_flag_test("openmp_flag", "-qsmp=omp", "xl@=1.0") + unsupported_flag_test("cxx11_flag", "xl@=13.0") + supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl@=13.1") + unsupported_flag_test("c99_flag", "xl@=10.0") + supported_flag_test("c99_flag", "-qlanglvl=extc99", "xl@=10.1") + supported_flag_test("c99_flag", "-std=gnu99", "xl@=13.1.1") + unsupported_flag_test("c11_flag", "xl@=12.0") + supported_flag_test("c11_flag", "-qlanglvl=extc1x", "xl@=12.1") + supported_flag_test("c11_flag", "-std=gnu11", "xl@=13.1.2") + supported_flag_test("cc_pic_flag", "-qpic", "xl@=1.0") + supported_flag_test("cxx_pic_flag", "-qpic", "xl@=1.0") + supported_flag_test("f77_pic_flag", "-qpic", "xl@=1.0") + supported_flag_test("fc_pic_flag", "-qpic", "xl@=1.0") + supported_flag_test("fflags", "-qzerosize", "xl@=1.0") + supported_flag_test("debug_flags", ["-g", "-g0", "-g1", "-g2", "-g8", "-g9"], "xl@=1.0") + supported_flag_test( + "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4", "-O5", "-Ofast"], "xl@=1.0" + ) + + +def test_xl_r_flags(): + supported_flag_test("openmp_flag", "-qsmp=omp", "xl_r@=1.0") + unsupported_flag_test("cxx11_flag", "xl_r@=13.0") + supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@=13.1") + unsupported_flag_test("c99_flag", "xl_r@=10.0") + supported_flag_test("c99_flag", "-qlanglvl=extc99", "xl_r@=10.1") + supported_flag_test("c99_flag", "-std=gnu99", "xl_r@=13.1.1") + unsupported_flag_test("c11_flag", "xl_r@=12.0") + supported_flag_test("c11_flag", "-qlanglvl=extc1x", "xl_r@=12.1") + supported_flag_test("c11_flag", "-std=gnu11", "xl_r@=13.1.2") + supported_flag_test("cc_pic_flag", "-qpic", "xl_r@=1.0") + supported_flag_test("cxx_pic_flag", "-qpic", "xl_r@=1.0") + supported_flag_test("f77_pic_flag", "-qpic", "xl_r@=1.0") + supported_flag_test("fc_pic_flag", "-qpic", "xl_r@=1.0") + supported_flag_test("fflags", "-qzerosize", "xl_r@=1.0") + supported_flag_test("debug_flags", ["-g", "-g0", "-g1", "-g2", "-g8", "-g9"], "xl@=1.0") + supported_flag_test( + "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4", "-O5", "-Ofast"], "xl@=1.0" + ) + + +@pytest.mark.parametrize( + "compiler_spec,expected_result", + [("gcc@4.7.2", False), ("clang@3.3", False), ("clang@8.0.0", True)], +) +def test_detecting_mixed_toolchains( + compiler_spec, expected_result, mutable_config, compiler_factory +): + mixed_c = compiler_factory(spec="clang@8.0.0", operating_system="debian6") + mixed_c["compiler"]["paths"] = { + "cc": "/path/to/clang-8", + "cxx": "/path/to/clang++-8", + "f77": "/path/to/gfortran-9", + "fc": "/path/to/gfortran-9", + } + mutable_config.set( + "compilers", + [ + compiler_factory(spec="gcc@4.7.2", operating_system="debian6"), + compiler_factory(spec="clang@3.3", operating_system="debian6"), + mixed_c, + ], + ) + + compiler = spack.compilers.compilers_for_spec(compiler_spec).pop() + assert spack.compilers.is_mixed_toolchain(compiler) is expected_result + + +@pytest.mark.regression("14798,13733") +def test_raising_if_compiler_target_is_over_specific(config): + # Compiler entry with an overly specific target + compilers = [ + { + "compiler": { + "spec": "gcc@9.0.1", + "paths": { + "cc": "/usr/bin/gcc-9", + "cxx": "/usr/bin/g++-9", + "f77": "/usr/bin/gfortran-9", + "fc": "/usr/bin/gfortran-9", + }, + "flags": {}, + "operating_system": "ubuntu18.04", + "target": "haswell", + "modules": [], + "environment": {}, + "extra_rpaths": [], + } + } + ] + arch_spec = spack.spec.ArchSpec(("linux", "ubuntu18.04", "haswell")) + with spack.config.override("compilers", compilers): + cfg = spack.compilers.get_compiler_config(config) + with pytest.raises(ValueError): + spack.compilers.get_compilers(cfg, spack.spec.CompilerSpec("gcc@9.0.1"), arch_spec) + + +@pytest.mark.not_on_windows("Not supported on Windows (yet)") +def test_compiler_get_real_version(working_env, monkeypatch, tmpdir): + # Test variables + test_version = "2.2.2" + + # Create compiler + gcc = str(tmpdir.join("gcc")) + with open(gcc, "w") as f: + f.write( + """#!/bin/sh +if [ "$CMP_ON" = "1" ]; then + echo "$CMP_VER" +fi +""" + ) + fs.set_executable(gcc) + + # Add compiler to config + compiler_info = { + "spec": "gcc@foo", + "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, + "flags": {}, + "operating_system": "fake", + "target": "fake", + "modules": ["turn_on"], + "environment": {"set": {"CMP_VER": test_version}}, + "extra_rpaths": [], + } + compiler_dict = {"compiler": compiler_info} + + # Set module load to turn compiler on + def module(*args): + if args[0] == "show": + return "" + elif args[0] == "load": + os.environ["CMP_ON"] = "1" + + monkeypatch.setattr(spack.util.module_cmd, "module", module) + + # Run and confirm output + compilers = spack.compilers.get_compilers([compiler_dict]) + assert len(compilers) == 1 + compiler = compilers[0] + version = compiler.get_real_version() + assert version == test_version + + +@pytest.mark.regression("42679") +def test_get_compilers(config): + """Tests that we can select compilers whose versions differ only for a suffix.""" + common = { + "flags": {}, + "operating_system": "ubuntu23.10", + "target": "x86_64", + "modules": [], + "environment": {}, + "extra_rpaths": [], + } + with_suffix = { + "spec": "gcc@13.2.0-suffix", + "paths": { + "cc": "/usr/bin/gcc-13.2.0-suffix", + "cxx": "/usr/bin/g++-13.2.0-suffix", + "f77": "/usr/bin/gfortran-13.2.0-suffix", + "fc": "/usr/bin/gfortran-13.2.0-suffix", + }, + **common, + } + without_suffix = { + "spec": "gcc@13.2.0", + "paths": { + "cc": "/usr/bin/gcc-13.2.0", + "cxx": "/usr/bin/g++-13.2.0", + "f77": "/usr/bin/gfortran-13.2.0", + "fc": "/usr/bin/gfortran-13.2.0", + }, + **common, + } + + compilers = [{"compiler": without_suffix}, {"compiler": with_suffix}] + + assert spack.compilers.get_compilers( + compilers, cspec=spack.spec.CompilerSpec("gcc@=13.2.0-suffix") + ) == [spack.compilers._compiler_from_config_entry(with_suffix)] + + assert spack.compilers.get_compilers( + compilers, cspec=spack.spec.CompilerSpec("gcc@=13.2.0") + ) == [spack.compilers._compiler_from_config_entry(without_suffix)] + + +def test_compiler_get_real_version_fails(working_env, monkeypatch, tmpdir): + # Test variables + test_version = "2.2.2" + + # Create compiler + gcc = str(tmpdir.join("gcc")) + with open(gcc, "w") as f: + f.write( + """#!/bin/sh +if [ "$CMP_ON" = "1" ]; then + echo "$CMP_VER" +fi +""" + ) + fs.set_executable(gcc) + + # Add compiler to config + compiler_info = { + "spec": "gcc@foo", + "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, + "flags": {}, + "operating_system": "fake", + "target": "fake", + "modules": ["turn_on"], + "environment": {"set": {"CMP_VER": test_version}}, + "extra_rpaths": [], + } + compiler_dict = {"compiler": compiler_info} + + # Set module load to turn compiler on + def module(*args): + if args[0] == "show": + return "" + elif args[0] == "load": + os.environ["SPACK_TEST_CMP_ON"] = "1" + + monkeypatch.setattr(spack.util.module_cmd, "module", module) + + # Make compiler fail when getting implicit rpaths + def _call(*args, **kwargs): + raise ProcessError("Failed intentionally") + + monkeypatch.setattr(Executable, "__call__", _call) + + # Run and no change to environment + compilers = spack.compilers.get_compilers([compiler_dict]) + assert len(compilers) == 1 + compiler = compilers[0] + try: + _ = compiler.get_real_version() + assert False + except ProcessError: + # Confirm environment does not change after failed call + assert "SPACK_TEST_CMP_ON" not in os.environ + + +@pytest.mark.not_on_windows("Bash scripting unsupported on Windows (for now)") +def test_compiler_flags_use_real_version(working_env, monkeypatch, tmpdir): + # Create compiler + gcc = str(tmpdir.join("gcc")) + with open(gcc, "w") as f: + f.write( + """#!/bin/sh +echo "4.4.4" +""" + ) # Version for which c++11 flag is -std=c++0x + fs.set_executable(gcc) + + # Add compiler to config + compiler_info = { + "spec": "gcc@foo", + "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, + "flags": {}, + "operating_system": "fake", + "target": "fake", + "modules": ["turn_on"], + "environment": {}, + "extra_rpaths": [], + } + compiler_dict = {"compiler": compiler_info} + + # Run and confirm output + compilers = spack.compilers.get_compilers([compiler_dict]) + assert len(compilers) == 1 + compiler = compilers[0] + flag = compiler.cxx11_flag + assert flag == "-std=c++0x" + + +@pytest.mark.enable_compiler_verification +def test_compiler_executable_verification_raises(tmpdir): + compiler = MockCompiler() + compiler.cc = "/this/path/does/not/exist" + + with pytest.raises(spack.compiler.CompilerAccessError): + compiler.verify_executables() + + +@pytest.mark.enable_compiler_verification +def test_compiler_executable_verification_success(tmpdir): + def prepare_executable(name): + real = str(tmpdir.join("cc").ensure()) + fs.set_executable(real) + setattr(compiler, name, real) + + # setup mock compiler with real paths + compiler = MockCompiler() + for name in ("cc", "cxx", "f77", "fc"): + prepare_executable(name) + + # testing that this doesn't raise an error because the paths exist and + # are executable + compiler.verify_executables() + + # Test that null entries don't fail + compiler.cc = None + compiler.verify_executables() + + +@pytest.mark.parametrize( + "detected_versions,expected_length", + [ + # If we detect a C compiler we expect the result to be valid + ( + [ + spack.compilers.DetectVersionArgs( + id=spack.compilers.CompilerID( + os="ubuntu20.04", compiler_name="clang", version="12.0.0" + ), + variation=spack.compilers.NameVariation(prefix="", suffix="-12"), + language="cc", + path="/usr/bin/clang-12", + ), + spack.compilers.DetectVersionArgs( + id=spack.compilers.CompilerID( + os="ubuntu20.04", compiler_name="clang", version="12.0.0" + ), + variation=spack.compilers.NameVariation(prefix="", suffix="-12"), + language="cxx", + path="/usr/bin/clang++-12", + ), + ], + 1, + ), + # If we detect only a C++ compiler we expect the result to be discarded + ( + [ + spack.compilers.DetectVersionArgs( + id=spack.compilers.CompilerID( + os="ubuntu20.04", compiler_name="clang", version="12.0.0" + ), + variation=spack.compilers.NameVariation(prefix="", suffix="-12"), + language="cxx", + path="/usr/bin/clang++-12", + ) + ], + 0, + ), + ], +) +def test_detection_requires_c_compiler(detected_versions, expected_length): + """Tests that compilers automatically added to the configuration have + at least a C compiler. + """ + result = spack.compilers.make_compiler_list(detected_versions) + assert len(result) == expected_length + + +def test_compiler_environment(working_env): + """Test whether environment modifications from compilers are applied in compiler_environment""" + os.environ.pop("TEST", None) + compiler = Compiler( + "gcc@=13.2.0", + operating_system="ubuntu20.04", + target="x86_64", + paths=["/test/bin/gcc", "/test/bin/g++"], + environment={"set": {"TEST": "yes"}}, + ) + with compiler.compiler_environment(): + assert os.environ["TEST"] == "yes" + + +def test_compiler_environment_always_flags_oneapi(working_env): + """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Oneapi compiler + environment""" + + class MockOneapiCompiler(Oneapi): + @property + def version(self): + return Version("2023.2.0") + + with spack.config.override("config:install_missing_compilers", True): + with spack.concretize.disable_compiler_existence_check(): + s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^intel-oneapi-runtime%gcc@10.2.1").concretized() + pkg = spack.package.Package(s) + + compiler = MockOneapiCompiler( + "oneapi@=2023.2.0", + operating_system="ubuntu22.04", + target="x86_64", + paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], + ) + env = EnvironmentModifications() + compiler.setup_custom_environment(pkg, env) + shell_modifications = env.shell_modifications() + assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications + + +def test_compiler_environment_always_flags_intel(working_env): + """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Intel compiler + environment""" + + class MockIntelCompiler(Intel): + @property + def version(self): + return Version("2023.2.0") + + with spack.config.override("config:install_missing_compilers", True): + with spack.concretize.disable_compiler_existence_check(): + s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() + pkg = spack.package.Package(s) + + compiler = MockIntelCompiler( + "intel@=2023.2.0", + operating_system="ubuntu22.04", + target="x86_64", + paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], + ) + env = EnvironmentModifications() + compiler.setup_custom_environment(pkg, env) + shell_modifications = env.shell_modifications() + assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications + assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications diff --git a/lib/spack/spack/test/compilers/basics.py.rej b/lib/spack/spack/test/compilers/basics.py.rej new file mode 100644 index 00000000000000..f9e1ff9f7d2e24 --- /dev/null +++ b/lib/spack/spack/test/compilers/basics.py.rej @@ -0,0 +1,17 @@ +--- lib/spack/spack/test/compilers/basics.py 2024-08-05 13:41:19.025052+00:00 ++++ lib/spack/spack/test/compilers/basics.py 2024-08-05 13:41:32.700185+00:00 +@@ -1011,13 +1013,11 @@ + def version(self): + return Version("2023.2.0") + + with spack.config.override("config:install_missing_compilers", True): + with spack.concretize.disable_compiler_existence_check(): +- s = spack.spec.Spec( +- "zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1" +- ).concretized() ++ s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() + pkg = spack.package.Package(s) + + compiler = MockIntelCompiler( + "intel@=2023.2.0", + operating_system="ubuntu22.04", From 8230afe1c3c47095ef8f00995b60c5ea19afc84b Mon Sep 17 00:00:00 2001 From: Dom Heinzeller Date: Wed, 7 Aug 2024 08:54:24 -0600 Subject: [PATCH 22/22] Remove files that were added inadvertently --- lib/spack/spack/test/compilers/basics.py.orig | 1028 ----------------- lib/spack/spack/test/compilers/basics.py.rej | 17 - 2 files changed, 1045 deletions(-) delete mode 100644 lib/spack/spack/test/compilers/basics.py.orig delete mode 100644 lib/spack/spack/test/compilers/basics.py.rej diff --git a/lib/spack/spack/test/compilers/basics.py.orig b/lib/spack/spack/test/compilers/basics.py.orig deleted file mode 100644 index 397732868e538a..00000000000000 --- a/lib/spack/spack/test/compilers/basics.py.orig +++ /dev/null @@ -1,1028 +0,0 @@ -# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other -# Spack Project Developers. See the top-level COPYRIGHT file for details. -# -# SPDX-License-Identifier: (Apache-2.0 OR MIT) -"""Test basic behavior of compilers in Spack""" -import os -from copy import copy - -import pytest - -import llnl.util.filesystem as fs - -import spack.compiler -import spack.compilers -import spack.spec -import spack.util.environment -import spack.util.module_cmd -from spack.compiler import Compiler -from spack.compilers.intel import Intel -from spack.compilers.oneapi import Oneapi -from spack.util.environment import EnvironmentModifications -from spack.util.executable import Executable, ProcessError -from spack.version import Version - - -@pytest.fixture() -def make_args_for_version(monkeypatch): - def _factory(version, path="/usr/bin/gcc"): - class MockOs: - pass - - compiler_name = "gcc" - compiler_cls = spack.compilers.class_for_compiler_name(compiler_name) - monkeypatch.setattr(compiler_cls, "cc_version", lambda x: version) - - compiler_id = spack.compilers.CompilerID( - os=MockOs, compiler_name=compiler_name, version=None - ) - variation = spack.compilers.NameVariation(prefix="", suffix="") - return spack.compilers.DetectVersionArgs( - id=compiler_id, variation=variation, language="cc", path=path - ) - - return _factory - - -def test_multiple_conflicting_compiler_definitions(mutable_config): - compiler_def = { - "compiler": { - "flags": {}, - "modules": [], - "paths": {"cc": "cc", "cxx": "cxx", "f77": "null", "fc": "null"}, - "extra_rpaths": [], - "operating_system": "test", - "target": "test", - "environment": {}, - "spec": "clang@0.0.0", - } - } - - compiler_config = [compiler_def, compiler_def] - compiler_config[0]["compiler"]["paths"]["f77"] = "f77" - mutable_config.update_config("compilers", compiler_config) - - arch_spec = spack.spec.ArchSpec(("test", "test", "test")) - cmp = spack.compilers.compiler_for_spec("clang@=0.0.0", arch_spec) - assert cmp.f77 == "f77" - - -def test_get_compiler_duplicates(mutable_config, compiler_factory): - # In this case there is only one instance of the specified compiler in - # the test configuration (so it is not actually a duplicate), but the - # method behaves the same. - cnl_compiler = compiler_factory(spec="gcc@4.5.0", operating_system="CNL") - # CNL compiler has no target attribute, and this is essential to make detection pass - del cnl_compiler["compiler"]["target"] - mutable_config.set( - "compilers", [compiler_factory(spec="gcc@4.5.0", operating_system="SuSE11"), cnl_compiler] - ) - cfg_file_to_duplicates = spack.compilers.get_compiler_duplicates( - "gcc@4.5.0", spack.spec.ArchSpec("cray-CNL-xeon") - ) - - assert len(cfg_file_to_duplicates) == 1 - cfg_file, duplicates = next(iter(cfg_file_to_duplicates.items())) - assert len(duplicates) == 1 - - -@pytest.mark.parametrize( - "input_version,expected_version,expected_error", - [(None, None, "Couldn't get version for compiler /usr/bin/gcc"), ("4.9", "4.9", None)], -) -def test_version_detection_is_empty( - make_args_for_version, input_version, expected_version, expected_error -): - args = make_args_for_version(version=input_version) - result, error = spack.compilers.detect_version(args) - if not error: - assert result.id.version == expected_version - - assert error == expected_error - - -def test_compiler_flags_from_config_are_grouped(): - compiler_entry = { - "spec": "intel@17.0.2", - "operating_system": "foo-os", - "paths": {"cc": "cc-path", "cxx": "cxx-path", "fc": None, "f77": None}, - "flags": {"cflags": "-O0 -foo-flag foo-val"}, - "modules": None, - } - - compiler = spack.compilers.compiler_from_dict(compiler_entry) - assert any(x == "-foo-flag foo-val" for x in compiler.flags["cflags"]) - - -# Test behavior of flags and UnsupportedCompilerFlag. - -# Utility function to test most flags. -default_compiler_entry = { - "spec": "apple-clang@2.0.0", - "operating_system": "foo-os", - "paths": {"cc": "cc-path", "cxx": "cxx-path", "fc": "fc-path", "f77": "f77-path"}, - "flags": {}, - "modules": None, -} - - -# Fake up a mock compiler where everything is defaulted. -class MockCompiler(Compiler): - def __init__(self): - super().__init__( - cspec="badcompiler@1.0.0", - operating_system=default_compiler_entry["operating_system"], - target=None, - paths=[ - default_compiler_entry["paths"]["cc"], - default_compiler_entry["paths"]["cxx"], - default_compiler_entry["paths"]["fc"], - default_compiler_entry["paths"]["f77"], - ], - environment={}, - ) - - @property - def name(self): - return "mockcompiler" - - @property - def version(self): - return "1.0.0" - - _verbose_flag = "--verbose" - - @property - def verbose_flag(self): - return self._verbose_flag - - required_libs = ["libgfortran"] - - -@pytest.mark.not_on_windows("Not supported on Windows (yet)") -def test_implicit_rpaths(dirs_with_libfiles): - lib_to_dirs, all_dirs = dirs_with_libfiles - compiler = MockCompiler() - compiler._compile_c_source_output = "ld " + " ".join(f"-L{d}" for d in all_dirs) - retrieved_rpaths = compiler.implicit_rpaths() - assert set(retrieved_rpaths) == set(lib_to_dirs["libstdc++"] + lib_to_dirs["libgfortran"]) - - -without_flag_output = "ld -L/path/to/first/lib -L/path/to/second/lib64" -with_flag_output = "ld -L/path/to/first/with/flag/lib -L/path/to/second/lib64" - - -def call_compiler(exe, *args, **kwargs): - # This method can replace Executable.__call__ to emulate a compiler that - # changes libraries depending on a flag. - if "--correct-flag" in exe.exe: - return with_flag_output - return without_flag_output - - -@pytest.mark.not_on_windows("Not supported on Windows (yet)") -@pytest.mark.parametrize( - "exe,flagname", - [ - ("cxx", "cxxflags"), - ("cxx", "cppflags"), - ("cxx", "ldflags"), - ("cc", "cflags"), - ("cc", "cppflags"), - ], -) -@pytest.mark.enable_compiler_execution -def test_compile_dummy_c_source_adds_flags(monkeypatch, exe, flagname): - # create fake compiler that emits mock verbose output - compiler = MockCompiler() - 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 - assert compiler._compile_dummy_c_source() == without_flag_output - - if flagname: - # set flags and test - compiler.flags = {flagname: ["--correct-flag"]} - assert compiler._compile_dummy_c_source() == with_flag_output - - -@pytest.mark.enable_compiler_execution -def test_compile_dummy_c_source_no_path(): - compiler = MockCompiler() - compiler.cc = None - compiler.cxx = None - assert compiler._compile_dummy_c_source() is None - - -@pytest.mark.enable_compiler_execution -def test_compile_dummy_c_source_no_verbose_flag(): - compiler = MockCompiler() - compiler._verbose_flag = None - assert compiler._compile_dummy_c_source() is None - - -@pytest.mark.not_on_windows("Not supported on Windows (yet)") -@pytest.mark.enable_compiler_execution -def test_compile_dummy_c_source_load_env(working_env, monkeypatch, tmpdir): - gcc = str(tmpdir.join("gcc")) - with open(gcc, "w") as f: - f.write( - f"""#!/bin/sh -if [ "$ENV_SET" = "1" ] && [ "$MODULE_LOADED" = "1" ]; then - printf '{without_flag_output}' -fi -""" - ) - fs.set_executable(gcc) - - # Set module load to turn compiler on - def module(*args): - if args[0] == "show": - return "" - elif args[0] == "load": - os.environ["MODULE_LOADED"] = "1" - - monkeypatch.setattr(spack.util.module_cmd, "module", module) - - compiler = MockCompiler() - compiler.cc = gcc - compiler.environment = {"set": {"ENV_SET": "1"}} - compiler.modules = ["turn_on"] - - assert compiler._compile_dummy_c_source() == without_flag_output - - -# Get the desired flag from the specified compiler spec. -def flag_value(flag, spec): - compiler = None - if spec is None: - compiler = MockCompiler() - else: - compiler_entry = copy(default_compiler_entry) - compiler_entry["spec"] = spec - compiler = spack.compilers.compiler_from_dict(compiler_entry) - - return getattr(compiler, flag) - - -# Utility function to verify that the expected exception is thrown for -# an unsupported flag. -def unsupported_flag_test(flag, spec=None): - caught_exception = None - try: - flag_value(flag, spec) - except spack.compiler.UnsupportedCompilerFlag: - caught_exception = True - - assert caught_exception and "Expected exception not thrown." - - -# Verify the expected flag value for the give compiler spec. -def supported_flag_test(flag, flag_value_ref, spec=None): - assert flag_value(flag, spec) == flag_value_ref - - -# Tests for UnsupportedCompilerFlag exceptions from default -# implementations of flags. -def test_default_flags(): - supported_flag_test("cc_rpath_arg", "-Wl,-rpath,") - supported_flag_test("cxx_rpath_arg", "-Wl,-rpath,") - supported_flag_test("f77_rpath_arg", "-Wl,-rpath,") - supported_flag_test("fc_rpath_arg", "-Wl,-rpath,") - supported_flag_test("linker_arg", "-Wl,") - unsupported_flag_test("openmp_flag") - unsupported_flag_test("cxx11_flag") - unsupported_flag_test("cxx14_flag") - unsupported_flag_test("cxx17_flag") - supported_flag_test("cxx98_flag", "") - unsupported_flag_test("c99_flag") - unsupported_flag_test("c11_flag") - supported_flag_test("cc_pic_flag", "-fPIC") - supported_flag_test("cxx_pic_flag", "-fPIC") - supported_flag_test("f77_pic_flag", "-fPIC") - supported_flag_test("fc_pic_flag", "-fPIC") - supported_flag_test("debug_flags", ["-g"]) - supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3"]) - - -# Verify behavior of particular compiler definitions. -def test_arm_flags(): - supported_flag_test("openmp_flag", "-fopenmp", "arm@1.0") - supported_flag_test("cxx11_flag", "-std=c++11", "arm@1.0") - supported_flag_test("cxx14_flag", "-std=c++14", "arm@1.0") - supported_flag_test("cxx17_flag", "-std=c++1z", "arm@1.0") - supported_flag_test("c99_flag", "-std=c99", "arm@1.0") - supported_flag_test("c11_flag", "-std=c11", "arm@1.0") - supported_flag_test("cc_pic_flag", "-fPIC", "arm@1.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "arm@1.0") - supported_flag_test("f77_pic_flag", "-fPIC", "arm@1.0") - supported_flag_test("fc_pic_flag", "-fPIC", "arm@1.0") - supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast"], "arm@1.0") - - -def test_cce_flags(): - supported_flag_test("version_argument", "--version", "cce@9.0.1") - supported_flag_test("version_argument", "-V", "cce@9.0.1-classic") - supported_flag_test("openmp_flag", "-fopenmp", "cce@9.0.1") - supported_flag_test("openmp_flag", "-h omp", "cce@9.0.1-classic") - supported_flag_test("openmp_flag", "-h omp", "cce@1.0") - supported_flag_test("cxx11_flag", "-std=c++11", "cce@9.0.1") - supported_flag_test("cxx11_flag", "-h std=c++11", "cce@9.0.1-classic") - supported_flag_test("cxx11_flag", "-h std=c++11", "cce@1.0") - unsupported_flag_test("c99_flag", "cce@8.0") - supported_flag_test("c99_flag", "-std=c99", "cce@9.0.1") - supported_flag_test("c99_flag", "-h c99,noconform,gnu", "cce@8.1") - supported_flag_test("c99_flag", "-h std=c99,noconform,gnu", "cce@8.4") - unsupported_flag_test("c11_flag", "cce@8.4") - supported_flag_test("c11_flag", "-std=c11", "cce@9.0.1") - supported_flag_test("c11_flag", "-h std=c11,noconform,gnu", "cce@8.5") - supported_flag_test("cc_pic_flag", "-h PIC", "cce@1.0") - supported_flag_test("cxx_pic_flag", "-h PIC", "cce@1.0") - supported_flag_test("f77_pic_flag", "-h PIC", "cce@1.0") - supported_flag_test("fc_pic_flag", "-h PIC", "cce@1.0") - supported_flag_test("cc_pic_flag", "-fPIC", "cce@9.1.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "cce@9.1.0") - supported_flag_test("f77_pic_flag", "-fPIC", "cce@9.1.0") - supported_flag_test("fc_pic_flag", "-fPIC", "cce@9.1.0") - supported_flag_test("stdcxx_libs", (), "cce@1.0") - supported_flag_test("debug_flags", ["-g", "-G0", "-G1", "-G2", "-Gfast"], "cce@1.0") - - -def test_apple_clang_flags(): - supported_flag_test("openmp_flag", "-Xpreprocessor -fopenmp", "apple-clang@2.0.0") - unsupported_flag_test("cxx11_flag", "apple-clang@2.0.0") - supported_flag_test("cxx11_flag", "-std=c++11", "apple-clang@4.0.0") - unsupported_flag_test("cxx14_flag", "apple-clang@5.0.0") - supported_flag_test("cxx14_flag", "-std=c++1y", "apple-clang@5.1.0") - supported_flag_test("cxx14_flag", "-std=c++14", "apple-clang@6.1.0") - unsupported_flag_test("cxx17_flag", "apple-clang@6.0.0") - supported_flag_test("cxx17_flag", "-std=c++1z", "apple-clang@6.1.0") - supported_flag_test("c99_flag", "-std=c99", "apple-clang@6.1.0") - unsupported_flag_test("c11_flag", "apple-clang@3.0.0") - supported_flag_test("c11_flag", "-std=c11", "apple-clang@6.1.0") - supported_flag_test("cc_pic_flag", "-fPIC", "apple-clang@2.0.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "apple-clang@2.0.0") - supported_flag_test("f77_pic_flag", "-fPIC", "apple-clang@2.0.0") - supported_flag_test("fc_pic_flag", "-fPIC", "apple-clang@2.0.0") - - -def test_clang_flags(): - supported_flag_test("version_argument", "--version", "clang@foo.bar") - supported_flag_test("openmp_flag", "-fopenmp", "clang@3.3") - unsupported_flag_test("cxx11_flag", "clang@3.2") - supported_flag_test("cxx11_flag", "-std=c++11", "clang@3.3") - unsupported_flag_test("cxx14_flag", "clang@3.3") - supported_flag_test("cxx14_flag", "-std=c++1y", "clang@3.4") - supported_flag_test("cxx14_flag", "-std=c++14", "clang@3.5") - unsupported_flag_test("cxx17_flag", "clang@3.4") - supported_flag_test("cxx17_flag", "-std=c++1z", "clang@3.5") - supported_flag_test("cxx17_flag", "-std=c++17", "clang@5.0") - unsupported_flag_test("cxx20_flag", "clang@4.0") - supported_flag_test("cxx20_flag", "-std=c++2a", "clang@5.0") - supported_flag_test("cxx20_flag", "-std=c++20", "clang@11.0") - unsupported_flag_test("cxx23_flag", "clang@11.0") - supported_flag_test("cxx23_flag", "-std=c++2b", "clang@12.0") - supported_flag_test("cxx23_flag", "-std=c++23", "clang@17.0") - supported_flag_test("c99_flag", "-std=c99", "clang@3.3") - unsupported_flag_test("c11_flag", "clang@2.0") - supported_flag_test("c11_flag", "-std=c11", "clang@6.1.0") - unsupported_flag_test("c23_flag", "clang@8.0") - supported_flag_test("c23_flag", "-std=c2x", "clang@9.0") - supported_flag_test("c23_flag", "-std=c23", "clang@18.0") - supported_flag_test("cc_pic_flag", "-fPIC", "clang@3.3") - supported_flag_test("cxx_pic_flag", "-fPIC", "clang@3.3") - supported_flag_test("f77_pic_flag", "-fPIC", "clang@3.3") - supported_flag_test("fc_pic_flag", "-fPIC", "clang@3.3") - supported_flag_test( - "debug_flags", - [ - "-gcodeview", - "-gdwarf-2", - "-gdwarf-3", - "-gdwarf-4", - "-gdwarf-5", - "-gline-tables-only", - "-gmodules", - "-g", - ], - "clang@3.3", - ) - supported_flag_test( - "opt_flags", - ["-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os", "-Oz", "-Og", "-O", "-O4"], - "clang@3.3", - ) - - -def test_aocc_flags(): - supported_flag_test( - "debug_flags", - [ - "-gcodeview", - "-gdwarf-2", - "-gdwarf-3", - "-gdwarf-4", - "-gdwarf-5", - "-gline-tables-only", - "-gmodules", - "-g", - ], - "aocc@2.2.0", - ) - supported_flag_test( - "opt_flags", - ["-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os", "-Oz", "-Og", "-O", "-O4"], - "aocc@2.2.0", - ) - - supported_flag_test("stdcxx_libs", ("-lstdc++",), "aocc@2.2.0") - supported_flag_test("openmp_flag", "-fopenmp", "aocc@2.2.0") - supported_flag_test("cxx11_flag", "-std=c++11", "aocc@2.2.0") - supported_flag_test("cxx14_flag", "-std=c++14", "aocc@2.2.0") - supported_flag_test("cxx17_flag", "-std=c++17", "aocc@2.2.0") - supported_flag_test("c99_flag", "-std=c99", "aocc@2.2.0") - supported_flag_test("c11_flag", "-std=c11", "aocc@2.2.0") - supported_flag_test("cc_pic_flag", "-fPIC", "aocc@2.2.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "aocc@2.2.0") - supported_flag_test("f77_pic_flag", "-fPIC", "aocc@2.2.0") - supported_flag_test("fc_pic_flag", "-fPIC", "aocc@2.2.0") - supported_flag_test("version_argument", "--version", "aocc@2.2.0") - flg = "-Wno-unused-command-line-argument -mllvm -eliminate-similar-expr=false" - supported_flag_test("cflags", flg, "aocc@3.0.0") - supported_flag_test("cxxflags", flg, "aocc@3.0.0") - supported_flag_test("fflags", flg, "aocc@3.0.0") - - -def test_fj_flags(): - supported_flag_test("openmp_flag", "-Kopenmp", "fj@4.0.0") - supported_flag_test("cxx98_flag", "-std=c++98", "fj@4.0.0") - supported_flag_test("cxx11_flag", "-std=c++11", "fj@4.0.0") - supported_flag_test("cxx14_flag", "-std=c++14", "fj@4.0.0") - supported_flag_test("cxx17_flag", "-std=c++17", "fj@4.0.0") - supported_flag_test("c99_flag", "-std=c99", "fj@4.0.0") - supported_flag_test("c11_flag", "-std=c11", "fj@4.0.0") - supported_flag_test("cc_pic_flag", "-KPIC", "fj@4.0.0") - supported_flag_test("cxx_pic_flag", "-KPIC", "fj@4.0.0") - supported_flag_test("f77_pic_flag", "-KPIC", "fj@4.0.0") - supported_flag_test("fc_pic_flag", "-KPIC", "fj@4.0.0") - supported_flag_test("opt_flags", ["-O0", "-O1", "-O2", "-O3", "-Ofast"], "fj@4.0.0") - supported_flag_test("debug_flags", "-g", "fj@4.0.0") - - -def test_gcc_flags(): - supported_flag_test("openmp_flag", "-fopenmp", "gcc@4.1") - supported_flag_test("cxx98_flag", "", "gcc@5.2") - supported_flag_test("cxx98_flag", "-std=c++98", "gcc@6.0") - unsupported_flag_test("cxx11_flag", "gcc@4.2") - supported_flag_test("cxx11_flag", "-std=c++0x", "gcc@4.3") - supported_flag_test("cxx11_flag", "-std=c++11", "gcc@4.7") - unsupported_flag_test("cxx14_flag", "gcc@4.7") - supported_flag_test("cxx14_flag", "-std=c++1y", "gcc@4.8") - supported_flag_test("cxx14_flag", "-std=c++14", "gcc@4.9") - supported_flag_test("cxx14_flag", "-std=c++14", "gcc@6.0") - unsupported_flag_test("cxx17_flag", "gcc@4.9") - supported_flag_test("cxx17_flag", "-std=c++1z", "gcc@5.0") - supported_flag_test("cxx17_flag", "-std=c++17", "gcc@6.0") - unsupported_flag_test("c99_flag", "gcc@4.4") - supported_flag_test("c99_flag", "-std=c99", "gcc@4.5") - unsupported_flag_test("c11_flag", "gcc@4.6") - supported_flag_test("c11_flag", "-std=c11", "gcc@4.7") - supported_flag_test("cc_pic_flag", "-fPIC", "gcc@4.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "gcc@4.0") - supported_flag_test("f77_pic_flag", "-fPIC", "gcc@4.0") - supported_flag_test("fc_pic_flag", "-fPIC", "gcc@4.0") - supported_flag_test("stdcxx_libs", ("-lstdc++",), "gcc@4.1") - supported_flag_test( - "debug_flags", ["-g", "-gstabs+", "-gstabs", "-gxcoff+", "-gxcoff", "-gvms"], "gcc@4.0" - ) - supported_flag_test( - "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Os", "-Ofast", "-Og"], "gcc@4.0" - ) - - -def test_intel_flags(): - supported_flag_test("openmp_flag", "-openmp", "intel@=15.0") - supported_flag_test("openmp_flag", "-qopenmp", "intel@=16.0") - unsupported_flag_test("cxx11_flag", "intel@=11.0") - supported_flag_test("cxx11_flag", "-std=c++0x", "intel@=12.0") - supported_flag_test("cxx11_flag", "-std=c++11", "intel@=13") - unsupported_flag_test("cxx14_flag", "intel@=14.0") - supported_flag_test("cxx14_flag", "-std=c++1y", "intel@=15.0") - supported_flag_test("cxx14_flag", "-std=c++14", "intel@=15.0.2") - unsupported_flag_test("c99_flag", "intel@=11.0") - supported_flag_test("c99_flag", "-std=c99", "intel@=12.0") - unsupported_flag_test("c11_flag", "intel@=15.0") - supported_flag_test("c11_flag", "-std=c1x", "intel@=16.0") - supported_flag_test("cc_pic_flag", "-fPIC", "intel@=1.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "intel@=1.0") - supported_flag_test("f77_pic_flag", "-fPIC", "intel@=1.0") - supported_flag_test("fc_pic_flag", "-fPIC", "intel@=1.0") - supported_flag_test("stdcxx_libs", ("-cxxlib",), "intel@=1.0") - supported_flag_test("debug_flags", ["-debug", "-g", "-g0", "-g1", "-g2", "-g3"], "intel@=1.0") - supported_flag_test( - "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os"], "intel@=1.0" - ) - - -def test_oneapi_flags(): - supported_flag_test("openmp_flag", "-fiopenmp", "oneapi@=2020.8.0.0827") - supported_flag_test("cxx11_flag", "-std=c++11", "oneapi@=2020.8.0.0827") - supported_flag_test("cxx14_flag", "-std=c++14", "oneapi@=2020.8.0.0827") - supported_flag_test("c99_flag", "-std=c99", "oneapi@=2020.8.0.0827") - supported_flag_test("c11_flag", "-std=c1x", "oneapi@=2020.8.0.0827") - supported_flag_test("cc_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") - supported_flag_test("cxx_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") - supported_flag_test("f77_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") - supported_flag_test("fc_pic_flag", "-fPIC", "oneapi@=2020.8.0.0827") - supported_flag_test("stdcxx_libs", ("-cxxlib",), "oneapi@=2020.8.0.0827") - supported_flag_test( - "debug_flags", ["-debug", "-g", "-g0", "-g1", "-g2", "-g3"], "oneapi@=2020.8.0.0827" - ) - supported_flag_test( - "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-Ofast", "-Os"], "oneapi@=2020.8.0.0827" - ) - - -def test_nag_flags(): - supported_flag_test("openmp_flag", "-openmp", "nag@=1.0") - supported_flag_test("cxx11_flag", "-std=c++11", "nag@=1.0") - supported_flag_test("cc_pic_flag", "-fPIC", "nag@=1.0") - supported_flag_test("cxx_pic_flag", "-fPIC", "nag@=1.0") - supported_flag_test("f77_pic_flag", "-PIC", "nag@=1.0") - supported_flag_test("fc_pic_flag", "-PIC", "nag@=1.0") - supported_flag_test("cc_rpath_arg", "-Wl,-rpath,", "nag@=1.0") - supported_flag_test("cxx_rpath_arg", "-Wl,-rpath,", "nag@=1.0") - supported_flag_test("f77_rpath_arg", "-Wl,-Wl,,-rpath,,", "nag@=1.0") - supported_flag_test("fc_rpath_arg", "-Wl,-Wl,,-rpath,,", "nag@=1.0") - supported_flag_test("linker_arg", "-Wl,-Wl,,", "nag@=1.0") - supported_flag_test("debug_flags", ["-g", "-gline", "-g90"], "nag@=1.0") - supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "nag@=1.0") - - -def test_nvhpc_flags(): - supported_flag_test("openmp_flag", "-mp", "nvhpc@=20.9") - supported_flag_test("cxx11_flag", "--c++11", "nvhpc@=20.9") - supported_flag_test("cxx14_flag", "--c++14", "nvhpc@=20.9") - supported_flag_test("cxx17_flag", "--c++17", "nvhpc@=20.9") - supported_flag_test("c99_flag", "-c99", "nvhpc@=20.9") - supported_flag_test("c11_flag", "-c11", "nvhpc@=20.9") - supported_flag_test("cc_pic_flag", "-fpic", "nvhpc@=20.9") - supported_flag_test("cxx_pic_flag", "-fpic", "nvhpc@=20.9") - supported_flag_test("f77_pic_flag", "-fpic", "nvhpc@=20.9") - supported_flag_test("fc_pic_flag", "-fpic", "nvhpc@=20.9") - supported_flag_test("debug_flags", ["-g", "-gopt"], "nvhpc@=20.9") - supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "nvhpc@=20.9") - supported_flag_test("stdcxx_libs", ("-c++libs",), "nvhpc@=20.9") - - -def test_pgi_flags(): - supported_flag_test("openmp_flag", "-mp", "pgi@=1.0") - supported_flag_test("cxx11_flag", "-std=c++11", "pgi@=1.0") - unsupported_flag_test("c99_flag", "pgi@=12.9") - supported_flag_test("c99_flag", "-c99", "pgi@=12.10") - unsupported_flag_test("c11_flag", "pgi@=15.2") - supported_flag_test("c11_flag", "-c11", "pgi@=15.3") - supported_flag_test("cc_pic_flag", "-fpic", "pgi@=1.0") - supported_flag_test("cxx_pic_flag", "-fpic", "pgi@=1.0") - supported_flag_test("f77_pic_flag", "-fpic", "pgi@=1.0") - supported_flag_test("fc_pic_flag", "-fpic", "pgi@=1.0") - supported_flag_test("stdcxx_libs", ("-pgc++libs",), "pgi@=1.0") - supported_flag_test("debug_flags", ["-g", "-gopt"], "pgi@=1.0") - supported_flag_test("opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4"], "pgi@=1.0") - - -def test_xl_flags(): - supported_flag_test("openmp_flag", "-qsmp=omp", "xl@=1.0") - unsupported_flag_test("cxx11_flag", "xl@=13.0") - supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl@=13.1") - unsupported_flag_test("c99_flag", "xl@=10.0") - supported_flag_test("c99_flag", "-qlanglvl=extc99", "xl@=10.1") - supported_flag_test("c99_flag", "-std=gnu99", "xl@=13.1.1") - unsupported_flag_test("c11_flag", "xl@=12.0") - supported_flag_test("c11_flag", "-qlanglvl=extc1x", "xl@=12.1") - supported_flag_test("c11_flag", "-std=gnu11", "xl@=13.1.2") - supported_flag_test("cc_pic_flag", "-qpic", "xl@=1.0") - supported_flag_test("cxx_pic_flag", "-qpic", "xl@=1.0") - supported_flag_test("f77_pic_flag", "-qpic", "xl@=1.0") - supported_flag_test("fc_pic_flag", "-qpic", "xl@=1.0") - supported_flag_test("fflags", "-qzerosize", "xl@=1.0") - supported_flag_test("debug_flags", ["-g", "-g0", "-g1", "-g2", "-g8", "-g9"], "xl@=1.0") - supported_flag_test( - "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4", "-O5", "-Ofast"], "xl@=1.0" - ) - - -def test_xl_r_flags(): - supported_flag_test("openmp_flag", "-qsmp=omp", "xl_r@=1.0") - unsupported_flag_test("cxx11_flag", "xl_r@=13.0") - supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@=13.1") - unsupported_flag_test("c99_flag", "xl_r@=10.0") - supported_flag_test("c99_flag", "-qlanglvl=extc99", "xl_r@=10.1") - supported_flag_test("c99_flag", "-std=gnu99", "xl_r@=13.1.1") - unsupported_flag_test("c11_flag", "xl_r@=12.0") - supported_flag_test("c11_flag", "-qlanglvl=extc1x", "xl_r@=12.1") - supported_flag_test("c11_flag", "-std=gnu11", "xl_r@=13.1.2") - supported_flag_test("cc_pic_flag", "-qpic", "xl_r@=1.0") - supported_flag_test("cxx_pic_flag", "-qpic", "xl_r@=1.0") - supported_flag_test("f77_pic_flag", "-qpic", "xl_r@=1.0") - supported_flag_test("fc_pic_flag", "-qpic", "xl_r@=1.0") - supported_flag_test("fflags", "-qzerosize", "xl_r@=1.0") - supported_flag_test("debug_flags", ["-g", "-g0", "-g1", "-g2", "-g8", "-g9"], "xl@=1.0") - supported_flag_test( - "opt_flags", ["-O", "-O0", "-O1", "-O2", "-O3", "-O4", "-O5", "-Ofast"], "xl@=1.0" - ) - - -@pytest.mark.parametrize( - "compiler_spec,expected_result", - [("gcc@4.7.2", False), ("clang@3.3", False), ("clang@8.0.0", True)], -) -def test_detecting_mixed_toolchains( - compiler_spec, expected_result, mutable_config, compiler_factory -): - mixed_c = compiler_factory(spec="clang@8.0.0", operating_system="debian6") - mixed_c["compiler"]["paths"] = { - "cc": "/path/to/clang-8", - "cxx": "/path/to/clang++-8", - "f77": "/path/to/gfortran-9", - "fc": "/path/to/gfortran-9", - } - mutable_config.set( - "compilers", - [ - compiler_factory(spec="gcc@4.7.2", operating_system="debian6"), - compiler_factory(spec="clang@3.3", operating_system="debian6"), - mixed_c, - ], - ) - - compiler = spack.compilers.compilers_for_spec(compiler_spec).pop() - assert spack.compilers.is_mixed_toolchain(compiler) is expected_result - - -@pytest.mark.regression("14798,13733") -def test_raising_if_compiler_target_is_over_specific(config): - # Compiler entry with an overly specific target - compilers = [ - { - "compiler": { - "spec": "gcc@9.0.1", - "paths": { - "cc": "/usr/bin/gcc-9", - "cxx": "/usr/bin/g++-9", - "f77": "/usr/bin/gfortran-9", - "fc": "/usr/bin/gfortran-9", - }, - "flags": {}, - "operating_system": "ubuntu18.04", - "target": "haswell", - "modules": [], - "environment": {}, - "extra_rpaths": [], - } - } - ] - arch_spec = spack.spec.ArchSpec(("linux", "ubuntu18.04", "haswell")) - with spack.config.override("compilers", compilers): - cfg = spack.compilers.get_compiler_config(config) - with pytest.raises(ValueError): - spack.compilers.get_compilers(cfg, spack.spec.CompilerSpec("gcc@9.0.1"), arch_spec) - - -@pytest.mark.not_on_windows("Not supported on Windows (yet)") -def test_compiler_get_real_version(working_env, monkeypatch, tmpdir): - # Test variables - test_version = "2.2.2" - - # Create compiler - gcc = str(tmpdir.join("gcc")) - with open(gcc, "w") as f: - f.write( - """#!/bin/sh -if [ "$CMP_ON" = "1" ]; then - echo "$CMP_VER" -fi -""" - ) - fs.set_executable(gcc) - - # Add compiler to config - compiler_info = { - "spec": "gcc@foo", - "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, - "flags": {}, - "operating_system": "fake", - "target": "fake", - "modules": ["turn_on"], - "environment": {"set": {"CMP_VER": test_version}}, - "extra_rpaths": [], - } - compiler_dict = {"compiler": compiler_info} - - # Set module load to turn compiler on - def module(*args): - if args[0] == "show": - return "" - elif args[0] == "load": - os.environ["CMP_ON"] = "1" - - monkeypatch.setattr(spack.util.module_cmd, "module", module) - - # Run and confirm output - compilers = spack.compilers.get_compilers([compiler_dict]) - assert len(compilers) == 1 - compiler = compilers[0] - version = compiler.get_real_version() - assert version == test_version - - -@pytest.mark.regression("42679") -def test_get_compilers(config): - """Tests that we can select compilers whose versions differ only for a suffix.""" - common = { - "flags": {}, - "operating_system": "ubuntu23.10", - "target": "x86_64", - "modules": [], - "environment": {}, - "extra_rpaths": [], - } - with_suffix = { - "spec": "gcc@13.2.0-suffix", - "paths": { - "cc": "/usr/bin/gcc-13.2.0-suffix", - "cxx": "/usr/bin/g++-13.2.0-suffix", - "f77": "/usr/bin/gfortran-13.2.0-suffix", - "fc": "/usr/bin/gfortran-13.2.0-suffix", - }, - **common, - } - without_suffix = { - "spec": "gcc@13.2.0", - "paths": { - "cc": "/usr/bin/gcc-13.2.0", - "cxx": "/usr/bin/g++-13.2.0", - "f77": "/usr/bin/gfortran-13.2.0", - "fc": "/usr/bin/gfortran-13.2.0", - }, - **common, - } - - compilers = [{"compiler": without_suffix}, {"compiler": with_suffix}] - - assert spack.compilers.get_compilers( - compilers, cspec=spack.spec.CompilerSpec("gcc@=13.2.0-suffix") - ) == [spack.compilers._compiler_from_config_entry(with_suffix)] - - assert spack.compilers.get_compilers( - compilers, cspec=spack.spec.CompilerSpec("gcc@=13.2.0") - ) == [spack.compilers._compiler_from_config_entry(without_suffix)] - - -def test_compiler_get_real_version_fails(working_env, monkeypatch, tmpdir): - # Test variables - test_version = "2.2.2" - - # Create compiler - gcc = str(tmpdir.join("gcc")) - with open(gcc, "w") as f: - f.write( - """#!/bin/sh -if [ "$CMP_ON" = "1" ]; then - echo "$CMP_VER" -fi -""" - ) - fs.set_executable(gcc) - - # Add compiler to config - compiler_info = { - "spec": "gcc@foo", - "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, - "flags": {}, - "operating_system": "fake", - "target": "fake", - "modules": ["turn_on"], - "environment": {"set": {"CMP_VER": test_version}}, - "extra_rpaths": [], - } - compiler_dict = {"compiler": compiler_info} - - # Set module load to turn compiler on - def module(*args): - if args[0] == "show": - return "" - elif args[0] == "load": - os.environ["SPACK_TEST_CMP_ON"] = "1" - - monkeypatch.setattr(spack.util.module_cmd, "module", module) - - # Make compiler fail when getting implicit rpaths - def _call(*args, **kwargs): - raise ProcessError("Failed intentionally") - - monkeypatch.setattr(Executable, "__call__", _call) - - # Run and no change to environment - compilers = spack.compilers.get_compilers([compiler_dict]) - assert len(compilers) == 1 - compiler = compilers[0] - try: - _ = compiler.get_real_version() - assert False - except ProcessError: - # Confirm environment does not change after failed call - assert "SPACK_TEST_CMP_ON" not in os.environ - - -@pytest.mark.not_on_windows("Bash scripting unsupported on Windows (for now)") -def test_compiler_flags_use_real_version(working_env, monkeypatch, tmpdir): - # Create compiler - gcc = str(tmpdir.join("gcc")) - with open(gcc, "w") as f: - f.write( - """#!/bin/sh -echo "4.4.4" -""" - ) # Version for which c++11 flag is -std=c++0x - fs.set_executable(gcc) - - # Add compiler to config - compiler_info = { - "spec": "gcc@foo", - "paths": {"cc": gcc, "cxx": None, "f77": None, "fc": None}, - "flags": {}, - "operating_system": "fake", - "target": "fake", - "modules": ["turn_on"], - "environment": {}, - "extra_rpaths": [], - } - compiler_dict = {"compiler": compiler_info} - - # Run and confirm output - compilers = spack.compilers.get_compilers([compiler_dict]) - assert len(compilers) == 1 - compiler = compilers[0] - flag = compiler.cxx11_flag - assert flag == "-std=c++0x" - - -@pytest.mark.enable_compiler_verification -def test_compiler_executable_verification_raises(tmpdir): - compiler = MockCompiler() - compiler.cc = "/this/path/does/not/exist" - - with pytest.raises(spack.compiler.CompilerAccessError): - compiler.verify_executables() - - -@pytest.mark.enable_compiler_verification -def test_compiler_executable_verification_success(tmpdir): - def prepare_executable(name): - real = str(tmpdir.join("cc").ensure()) - fs.set_executable(real) - setattr(compiler, name, real) - - # setup mock compiler with real paths - compiler = MockCompiler() - for name in ("cc", "cxx", "f77", "fc"): - prepare_executable(name) - - # testing that this doesn't raise an error because the paths exist and - # are executable - compiler.verify_executables() - - # Test that null entries don't fail - compiler.cc = None - compiler.verify_executables() - - -@pytest.mark.parametrize( - "detected_versions,expected_length", - [ - # If we detect a C compiler we expect the result to be valid - ( - [ - spack.compilers.DetectVersionArgs( - id=spack.compilers.CompilerID( - os="ubuntu20.04", compiler_name="clang", version="12.0.0" - ), - variation=spack.compilers.NameVariation(prefix="", suffix="-12"), - language="cc", - path="/usr/bin/clang-12", - ), - spack.compilers.DetectVersionArgs( - id=spack.compilers.CompilerID( - os="ubuntu20.04", compiler_name="clang", version="12.0.0" - ), - variation=spack.compilers.NameVariation(prefix="", suffix="-12"), - language="cxx", - path="/usr/bin/clang++-12", - ), - ], - 1, - ), - # If we detect only a C++ compiler we expect the result to be discarded - ( - [ - spack.compilers.DetectVersionArgs( - id=spack.compilers.CompilerID( - os="ubuntu20.04", compiler_name="clang", version="12.0.0" - ), - variation=spack.compilers.NameVariation(prefix="", suffix="-12"), - language="cxx", - path="/usr/bin/clang++-12", - ) - ], - 0, - ), - ], -) -def test_detection_requires_c_compiler(detected_versions, expected_length): - """Tests that compilers automatically added to the configuration have - at least a C compiler. - """ - result = spack.compilers.make_compiler_list(detected_versions) - assert len(result) == expected_length - - -def test_compiler_environment(working_env): - """Test whether environment modifications from compilers are applied in compiler_environment""" - os.environ.pop("TEST", None) - compiler = Compiler( - "gcc@=13.2.0", - operating_system="ubuntu20.04", - target="x86_64", - paths=["/test/bin/gcc", "/test/bin/g++"], - environment={"set": {"TEST": "yes"}}, - ) - with compiler.compiler_environment(): - assert os.environ["TEST"] == "yes" - - -def test_compiler_environment_always_flags_oneapi(working_env): - """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Oneapi compiler - environment""" - - class MockOneapiCompiler(Oneapi): - @property - def version(self): - return Version("2023.2.0") - - with spack.config.override("config:install_missing_compilers", True): - with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%oneapi@=2023.2.0 ^intel-oneapi-runtime%gcc@10.2.1").concretized() - pkg = spack.package.Package(s) - - compiler = MockOneapiCompiler( - "oneapi@=2023.2.0", - operating_system="ubuntu22.04", - target="x86_64", - paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], - ) - env = EnvironmentModifications() - compiler.setup_custom_environment(pkg, env) - shell_modifications = env.shell_modifications() - assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications - - -def test_compiler_environment_always_flags_intel(working_env): - """Test whether flags labeled as "SPACK_ALWAYS_*FLAGS" are set in the Intel compiler - environment""" - - class MockIntelCompiler(Intel): - @property - def version(self): - return Version("2023.2.0") - - with spack.config.override("config:install_missing_compilers", True): - with spack.concretize.disable_compiler_existence_check(): - s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() - pkg = spack.package.Package(s) - - compiler = MockIntelCompiler( - "intel@=2023.2.0", - operating_system="ubuntu22.04", - target="x86_64", - paths=["/test/bin/icc", "/test/bin/icpc", "/test/bin/ifort"], - ) - env = EnvironmentModifications() - compiler.setup_custom_environment(pkg, env) - shell_modifications = env.shell_modifications() - assert "export SPACK_ALWAYS_CFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_CXXFLAGS=-diag-disable=10441" in shell_modifications - assert "export SPACK_ALWAYS_FFLAGS=-diag-disable=10448" in shell_modifications diff --git a/lib/spack/spack/test/compilers/basics.py.rej b/lib/spack/spack/test/compilers/basics.py.rej deleted file mode 100644 index f9e1ff9f7d2e24..00000000000000 --- a/lib/spack/spack/test/compilers/basics.py.rej +++ /dev/null @@ -1,17 +0,0 @@ ---- lib/spack/spack/test/compilers/basics.py 2024-08-05 13:41:19.025052+00:00 -+++ lib/spack/spack/test/compilers/basics.py 2024-08-05 13:41:32.700185+00:00 -@@ -1011,13 +1013,11 @@ - def version(self): - return Version("2023.2.0") - - with spack.config.override("config:install_missing_compilers", True): - with spack.concretize.disable_compiler_existence_check(): -- s = spack.spec.Spec( -- "zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1" -- ).concretized() -+ s = spack.spec.Spec("zlib%intel@=2023.2.0 ^gcc-runtime%gcc@10.2.1").concretized() - pkg = spack.package.Package(s) - - compiler = MockIntelCompiler( - "intel@=2023.2.0", - operating_system="ubuntu22.04",