From 32c708525f80db08e6399628cdb944a67e4eba69 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 3 Feb 2022 21:38:31 +0200 Subject: [PATCH] feat: Add support for clang-cl (#993) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Co-authored-by: Luboš Luňák --- src/Config.cpp | 3 +++ src/Config.hpp | 20 +++++++++++++++++++- src/argprocessing.cpp | 24 +++++++++++------------- src/ccache.cpp | 13 +++++++------ 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index 286bdc2e2..55105a266 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -241,6 +241,8 @@ parse_compiler_type(const std::string& value) { if (value == "clang") { return CompilerType::clang; + } else if (value == "clang-cl") { + return CompilerType::clangcl; } else if (value == "gcc") { return CompilerType::gcc; } else if (value == "msvc") { @@ -451,6 +453,7 @@ compiler_type_to_string(CompilerType compiler_type) return "auto"; CASE(clang); + CASE(clangcl); CASE(gcc); CASE(msvc); CASE(nvcc); diff --git a/src/Config.hpp b/src/Config.hpp index da84e0774..d138e6dec 100644 --- a/src/Config.hpp +++ b/src/Config.hpp @@ -31,7 +31,7 @@ #include #include -enum class CompilerType { auto_guess, clang, gcc, msvc, nvcc, other }; +enum class CompilerType { auto_guess, clang, clangcl, gcc, msvc, nvcc, other }; std::string compiler_type_to_string(CompilerType compiler_type); @@ -48,6 +48,10 @@ public: const std::string& compiler() const; const std::string& compiler_check() const; CompilerType compiler_type() const; + // Returns true for clang or clangcl. + bool is_compiler_group_clang() const; + // Returns true for cl or clangcl. + bool is_compiler_group_cl() const; bool compression() const; int8_t compression_level() const; const std::string& cpp_extension() const; @@ -232,6 +236,20 @@ Config::compiler_type() const return m_compiler_type; } +inline bool +Config::is_compiler_group_clang() const +{ + return m_compiler_type == CompilerType::clang + || m_compiler_type == CompilerType::clangcl; +} + +inline bool +Config::is_compiler_group_cl() const +{ + return m_compiler_type == CompilerType::msvc + || m_compiler_type == CompilerType::clangcl; +} + inline bool Config::compression() const { diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index b036d5a6a..345a4ddd2 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -201,7 +201,7 @@ process_profiling_option(const Context& ctx, new_profile_path = arg.substr(arg.find('=') + 1); } else if (arg == "-fprofile-generate" || arg == "-fprofile-instr-generate") { args_info.profile_generate = true; - if (ctx.config.compiler_type() == CompilerType::clang) { + if (ctx.config.is_compiler_group_clang()) { new_profile_path = "."; } else { // GCC uses $PWD/$(basename $obj). @@ -273,8 +273,7 @@ process_arg(const Context& ctx, } bool changed_from_slash = false; - if (ctx.config.compiler_type() == CompilerType::msvc - && util::starts_with(args[i], "/")) { + if (ctx.config.is_compiler_group_cl() && util::starts_with(args[i], "/")) { // MSVC understands both /option and -option, so convert all /option to // -option to simplify our handling. args[i][0] = '-'; @@ -295,7 +294,7 @@ process_arg(const Context& ctx, return Statistic::called_for_preprocessing; } // MSVC -P is -E with output to a file. - if (args[i] == "-P" && ctx.config.compiler_type() == CompilerType::msvc) { + if (args[i] == "-P" && ctx.config.is_compiler_group_cl()) { return Statistic::called_for_preprocessing; } @@ -307,7 +306,7 @@ process_arg(const Context& ctx, ++argpath; } auto file_args = - Args::from_atfile(argpath, config.compiler_type() == CompilerType::msvc); + Args::from_atfile(argpath, ctx.config.is_compiler_group_cl()); if (!file_args) { LOG("Couldn't read arg file {}", argpath); return Statistic::bad_compiler_arguments; @@ -450,8 +449,7 @@ process_arg(const Context& ctx, } // MSVC -Fo with no space. - if (util::starts_with(args[i], "-Fo") - && config.compiler_type() == CompilerType::msvc) { + if (util::starts_with(args[i], "-Fo") && config.is_compiler_group_cl()) { args_info.output_obj = Util::make_relative_path(ctx, string_view(args[i]).substr(3)); return nullopt; @@ -570,7 +568,7 @@ process_arg(const Context& ctx, // These options require special handling, because they behave differently // with gcc -E, when the output file is not specified. if ((args[i] == "-MD" || args[i] == "-MMD") - && config.compiler_type() != CompilerType::msvc) { + && !config.is_compiler_group_cl()) { args_info.generating_dependencies = true; args_info.seen_MD_MMD = true; state.dep_args.push_back(args[i]); @@ -606,7 +604,7 @@ process_arg(const Context& ctx, } if ((util::starts_with(args[i], "-MQ") || util::starts_with(args[i], "-MT")) - && config.compiler_type() != CompilerType::msvc) { + && !config.is_compiler_group_cl()) { args_info.dependency_target_specified = true; if (args[i].size() == 3) { @@ -630,7 +628,7 @@ process_arg(const Context& ctx, // MSVC -MD[d], -MT[d] and -LT[d] options are something different than GCC's // -MD etc. - if (config.compiler_type() == CompilerType::msvc + if (config.is_compiler_group_cl() && (util::starts_with(args[i], "-MD") || util::starts_with(args[i], "-MT") || util::starts_with(args[i], "-LD"))) { // These affect compiler but also #define some things. @@ -880,7 +878,7 @@ process_arg(const Context& ctx, } // MSVC -u is something else than GCC -u, handle it specially. - if (args[i] == "-u" && ctx.config.compiler_type() == CompilerType::msvc) { + if (args[i] == "-u" && ctx.config.is_compiler_group_cl()) { state.cpp_args.push_back(args[i]); return nullopt; } @@ -1130,7 +1128,7 @@ process_args(Context& ctx) string_view extension; if (state.found_S_opt) { extension = ".s"; - } else if (ctx.config.compiler_type() != CompilerType::msvc) { + } else if (!ctx.config.is_compiler_group_cl()) { extension = ".o"; } else { extension = ".obj"; @@ -1306,7 +1304,7 @@ process_args(Context& ctx) // Since output is redirected, compilers will not color their output by // default, so force it explicitly. nonstd::optional diagnostics_color_arg; - if (config.compiler_type() == CompilerType::clang) { + if (config.is_compiler_group_clang()) { // Don't pass -fcolor-diagnostics when compiling assembler to avoid an // "argument unused during compilation" warning. if (args_info.actual_language != "assembler") { diff --git a/src/ccache.cpp b/src/ccache.cpp index 0d2664caa..3170d3ca1 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -229,7 +229,9 @@ guess_compiler(string_view path) const auto name = Util::to_lowercase(Util::remove_extension(Util::base_name(compiler_path))); - if (name.find("clang") != nonstd::string_view::npos) { + if (name.find("clang-cl") != nonstd::string_view::npos) { + return CompilerType::clangcl; + } else if (name.find("clang") != nonstd::string_view::npos) { return CompilerType::clang; } else if (name.find("gcc") != nonstd::string_view::npos || name.find("g++") != nonstd::string_view::npos) { @@ -934,7 +936,7 @@ to_cache(Context& ctx, const Args& depend_extra_args, Hash* depend_mode_hash) { - if (ctx.config.compiler_type() == CompilerType::msvc) { + if (ctx.config.is_compiler_group_cl()) { args.push_back(fmt::format("-Fo{}", ctx.args_info.output_obj)); } else { args.push_back("-o"); @@ -1500,7 +1502,7 @@ calculate_result_and_manifest_key(Context& ctx, // clang will emit warnings for unused linker flags, so we shouldn't skip // those arguments. - int is_clang = ctx.config.compiler_type() == CompilerType::clang + int is_clang = ctx.config.is_compiler_group_clang() || ctx.config.compiler_type() == CompilerType::other; // First the arguments. @@ -1827,7 +1829,7 @@ from_cache(Context& ctx, FromCacheCallMode mode, const Digest& result_key) // // file 'foo.h' has been modified since the precompiled header 'foo.pch' // was built - if ((ctx.config.compiler_type() == CompilerType::clang + if ((ctx.config.is_compiler_group_clang() || ctx.config.compiler_type() == CompilerType::other) && ctx.args_info.output_is_precompiled_header && mode == FromCacheCallMode::cpp) { @@ -2120,8 +2122,7 @@ do_cache_compilation(Context& ctx, const char* const* argv) TRY(set_up_uncached_err()); - if (!ctx.config.run_second_cpp() - && ctx.config.compiler_type() == CompilerType::msvc) { + if (!ctx.config.run_second_cpp() && ctx.config.is_compiler_group_cl()) { LOG_RAW("Second preprocessor cannot be disabled"); ctx.config.set_run_second_cpp(true); } -- 2.47.2