summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/release/dev/nmake-utf8.rst5
-rw-r--r--Source/cmGeneratedFileStream.cxx5
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx41
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h7
-rw-r--r--Source/cmMakefileTargetGenerator.cxx3
-rw-r--r--Source/cm_codecvt.cxx1
-rw-r--r--Source/cm_codecvt.hxx1
7 files changed, 61 insertions, 2 deletions
diff --git a/Help/release/dev/nmake-utf8.rst b/Help/release/dev/nmake-utf8.rst
new file mode 100644
index 0000000..ebbb45b
--- /dev/null
+++ b/Help/release/dev/nmake-utf8.rst
@@ -0,0 +1,5 @@
+nmake-utf8
+----------
+
+* The :generator:`NMake Makefiles` generator now encodes the generated
+ makefiles as UTF-8 with a BOM when using ``nmake`` from VS 9 or above.
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 43f384a..06778b1 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -42,6 +42,11 @@ cmGeneratedFileStream::cmGeneratedFileStream(std::string const& name,
#else
static_cast<void>(encoding);
#endif
+ if (encoding == codecvt::UTF8_WITH_BOM) {
+ // Write the BOM encoding header into the file
+ char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
+ this->write(magic, 3);
+ }
}
cmGeneratedFileStream::~cmGeneratedFileStream()
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 36f583f..313f39b 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -2,7 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalNMakeMakefileGenerator.h"
+#include "cmsys/RegularExpression.hxx"
+
#include "cmDocumentationEntry.h"
+#include "cmDuration.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -34,6 +37,44 @@ void cmGlobalNMakeMakefileGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
+bool cmGlobalNMakeMakefileGenerator::FindMakeProgram(cmMakefile* mf)
+{
+ if (!this->cmGlobalGenerator::FindMakeProgram(mf)) {
+ return false;
+ }
+ if (cmProp nmakeCommand = mf->GetDefinition("CMAKE_MAKE_PROGRAM")) {
+ std::vector<std::string> command;
+ command.emplace_back(*nmakeCommand);
+ command.emplace_back("-?");
+ std::string out;
+ std::string err;
+ if (!cmSystemTools::RunSingleCommand(command, &out, &err, nullptr, nullptr,
+ cmSystemTools::OUTPUT_NONE,
+ cmDuration(30))) {
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Running\n '", cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ err));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ cmsys::RegularExpression regex(
+ "Program Maintenance Utility Version ([1-9][0-9.]+)");
+ if (regex.find(err)) {
+ this->NMakeVersion = regex.match(1);
+ this->CheckNMakeFeatures();
+ }
+ }
+ return true;
+}
+
+void cmGlobalNMakeMakefileGenerator::CheckNMakeFeatures()
+{
+ this->NMakeSupportsUTF8 = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NMakeVersion.c_str(), "9");
+}
+
void cmGlobalNMakeMakefileGenerator::GetDocumentation(
cmDocumentationEntry& entry)
{
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index abe64ff..402b89f 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -31,7 +31,7 @@ public:
/** Get encoding used by generator for makefile files */
codecvt::Encoding GetMakefileEncoding() const override
{
- return codecvt::ANSI;
+ return this->NMakeSupportsUTF8 ? codecvt::UTF8_WITH_BOM : codecvt::ANSI;
}
/** Get the documentation entry for this generator. */
@@ -55,6 +55,11 @@ protected:
void PrintBuildCommandAdvice(std::ostream& os, int jobs) const override;
private:
+ bool NMakeSupportsUTF8 = false;
+ std::string NMakeVersion;
+ bool FindMakeProgram(cmMakefile* mf) override;
+ void CheckNMakeFeatures();
+
void PrintCompilerAdvice(std::ostream& os, std::string const& lang,
const char* envVar) const override;
};
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index fa469ed..5b6c58d 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -2058,7 +2058,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
// Create the response file.
std::string responseFileNameFull =
cmStrCat(this->TargetBuildDirectoryFull, '/', name);
- cmGeneratedFileStream responseStream(responseFileNameFull);
+ cmGeneratedFileStream responseStream(
+ responseFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
responseStream.SetCopyIfDifferent(true);
responseStream << options << "\n";
diff --git a/Source/cm_codecvt.cxx b/Source/cm_codecvt.cxx
index 15f83e0..216d3f0 100644
--- a/Source/cm_codecvt.cxx
+++ b/Source/cm_codecvt.cxx
@@ -31,6 +31,7 @@ codecvt::codecvt(Encoding e)
// We don't know which ANSI encoding to use for other platforms than
// Windows so we don't do any conversion there
case codecvt::UTF8:
+ case codecvt::UTF8_WITH_BOM:
// Assume internal encoding is UTF-8
case codecvt::None:
// No encoding
diff --git a/Source/cm_codecvt.hxx b/Source/cm_codecvt.hxx
index 1860211..b73204f 100644
--- a/Source/cm_codecvt.hxx
+++ b/Source/cm_codecvt.hxx
@@ -14,6 +14,7 @@ public:
{
None,
UTF8,
+ UTF8_WITH_BOM,
ANSI
};