Summary
When target_os = "qnx" is selected for a gcc.toolchain tag, the version attribute (and the GCC version resolved from the version matrix) is not used to control which GCC version qcc invokes. The compiler/linker -V flag was hardcoded to 12.2.0 regardless of the toolchain instance's actual configured/resolved version.
Affected component
extensions/gcc.bzl (module extension, gcc.toolchain tag)
features/custom/qnx/gcc_version_flags/BUILD
features/custom/qnx/make_cc_features.bzl
rules/gcc.bzl
Steps to reproduce
- Define a QNX toolchain via the
gcc module extension with an explicit version (or an SDP version whose matrix entry resolves to a GCC version other than 12.2.0), e.g.:
gcc.toolchain(
name = "score_qcc_toolchain",
sdp_version = "8.0.4",
target_cpu = "x86_64",
target_os = "qnx",
use_default_package = True,
)
- Build any C/C++ target with that toolchain and inspect the compile/link action command line, e.g.:
bazel aquery --config=x86_64-qnx 'mnemonic("CppCompile", //some:target)'
- Observe the
-V flag passed to qcc.
Expected behavior
The -V<version>,gcc_nto<cpu> flag should reflect the GCC version actually resolved for that toolchain instance (from the explicit version attribute or the version matrix entry for the given sdp_version).
Actual behavior
The flag is always -V12.2.0,gcc_nto<cpu> / -V12.2.0,gcc_nto<cpu>_cxx, no matter what version/gcc_version was resolved for the toolchain instance.
Root cause
extensions/gcc.bzl correctly threads the toolchain tag's version through to gcc_toolchain(gcc_version = ...), and rules/gcc.bzl substitutes it into %{tc_version} in the generated templates/BUILD.template / templates/cc_toolchain_config.bzl.template.
- However, the actual
-V flag passed to qcc comes from a separate, static, non-templated feature target:
# features/custom/qnx/gcc_version_flags/BUILD
cc_args(
name = "qnx_gcc_version_compile_args",
actions = ["@rules_cc//cc/toolchains/actions:compile_actions"],
args = select({
"@score_bazel_platforms//settings:aarch64-qnx8": ["-V12.2.0,gcc_ntoaarch64le"],
"@score_bazel_platforms//settings:x86_64-qnx8": ["-V12.2.0,gcc_ntox86_64"],
}),
)
This target is referenced by a single shared label in _QNX_FEATURES (features/custom/qnx/make_cc_features.bzl), so it's identical across every QNX toolchain instance and never consults gcc_version/%{tc_version}.
- This has gone unnoticed because every QNX SDP entry currently in
packages/version_matrix.bzl (8.0.0, 8.0.4) happens to resolve to GCC 12.2.0, matching the hardcoded value by coincidence.
Impact
Any QNX toolchain instance whose resolved GCC version differs from 12.2.0 (e.g. an explicit version override, or a future SDP matrix entry bundling a different GCC release) will silently compile/link with the wrong -V identifier, causing qcc to select the wrong bundled GCC version without any error.
Suggested fix
Convert gcc_version_flags from a static, repo-wide feature into a per-toolchain-instance generated feature (mirroring the existing sdp_env pattern):
- Add a
make_gcc_version_flags_feature(cpu, version) macro that builds the -V{version},gcc_nto{cpu}[_cxx] args from the toolchain's resolved gcc_version + normalized CPU.
- Instantiate it per-repo from
rules/gcc.bzl's get_custom_cc_features_qnx(), alongside sdp_env.
- Update
_QNX_FEATURES in make_cc_features.bzl to reference the per-instance :gcc_version_flags label instead of the shared repo-wide target.
- Remove the hardcoded
12.2.0 select() from the static BUILD file.
Additional follow-up (optional, related)
Since QNX SDP major versions map to a known GCC version (e.g. SDP 7.x → GCC 8.3.0, SDP 8.x → GCC 12.2.0), consider adding an explicit QNX_SDP_TO_GCC_VERSION lookup (in rules/common.bzl) so that:
gcc_version can be defaulted from sdp_version alone, without needing to duplicate it across every packages/version_matrix.bzl entry, and without requiring the "use default package" code path.
- An explicit, mismatched
version attribute (e.g. sdp_version = "8.0.4" with version = "8.3.0") fails the build with a clear error instead of silently building with an inconsistent toolchain/version pairing.
Summary
When
target_os = "qnx"is selected for agcc.toolchaintag, theversionattribute (and the GCC version resolved from the version matrix) is not used to control which GCC versionqccinvokes. The compiler/linker-Vflag was hardcoded to12.2.0regardless of the toolchain instance's actual configured/resolved version.Affected component
extensions/gcc.bzl(module extension,gcc.toolchaintag)features/custom/qnx/gcc_version_flags/BUILDfeatures/custom/qnx/make_cc_features.bzlrules/gcc.bzlSteps to reproduce
gccmodule extension with an explicitversion(or an SDP version whose matrix entry resolves to a GCC version other than12.2.0), e.g.:-Vflag passed toqcc.Expected behavior
The
-V<version>,gcc_nto<cpu>flag should reflect the GCC version actually resolved for that toolchain instance (from the explicitversionattribute or the version matrix entry for the givensdp_version).Actual behavior
The flag is always
-V12.2.0,gcc_nto<cpu>/-V12.2.0,gcc_nto<cpu>_cxx, no matter whatversion/gcc_versionwas resolved for the toolchain instance.Root cause
extensions/gcc.bzlcorrectly threads the toolchain tag'sversionthrough togcc_toolchain(gcc_version = ...), andrules/gcc.bzlsubstitutes it into%{tc_version}in the generatedtemplates/BUILD.template/templates/cc_toolchain_config.bzl.template.-Vflag passed toqcccomes from a separate, static, non-templated feature target:_QNX_FEATURES(features/custom/qnx/make_cc_features.bzl), so it's identical across every QNX toolchain instance and never consultsgcc_version/%{tc_version}.packages/version_matrix.bzl(8.0.0,8.0.4) happens to resolve to GCC12.2.0, matching the hardcoded value by coincidence.Impact
Any QNX toolchain instance whose resolved GCC version differs from
12.2.0(e.g. an explicitversionoverride, or a future SDP matrix entry bundling a different GCC release) will silently compile/link with the wrong-Videntifier, causingqccto select the wrong bundled GCC version without any error.Suggested fix
Convert
gcc_version_flagsfrom a static, repo-wide feature into a per-toolchain-instance generated feature (mirroring the existingsdp_envpattern):make_gcc_version_flags_feature(cpu, version)macro that builds the-V{version},gcc_nto{cpu}[_cxx]args from the toolchain's resolvedgcc_version+ normalized CPU.rules/gcc.bzl'sget_custom_cc_features_qnx(), alongsidesdp_env._QNX_FEATURESinmake_cc_features.bzlto reference the per-instance:gcc_version_flagslabel instead of the shared repo-wide target.12.2.0select()from the staticBUILDfile.Additional follow-up (optional, related)
Since QNX SDP major versions map to a known GCC version (e.g. SDP 7.x → GCC 8.3.0, SDP 8.x → GCC 12.2.0), consider adding an explicit
QNX_SDP_TO_GCC_VERSIONlookup (inrules/common.bzl) so that:gcc_versioncan be defaulted fromsdp_versionalone, without needing to duplicate it across everypackages/version_matrix.bzlentry, and without requiring the "use default package" code path.versionattribute (e.g.sdp_version = "8.0.4"withversion = "8.3.0") fails the build with a clear error instead of silently building with an inconsistent toolchain/version pairing.