From f7e6700393d0dec766e2e806cea749bd45475b62 Mon Sep 17 00:00:00 2001 From: Joy Wang Date: Tue, 21 Jul 2026 17:14:28 +0800 Subject: [PATCH] feat: Add support for QCC (QNX) compiler (#1701) --- doc/manual.adoc | 2 ++ doc/news.adoc | 2 ++ src/ccache/argprocessing.cpp | 12 ++++++------ src/ccache/ccache.cpp | 22 ++++++++++++++++++---- src/ccache/compopt.cpp | 1 + src/ccache/config.cpp | 3 +++ src/ccache/config.hpp | 11 +++++++++++ unittest/test_ccache.cpp | 3 +++ 8 files changed, 46 insertions(+), 10 deletions(-) diff --git a/doc/manual.adoc b/doc/manual.adoc index d20fb10c..88910d41 100644 --- a/doc/manual.adoc +++ b/doc/manual.adoc @@ -683,6 +683,8 @@ _<>_. Microsoft Visual C++ (MSVC). *nvcc*:: NVCC (CUDA) compiler. +*qcc*:: + QCC (QNX) compiler. *other*:: Any compiler other than the known types. -- diff --git a/doc/news.adoc b/doc/news.adoc index 450bd2c3..74b05a71 100644 --- a/doc/news.adoc +++ b/doc/news.adoc @@ -261,6 +261,8 @@ Release date: 2026-03-05 - Added support for caching distributed ThinLTO for Clang. + [small]#_[contributed by GitHub user zcfh]_# +- Added support for QCC (QNX) compiler. + - Added support for caching MSVC `/sourceDependencies` file. + [small]#_[contributed by Joel Rosdahl]_# diff --git a/src/ccache/argprocessing.cpp b/src/ccache/argprocessing.cpp index 5fc70ecd..22bb66d4 100644 --- a/src/ccache/argprocessing.cpp +++ b/src/ccache/argprocessing.cpp @@ -1181,7 +1181,7 @@ process_option_arg(const Context& ctx, return Statistic::none; } - if (config.compiler_type() == CompilerType::gcc) { + if (config.is_compiler_group_gcc()) { if (arg == "-fdiagnostics-color" || arg == "-fdiagnostics-color=always") { state.color_diagnostics = ColorDiagnostics::always; state.add_compiler_only_arg_no_hash(args[i]); @@ -1798,7 +1798,7 @@ process_args(Context& ctx) if (args_info.actual_language != "assembler") { diagnostics_color_arg = "-fcolor-diagnostics"; } - } else if (config.compiler_type() == CompilerType::gcc) { + } else if (config.is_compiler_group_gcc()) { diagnostics_color_arg = "-fdiagnostics-color"; } else { // Other compilers shouldn't output color, so no need to strip it. @@ -1822,9 +1822,9 @@ process_args(Context& ctx) if (config.compiler_type() == CompilerType::clang) { // Clang does the sane thing: the dependency target is the output file // so that the dependency file actually makes sense. - } else if (config.compiler_type() == CompilerType::gcc) { - // GCC strangely uses the base name of the source file but with a .o - // extension. + } else if (config.is_compiler_group_gcc()) { + // GCC (and QCC) strangely uses the base name of the source file but + // with a .o extension. dep_target = util::with_extension(args_info.orig_input_file.filename(), get_default_object_file_extension(ctx.config)); @@ -1832,7 +1832,7 @@ process_args(Context& ctx) // How other compilers behave is currently unknown, so bail out. LOG( "-Wp,-M[M]D with -o without -MMD, -MQ or -MT is only supported for" - " GCC or Clang"); + " GCC-like or Clang compilers"); return tl::unexpected(Statistic::unsupported_compiler_option); } } diff --git a/src/ccache/ccache.cpp b/src/ccache/ccache.cpp index 2ff0cf9d..86d3f81b 100644 --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp @@ -334,6 +334,8 @@ do_guess_compiler(const fs::path& path) return CompilerType::gcc; } else if (name.find("nvcc") != std::string_view::npos) { return CompilerType::nvcc; + } else if (name == "qcc" || name == "q++") { + return CompilerType::qcc; } else if (name == "icl") { return CompilerType::icl; } else if (name == "icx") { @@ -833,7 +835,7 @@ do_execute(Context& ctx, util::Args& args, const bool capture_stdout = true) util::UmaskScope umask_scope(ctx.original_umask); if (ctx.diagnostics_color_failed) { - DEBUG_ASSERT(ctx.config.compiler_type() == CompilerType::gcc); + DEBUG_ASSERT(ctx.config.is_compiler_group_gcc()); args.erase_last("-fdiagnostics-color"); } @@ -845,11 +847,11 @@ do_execute(Context& ctx, util::Args& args, const bool capture_stdout = true) std::move(tmp_stdout.fd), std::move(tmp_stderr.fd)); if (status != 0 && !ctx.diagnostics_color_failed - && ctx.config.compiler_type() == CompilerType::gcc) { + && ctx.config.is_compiler_group_gcc()) { const auto errors = util::read_file(tmp_stderr.path); if (errors && errors->find("fdiagnostics-color") != std::string::npos) { // GCC versions older than 4.9 don't understand -fdiagnostics-color, and - // non-GCC compilers misclassified as CompilerType::gcc might not do it + // non-GCC compilers misclassified as GCC-like might not do it // either. We assume that if the error message contains // "fdiagnostics-color" then the compilation failed due to // -fdiagnostics-color being unsupported and we then retry without the @@ -1905,7 +1907,7 @@ hash_common_info(const Context& ctx, const util::Args& args, Hash& hash) } // Possibly hash GCC_COLORS (for color diagnostics). - if (ctx.config.compiler_type() == CompilerType::gcc) { + if (ctx.config.is_compiler_group_gcc()) { const char* gcc_colors = getenv("GCC_COLORS"); if (gcc_colors) { hash.hash_delimiter("gcccolors"); @@ -1913,6 +1915,18 @@ hash_common_info(const Context& ctx, const util::Args& args, Hash& hash) } } + // Hash QNX-specific environment variables that affect QCC behavior. + if (ctx.config.compiler_type() == CompilerType::qcc) { + const char* qnx_env_vars[] = {"QNX_HOST", "QNX_TARGET", "QCC_CONF_PATH"}; + for (const char* name : qnx_env_vars) { + const char* value = getenv(name); + if (value) { + hash.hash_delimiter(name); + hash.hash(value); + } + } + } + return {}; } diff --git a/src/ccache/compopt.cpp b/src/ccache/compopt.cpp index 8db5fea9..a05567de 100644 --- a/src/ccache/compopt.cpp +++ b/src/ccache/compopt.cpp @@ -172,6 +172,7 @@ const CompOpt compopts[] = { {"-save-temps", TOO_HARD }, {"-save-temps=cwd", TOO_HARD }, {"-save-temps=obj", TOO_HARD }, + {"-set-default", TOO_HARD }, // qcc {"-specs", TAKES_ARG }, {"-stdlib=", AFFECTS_CPP | TAKES_CONCAT_ARG }, {"-trigraphs", AFFECTS_CPP }, diff --git a/src/ccache/config.cpp b/src/ccache/config.cpp index d748604f..a18e9e58 100644 --- a/src/ccache/config.cpp +++ b/src/ccache/config.cpp @@ -353,6 +353,8 @@ parse_compiler_type(const std::string& value) return CompilerType::msvc; } else if (value == "nvcc") { return CompilerType::nvcc; + } else if (value == "qcc") { + return CompilerType::qcc; } else if (value == "other") { return CompilerType::other; } else { @@ -628,6 +630,7 @@ compiler_type_to_string(CompilerType compiler_type) CASE(icx); CASE(msvc); CASE(nvcc); + CASE(qcc); CASE(other); } #undef CASE diff --git a/src/ccache/config.hpp b/src/ccache/config.hpp index 0951b92b..f687d425 100644 --- a/src/ccache/config.hpp +++ b/src/ccache/config.hpp @@ -45,6 +45,7 @@ enum class CompilerType { icx_cl, msvc, nvcc, + qcc, other }; @@ -113,6 +114,9 @@ public: // Return true for Clang, clang-cl and icx (not on Windows). bool is_compiler_group_clang() const; + // Return true for GCC and QCC (QNX compiler, which is GCC-based). + bool is_compiler_group_gcc() const; + // Return true for MSVC (cl.exe), clang-cl, icl, icx-cl, and icx (on Windows). bool is_compiler_group_msvc() const; @@ -318,6 +322,13 @@ Config::is_compiler_group_clang() const || m_compiler_type == CompilerType::clang_cl; } +inline bool +Config::is_compiler_group_gcc() const +{ + return m_compiler_type == CompilerType::gcc + || m_compiler_type == CompilerType::qcc; +} + inline bool Config::is_compiler_group_msvc() const { diff --git a/unittest/test_ccache.cpp b/unittest/test_ccache.cpp index b2033993..20c2e644 100644 --- a/unittest/test_ccache.cpp +++ b/unittest/test_ccache.cpp @@ -197,6 +197,9 @@ TEST_CASE("guess_compiler") CHECK(guess_compiler("/test/prefix/nvcc") == CompilerType::nvcc); CHECK(guess_compiler("/test/prefix/nvcc-10.1.243") == CompilerType::nvcc); + CHECK(guess_compiler("/test/prefix/qcc") == CompilerType::qcc); + CHECK(guess_compiler("/test/prefix/q++") == CompilerType::qcc); + CHECK(guess_compiler("/test/prefix/x") == CompilerType::other); CHECK(guess_compiler("/test/prefix/cc") == CompilerType::other); CHECK(guess_compiler("/test/prefix/c++") == CompilerType::other); -- 2.47.3