summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalNinjaGenerator.cxx
diff options
context:
space:
mode:
authorKyle Edwards <kyle.edwards@kitware.com>2021-02-26 16:49:50 (GMT)
committerKyle Edwards <kyle.edwards@kitware.com>2021-03-09 16:09:24 (GMT)
commit9af6e2e7b2940d5ba4d138f0df5950a675ec41c0 (patch)
treeed6741d332a8c57fe1d1dab37292a842b516cedd /Source/cmGlobalNinjaGenerator.cxx
parent4250c5f91b67a84318c31485a2ab36ab64967f21 (diff)
downloadCMake-9af6e2e7b2940d5ba4d138f0df5950a675ec41c0.zip
CMake-9af6e2e7b2940d5ba4d138f0df5950a675ec41c0.tar.gz
CMake-9af6e2e7b2940d5ba4d138f0df5950a675ec41c0.tar.bz2
Ninja: Use new wincodepage tool to determine encoding
Ninja 1.11 and later uses UTF-8 on Windows when possible, and includes a tool that reports the code page in use. Use this tool to determine what encoding to write the Ninja files in. Fixes: #21866
Diffstat (limited to 'Source/cmGlobalNinjaGenerator.cxx')
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx65
1 files changed, 57 insertions, 8 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 7eac169..36be45c 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -9,6 +9,7 @@
#include <cm/iterator>
#include <cm/memory>
+#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/memory>
@@ -503,14 +504,7 @@ std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
{
-#ifdef _WIN32
- // Ninja on Windows does not support non-ANSI characters.
- // https://github.com/ninja-build/ninja/issues/1195
- return codecvt::ANSI;
-#else
- // No encoding conversion needed on other platforms.
- return codecvt::None;
-#endif
+ return this->NinjaExpectedEncoding;
}
void cmGlobalNinjaGenerator::GetDocumentation(cmDocumentationEntry& entry)
@@ -731,6 +725,61 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
this->NinjaSupportsMetadataOnRegeneration = !cmSystemTools::VersionCompare(
cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
RequiredNinjaVersionForMetadataOnRegeneration().c_str());
+#ifdef _WIN32
+ this->NinjaSupportsCodePage = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForCodePage().c_str());
+ if (this->NinjaSupportsCodePage) {
+ this->CheckNinjaCodePage();
+ } else {
+ this->NinjaExpectedEncoding = codecvt::ANSI;
+ }
+#endif
+}
+
+void cmGlobalNinjaGenerator::CheckNinjaCodePage()
+{
+ std::vector<std::string> command{ this->NinjaCommand, "-t", "wincodepage" };
+ std::string output;
+ std::string error;
+ int result;
+ if (!cmSystemTools::RunSingleCommand(command, &output, &error, &result,
+ nullptr, cmSystemTools::OUTPUT_NONE)) {
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Running\n '",
+ cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ error));
+ cmSystemTools::SetFatalErrorOccured();
+ } else if (result == 0) {
+ std::istringstream outputStream(output);
+ std::string line;
+ bool found = false;
+ while (cmSystemTools::GetLineFromStream(outputStream, line)) {
+ if (cmHasLiteralPrefix(line, "Build file encoding: ")) {
+ cm::string_view lineView(line);
+ cm::string_view encoding =
+ lineView.substr(cmStrLen("Build file encoding: "));
+ if (encoding == "UTF-8") {
+ // Ninja expects UTF-8. We use that internally. No conversion needed.
+ this->NinjaExpectedEncoding = codecvt::None;
+ } else {
+ this->NinjaExpectedEncoding = codecvt::ANSI;
+ }
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ this->GetCMakeInstance()->IssueMessage(
+ MessageType::WARNING,
+ "Could not determine Ninja's code page, defaulting to UTF-8");
+ this->NinjaExpectedEncoding = codecvt::None;
+ }
+ } else {
+ this->NinjaExpectedEncoding = codecvt::ANSI;
+ }
}
bool cmGlobalNinjaGenerator::CheckLanguages(