#include <optional>
#include <string>
+#include <unordered_map>
#include <vector>
// This class holds meta-information derived from the compiler arguments.
// Architectures from -arch options.
std::vector<std::string> arch_args;
+ // Values for -Xarch_* options.
+ std::unordered_map<std::string, std::vector<std::string>> xarch_args;
+
// Relocating debuginfo in the format old=new.
std::vector<std::string> debug_prefix_maps;
ColorDiagnostics color_diagnostics = ColorDiagnostics::automatic;
bool found_directives_only = false;
bool found_rewrite_includes = false;
- std::optional<std::string> found_xarch_arch;
+ std::unordered_map<std::string, std::vector<std::string>> xarch_args;
bool found_mf_opt = false;
bool found_wp_md_or_mmd_opt = false;
bool found_md_or_mmd_opt = false;
config.set_direct_mode(false);
}
- // -Xarch_* options are too hard.
+ // -Xarch_* options need to be handled with care
if (util::starts_with(arg, "-Xarch_")) {
if (i == args.size() - 1) {
LOG("Missing argument to {}", args[i]);
return Statistic::bad_compiler_arguments;
}
const auto arch = arg.substr(7);
- if (!state.found_xarch_arch) {
- state.found_xarch_arch = arch;
- } else if (*state.found_xarch_arch != arch) {
- LOG_RAW("Multiple different -Xarch_* options not supported");
- return Statistic::unsupported_compiler_option;
- }
- state.common_args.push_back(args[i]);
+ auto [it, inserted] =
+ state.xarch_args.emplace(arch, std::vector<std::string>());
+ it->second.emplace_back(args[i + 1]);
+ ++i;
return Statistic::none;
}
compiler_args.push_back("-dc");
}
- if (state.found_xarch_arch && !args_info.arch_args.empty()) {
- if (args_info.arch_args.size() > 1) {
- LOG_RAW(
- "Multiple -arch options in combination with -Xarch_* not supported");
- return Statistic::unsupported_compiler_option;
- } else if (args_info.arch_args[0] != *state.found_xarch_arch) {
- LOG_RAW("-arch option not matching -Xarch_* option not supported");
- return Statistic::unsupported_compiler_option;
+ if (!state.xarch_args.empty()) {
+ for (const auto& arch : args_info.arch_args) {
+ auto it = state.xarch_args.find(arch);
+ if (it != state.xarch_args.end()) {
+ args_info.xarch_args.emplace(arch, it->second);
+ }
}
}
for (const auto& arch : args_info.arch_args) {
compiler_args.push_back("-arch");
compiler_args.push_back(arch);
+
+ auto it = args_info.xarch_args.find(arch);
+ if (it != args_info.xarch_args.end()) {
+ args_info.xarch_args.emplace(arch, it->second);
+
+ for (const auto& xarch : it->second) {
+ compiler_args.push_back("-Xarch_" + arch);
+ compiler_args.push_back(xarch);
+ }
+ }
}
Args preprocessor_args = state.common_args;
for (const auto& arch : ctx.args_info.arch_args) {
hash.hash_delimiter("-arch");
hash.hash(arch);
+
+ // Adding -Xarch_* to hash since cpp output is affected.
+ auto it = ctx.args_info.xarch_args.find(arch);
+ if (it != ctx.args_info.xarch_args.end()) {
+ for (const auto& xarch : it->second) {
+ hash.hash_delimiter("-Xarch_" + arch);
+ hash.hash(xarch);
+ }
+ }
}
std::optional<Hash::Digest> result_key;
} else {
preprocessor_args->push_back("-arch");
for (size_t i = 0; i < ctx.args_info.arch_args.size(); ++i) {
- preprocessor_args->push_back(ctx.args_info.arch_args[i]);
+ const auto& arch = ctx.args_info.arch_args[i];
+ size_t xarch_count{};
+ preprocessor_args->push_back(arch);
+ auto it = ctx.args_info.xarch_args.find(arch);
+ if (it != ctx.args_info.xarch_args.end()) {
+ for (const auto& xarch : it->second) {
+ preprocessor_args->push_back("-Xarch_" + arch);
+ preprocessor_args->push_back(xarch);
+ xarch_count += 2;
+ }
+ }
const auto digest =
get_result_key_from_cpp(ctx, *preprocessor_args, hash);
if (!digest) {
return nonstd::make_unexpected(digest.error());
}
result_key = *digest;
- LOG("Got result key from preprocessor with -arch {}",
- ctx.args_info.arch_args[i]);
+ LOG("Got result key from preprocessor with -arch {}", arch);
if (i != ctx.args_info.arch_args.size() - 1) {
result_key = std::nullopt;
}
preprocessor_args->pop_back();
+ if (xarch_count > 0) {
+ preprocessor_args->pop_back(xarch_count);
+ }
}
preprocessor_args->pop_back();
}
expect_stat direct_cache_hit 2
expect_stat cache_miss 3
- # A single -Xarch_* matching -arch is supported.
CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
expect_stat direct_cache_hit 2
expect_stat cache_miss 4
- expect_contains test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -arch x86_64 -E"
- expect_not_contains test1.o.*.ccache-log "clang -Xarch_x86_64 -I. -I. -arch x86_64 -E"
+ expect_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -E"
+ expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -E"
$CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -c test1.c
expect_stat direct_cache_hit 3
expect_stat cache_miss 4
- # The parameter following -Xarch should be processed.
- $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -analyze -I. -c test1.c
- expect_stat unsupported_compiler_option 1
+ # -------------------------------------------------------------------------
+ TEST "cache hit, direct mode, multiple -Xarch_* arguments"
+
+ CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -arch arm64 -Xarch_x86_64 -I. -Xarch_arm64 -I. -c test1.c
+ expect_stat direct_cache_hit 0
+ expect_stat cache_miss 1
+ expect_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -E"
+ expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -E"
+ expect_contains test1.o.*.ccache-log "clang -arch arm64 -Xarch_arm64 -I. -E"
+ expect_not_contains test1.o.*.ccache-log "clang -arch arm64 -Xarch_arm64 -I. -I. -E"
+
+ $CCACHE_COMPILE -arch x86_64 -arch arm64 -Xarch_x86_64 -I. -Xarch_arm64 -I. -c test1.c
+ expect_stat direct_cache_hit 1
+ expect_stat cache_miss 1
+
+ # -------------------------------------------------------------------------
+ TEST "cache hit, direct mode, multiple -Xarch_* arguments for single arch"
+
+ CCACHE_DEBUG=1 $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -c test1.c
+ expect_stat direct_cache_hit 0
+ expect_stat cache_miss 1
+ expect_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -E"
+ expect_not_contains test1.o.*.ccache-log "clang -arch x86_64 -Xarch_x86_64 -I. -I. -Xarch_x86_64 -Ifoo -E"
+
+ $CCACHE_COMPILE -arch x86_64 -Xarch_x86_64 -I. -Xarch_x86_64 -Ifoo -c test1.c
+ expect_stat direct_cache_hit 1
+ expect_stat cache_miss 1
# -------------------------------------------------------------------------
TEST "cache hit, preprocessor mode"