Merge topic 'ninja-showIncludes-encoding' into release-3.25

a0d4e3bf34 cmGeneratedFileStream: Drop unused WriteRaw method
2e5af30ce0 Ninja: Match showIncludes dependencies using console output code page
e1c1679148 cm_codecvt: Add support for the Windows console output code page
328c15189d cmGeneratedFileStream: Add support for a temporary alternate encoding

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !7845
This commit is contained in:
Brad King
2022-10-31 13:43:54 +00:00
committed by Kitware Robot
18 changed files with 128 additions and 35 deletions
+7 -5
View File
@@ -14,11 +14,10 @@
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
: OriginalLocale(this->getloc())
{
#ifndef CMAKE_BOOTSTRAP
if (encoding != codecvt::None) {
this->imbue(std::locale(this->OriginalLocale, new codecvt(encoding)));
this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
}
#else
static_cast<void>(encoding);
@@ -239,13 +238,16 @@ void cmGeneratedFileStream::SetTempExt(std::string const& ext)
this->TempExt = ext;
}
void cmGeneratedFileStream::WriteRaw(std::string const& data)
void cmGeneratedFileStream::WriteAltEncoding(std::string const& data,
Encoding encoding)
{
#ifndef CMAKE_BOOTSTRAP
std::locale activeLocale = this->imbue(this->OriginalLocale);
std::locale prevLocale =
this->imbue(std::locale(this->getloc(), new codecvt(encoding)));
this->write(data.data(), data.size());
this->imbue(activeLocale);
this->imbue(prevLocale);
#else
static_cast<void>(encoding);
this->write(data.data(), data.size());
#endif
}
+3 -7
View File
@@ -148,12 +148,8 @@ public:
void SetTempExt(std::string const& ext);
/**
* Writes the given string directly to the file without changing the
* encoding.
* Write a specific string using an alternate encoding.
* Afterward, the original encoding is restored.
*/
void WriteRaw(std::string const& data);
private:
// The original locale of the stream (performs no encoding conversion).
std::locale OriginalLocale;
void WriteAltEncoding(std::string const& data, Encoding encoding);
};
+5 -21
View File
@@ -88,27 +88,11 @@ void cmLocalNinjaGenerator::Generate()
cmGlobalNinjaGenerator::WriteComment(this->GetRulesFileStream(),
"localized /showIncludes string");
this->GetRulesFileStream() << "msvc_deps_prefix = ";
#ifdef _WIN32
// Ninja uses the ANSI Windows APIs, so strings in the rules file
// typically need to be ANSI encoded. However, in this case the compiler
// is being invoked using the UTF-8 codepage so the /showIncludes prefix
// will be UTF-8 encoded on stdout. Ninja can't successfully compare this
// UTF-8 encoded prefix to the ANSI encoded msvc_deps_prefix if it
// contains any non-ASCII characters and dependency checking will fail.
// As a workaround, leave the msvc_deps_prefix UTF-8 encoded even though
// the rest of the file is ANSI encoded.
if (GetConsoleOutputCP() == CP_UTF8 && GetACP() != CP_UTF8 &&
this->GetGlobalGenerator()->GetMakefileEncoding() != codecvt::None) {
this->GetRulesFileStream().WriteRaw(showIncludesPrefix);
} else {
// Ninja 1.11 and above uses the UTF-8 code page if it's supported, so
// in that case we can write it normally without using raw bytes.
this->GetRulesFileStream() << showIncludesPrefix;
}
#else
// It's safe to use the standard encoding on other platforms.
this->GetRulesFileStream() << showIncludesPrefix;
#endif
// 'cl /showIncludes' encodes output in the console output code page.
// It may differ from the encoding used for file paths in 'build.ninja'.
// Ninja matches the showIncludes prefix using its raw byte sequence.
this->GetRulesFileStream().WriteAltEncoding(
showIncludesPrefix, cmGeneratedFileStream::Encoding::ConsoleOutput);
this->GetRulesFileStream() << "\n\n";
}
}
+6
View File
@@ -19,6 +19,12 @@ codecvt::codecvt(Encoding e)
#endif
{
switch (e) {
case codecvt::ConsoleOutput:
#if defined(_WIN32)
m_noconv = false;
m_codepage = GetConsoleOutputCP();
break;
#endif
case codecvt::ANSI:
#if defined(_WIN32)
m_noconv = false;
+2 -1
View File
@@ -15,7 +15,8 @@ public:
None,
UTF8,
UTF8_WITH_BOM,
ANSI
ANSI,
ConsoleOutput,
};
#ifndef CMAKE_BOOTSTRAP