The default prefix is "`Note: including file:`". If you use a localized
compiler, this should be set accordingly.
+[#config_msvc_utf8]
+*msvc_utf8* (*CCACHE_MSVC_UTF8*)::
+
+ This option adds `/utf-8` to the msvc command line when executing the preprocessor to
+ ensure that filenames are not garbled for non-ascii characters.
+ This implicitly enables `/validate-charset` and treats the source code as utf-8 which
+ may cause compilation errors if comments in your code have characters in the [128, 255]
+ range for a given Windows system codepage which results in an invalid utf-8 sequence.
+ The default is true.
+
[#config_namespace]
*namespace* (*CCACHE_NAMESPACE*)::
| Unsupported source encoding |
Source file (or an included header) has unsupported encoding. ccache currently
-requires UTF-8-encoded source code for MSVC.
+requires UTF-8-encoded source code for MSVC when `msvc_utf8` is true.
| Unsupported source language |
A source language e.g. specified with `-x` was unsupported by ccache.
// compilers that don't exit with a proper status on write error to stdout.
// See also <https://github.com/llvm/llvm-project/issues/56499>.
if (ctx.config.is_compiler_group_msvc()) {
- args.push_back("-utf-8"); // Avoid garbling filenames in output
+ if (ctx.config.msvc_utf8()) {
+ args.push_back("-utf-8"); // Avoid garbling filenames in output
+ }
args.push_back("-P");
args.push_back(FMT("-Fi{}", preprocessed_path));
} else {
cpp_stderr_data = result->stderr_data;
cpp_stdout_data = result->stdout_data;
- if (ctx.config.is_compiler_group_msvc()) {
+ if (ctx.config.is_compiler_group_msvc() && ctx.config.msvc_utf8()) {
// Check that usage of -utf-8 didn't garble the preprocessor output.
static constexpr char warning_c4828[] =
"warning C4828: The file contains a character starting at offset";
max_files,
max_size,
msvc_dep_prefix,
+ msvc_utf8,
namespace_,
path,
pch_external_checksum,
{"max_files", {ConfigItem::max_files} },
{"max_size", {ConfigItem::max_size} },
{"msvc_dep_prefix", {ConfigItem::msvc_dep_prefix} },
+ {"msvc_utf8", {ConfigItem::msvc_utf8} },
{"namespace", {ConfigItem::namespace_} },
{"path", {ConfigItem::path} },
{"pch_external_checksum", {ConfigItem::pch_external_checksum} },
{"MAXFILES", "max_files" },
{"MAXSIZE", "max_size" },
{"MSVC_DEP_PREFIX", "msvc_dep_prefix" },
+ {"MSVC_UTF8", "msvc_utf8" },
{"NAMESPACE", "namespace" },
{"PATH", "path" },
{"PCH_EXTSUM", "pch_external_checksum" },
case ConfigItem::msvc_dep_prefix:
return m_msvc_dep_prefix;
+ case ConfigItem::msvc_utf8:
+ return format_bool(m_msvc_utf8);
+
case ConfigItem::namespace_:
return m_namespace;
m_msvc_dep_prefix = value;
break;
+ case ConfigItem::msvc_utf8:
+ m_msvc_utf8 = parse_bool(value, env_var_key, negate);
+ break;
+
case ConfigItem::namespace_:
m_namespace = value;
break;
uint64_t max_files() const;
uint64_t max_size() const;
const std::string& msvc_dep_prefix() const;
+ bool msvc_utf8() const;
const std::string& path() const;
bool pch_external_checksum() const;
const std::string& prefix_command() const;
void set_inode_cache(bool value);
void set_max_files(uint64_t value);
void set_msvc_dep_prefix(const std::string& value);
+ void set_msvc_utf8(bool value);
void set_temporary_dir(const std::filesystem::path& value);
// Where to write configuration changes.
uint64_t m_max_files = 0;
uint64_t m_max_size = 5ULL * 1024 * 1024 * 1024;
std::string m_msvc_dep_prefix = "Note: including file:";
+ bool m_msvc_utf8 = true;
std::string m_path;
bool m_pch_external_checksum = false;
std::string m_prefix_command;
return m_msvc_dep_prefix;
}
+inline bool
+Config::msvc_utf8() const
+{
+ return m_msvc_utf8;
+}
+
inline const std::string&
Config::path() const
{
m_msvc_dep_prefix = value;
}
+inline void
+Config::set_msvc_utf8(bool value)
+{
+ m_msvc_utf8 = value;
+}
+
inline void
Config::set_temporary_dir(const std::filesystem::path& value)
{
CHECK(config.max_files() == 0);
CHECK(config.max_size() == static_cast<uint64_t>(5) * 1024 * 1024 * 1024);
CHECK(config.msvc_dep_prefix() == "Note: including file:");
+ CHECK(config.msvc_utf8());
CHECK(config.path().empty());
CHECK_FALSE(config.pch_external_checksum());
CHECK(config.prefix_command().empty());
"max_files = 17\n"
"max_size = 123M\n"
"msvc_dep_prefix = Some other prefix:\n"
+ "msvc_utf8 = false\n"
"path = $USER.x\n"
"pch_external_checksum = true\n"
"prefix_command = x$USER\n"
CHECK(config.max_files() == 17);
CHECK(config.max_size() == 123 * 1000 * 1000);
CHECK(config.msvc_dep_prefix() == "Some other prefix:");
+ CHECK_FALSE(config.msvc_utf8());
CHECK(config.path() == FMT("{}.x", user));
CHECK(config.pch_external_checksum());
CHECK(config.prefix_command() == FMT("x{}", user));
"max_files = 4711\n"
"max_size = 98.7M\n"
"msvc_dep_prefix = mdp\n"
+ "msvc_utf8 = true\n"
"namespace = ns\n"
"path = p\n"
"pch_external_checksum = true\n"
"(test.conf) max_files = 4711",
"(test.conf) max_size = 98.7 MB",
"(test.conf) msvc_dep_prefix = mdp",
+ "(test.conf) msvc_utf8 = true",
"(test.conf) namespace = ns",
"(test.conf) path = p",
"(test.conf) pch_external_checksum = true",