summaryrefslogtreecommitdiffstats
path: root/Source/cmTimestamp.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTimestamp.cxx')
-rw-r--r--Source/cmTimestamp.cxx29
1 files changed, 29 insertions, 0 deletions
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 056696d..3826577 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -18,6 +18,10 @@
#include <cstring>
#include <sstream>
+#ifdef __MINGW32__
+# include <libloaderapi.h>
+#endif
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -159,6 +163,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
case 'M':
case 'S':
case 'U':
+ case 'V':
case 'w':
case 'y':
case 'Y':
@@ -189,6 +194,30 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
char buffer[16];
+#ifdef __MINGW32__
+ /* See a bug in MinGW: https://sourceforge.net/p/mingw-w64/bugs/793/. A work
+ * around is to try to use strftime() from ucrtbase.dll. */
+ using T = size_t(__cdecl*)(char*, size_t, const char*, const struct tm*);
+ auto loadUcrtStrftime = []() -> T {
+ auto handle =
+ LoadLibraryExA("ucrtbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (handle) {
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wcast-function-type"
+ return reinterpret_cast<T>(GetProcAddress(handle, "strftime"));
+# pragma GCC diagnostic pop
+ }
+ return nullptr;
+ };
+ static T ucrtStrftime = loadUcrtStrftime();
+
+ if (ucrtStrftime) {
+ size_t size =
+ ucrtStrftime(buffer, sizeof(buffer), formatString.c_str(), &timeStruct);
+ return std::string(buffer, size);
+ }
+#endif
+
size_t size =
strftime(buffer, sizeof(buffer), formatString.c_str(), &timeStruct);