strip -Werror: all specific or none (#30284)

Add a config option to strip `-Werror*` or `-Werror=*` from compile lines everywhere.

```yaml
config:
    keep_werror: false
```

By default, we strip all `-Werror` arguments out of compile lines, to avoid unwanted
failures when upgrading compilers.  You can re-enable `-Werror` in your builds if
you really want to, with either:

```yaml
config:
    keep_werror: all
```

or to keep *just* specific `-Werror=XXX` args:

```yaml
config:
    keep_werror: specific
```

This should make swapping in newer versions of compilers much smoother when
maintainers have decided to enable `-Werror` by default.
This commit is contained in:
Tom Scogland
2022-05-23 21:57:09 -07:00
committed by GitHub
parent 306bed48d7
commit 330832c22c
5 changed files with 127 additions and 3 deletions

View File

@@ -242,6 +242,17 @@ def clean_environment():
# show useful matches.
env.set('LC_ALL', build_lang)
remove_flags = set()
keep_flags = set()
if spack.config.get('config:flags:keep_werror') == 'all':
keep_flags.add('-Werror*')
else:
if spack.config.get('config:flags:keep_werror') == 'specific':
keep_flags.add('-Werror=*')
remove_flags.add('-Werror*')
env.set('SPACK_COMPILER_FLAGS_KEEP', '|'.join(keep_flags))
env.set('SPACK_COMPILER_FLAGS_REMOVE', '|'.join(remove_flags))
# Remove any macports installs from the PATH. The macports ld can
# cause conflicts with the built-in linker on el capitan. Solves
# assembler issues, e.g.:

View File

@@ -105,6 +105,9 @@
'build_stage': '$tempdir/spack-stage',
'concretizer': 'clingo',
'license_dir': spack.paths.default_license_dir,
'flags': {
'keep_werror': 'none',
},
}
}

View File

@@ -91,7 +91,16 @@
'additional_external_search_paths': {
'type': 'array',
'items': {'type': 'string'}
}
},
'flags': {
'type': 'object',
'properties': {
'keep_werror': {
'type': 'string',
'enum': ['all', 'specific', 'none'],
},
},
},
},
'deprecatedProperties': {
'properties': ['module_roots'],

View File

@@ -12,6 +12,9 @@
import pytest
import spack.build_environment
import spack.config
import spack.spec
from spack.paths import build_env_path
from spack.util.environment import set_env, system_dirs
from spack.util.executable import Executable, ProcessError
@@ -129,7 +132,9 @@ def wrapper_environment():
SPACK_TARGET_ARGS="-march=znver2 -mtune=znver2",
SPACK_LINKER_ARG='-Wl,',
SPACK_DTAGS_TO_ADD='--disable-new-dtags',
SPACK_DTAGS_TO_STRIP='--enable-new-dtags'):
SPACK_DTAGS_TO_STRIP='--enable-new-dtags',
SPACK_COMPILER_FLAGS_KEEP='',
SPACK_COMPILER_FLAGS_REMOVE='-Werror*',):
yield
@@ -157,6 +162,21 @@ def check_args(cc, args, expected):
assert expected == cc_modified_args
def check_args_contents(cc, args, must_contain, must_not_contain):
"""Check output arguments that cc produces when called with args.
This assumes that cc will print debug command output with one element
per line, so that we see whether arguments that should (or shouldn't)
contain spaces are parsed correctly.
"""
with set_env(SPACK_TEST_COMMAND='dump-args'):
cc_modified_args = cc(*args, output=str).strip().split('\n')
for a in must_contain:
assert a in cc_modified_args
for a in must_not_contain:
assert a not in cc_modified_args
def check_env_var(executable, var, expected):
"""Check environment variables updated by the passed compiler wrapper
@@ -642,6 +662,63 @@ def test_no_ccache_prepend_for_fc(wrapper_environment):
common_compile_args)
def test_keep_and_remove(wrapper_environment):
werror_specific = ['-Werror=meh']
werror = ['-Werror']
werror_all = werror_specific + werror
with set_env(
SPACK_COMPILER_FLAGS_KEEP='',
SPACK_COMPILER_FLAGS_REMOVE='-Werror*',
):
check_args_contents(cc, test_args + werror_all, ['-Wl,--end-group'], werror_all)
with set_env(
SPACK_COMPILER_FLAGS_KEEP='-Werror=*',
SPACK_COMPILER_FLAGS_REMOVE='-Werror*',
):
check_args_contents(cc, test_args + werror_all, werror_specific, werror)
with set_env(
SPACK_COMPILER_FLAGS_KEEP='-Werror=*',
SPACK_COMPILER_FLAGS_REMOVE='-Werror*|-llib1|-Wl*',
):
check_args_contents(
cc,
test_args + werror_all,
werror_specific,
werror + ["-llib1", "-Wl,--rpath"]
)
@pytest.mark.parametrize('cfg_override,initial,expected,must_be_gone', [
# Set and unset variables
('config:flags:keep_werror:all',
['-Werror', '-Werror=specific', '-bah'],
['-Werror', '-Werror=specific', '-bah'],
[],
),
('config:flags:keep_werror:specific',
['-Werror', '-Werror=specific', '-bah'],
['-Werror=specific', '-bah'],
['-Werror'],
),
('config:flags:keep_werror:none',
['-Werror', '-Werror=specific', '-bah'],
['-bah'],
['-Werror', '-Werror=specific'],
),
])
@pytest.mark.usefixtures('wrapper_environment', 'mutable_config')
def test_flag_modification(cfg_override, initial, expected, must_be_gone):
spack.config.add(cfg_override)
env = spack.build_environment.clean_environment()
env.apply_modifications()
check_args_contents(
cc,
test_args + initial,
expected,
must_be_gone
)
@pytest.mark.regression('9160')
def test_disable_new_dtags(wrapper_environment, wrapper_flags):
with set_env(SPACK_TEST_COMMAND='dump-args'):