Am 08.07.2025 um 12:01 schrieb Jonathan Wakely:
On Mon, 7 Jul 2025 at 23:53, Björn Schäpers <g...@hazardy.de> wrote:
From: Björn Schäpers <bjo...@hazardy.de>
Windows does not provide a tzdata.zi, but msys does. Use this, if
available, instead of the embedded (and possibly outdated) database.
libstdc++-v3/Changelog:
Use msys provided time zone information.
* src/c++20/tzdb.cc (zoneinfo_file): On Windows look relative
from the DLL path for the time zone information.
Signed-off-by: Björn Schäpers <bjo...@hazardy.de>
---
libstdc++-v3/src/c++20/tzdb.cc | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index 6e244dc656d..9923d14b7a7 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -44,6 +44,12 @@
# include <cstdlib> // getenv
#endif
+#if _GLIBCXX_HAVE_WINDOWS_H
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include <psapi.h>
+#endif
+
#if defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2
# define USE_ATOMIC_LIST_HEAD 1
// TODO benchmark atomic<shared_ptr<>> vs mutex.
@@ -1144,6 +1150,34 @@ namespace std::chrono
#ifdef _GLIBCXX_ZONEINFO_DIR
else
path = _GLIBCXX_ZONEINFO_DIR;
+#endif
+#ifdef _GLIBCXX_HAVE_WINDOWS_H
+ if (path.empty())
+ {
+ HMODULE dll_module;
+ if (GetModuleHandleExA(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+ | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
+ reinterpret_cast<const char *>(&zoneinfo_file), &dll_module))
Does this assume that libstdc++.dll is installed as part of the msys
installation?
What if users build GCC themselves and install it elsewhere?
Is the correct solution for msys-based systems to build GCC with
--with-libstdcxx-zoneinfo=/path/to/msys/tzdata.zi ?
Yes the assumption is, that libstdc++-6.dll is installed in
$msysPath/$msysSubsystem/bin and the time zones are in ../share/zoneinfo.
If supplied with --with-libstdcxx-zoneinfo=/path/to/msys/tzdata.zi path
shouldn't be empty, but containing "/path/to/msys/tzdata.zi" and nothing changes
with my patch.
The problem for msys packages is, that $msysPath is unknown, since the user can
install msys anywhere. I tried using a long string constant and changing that in
the DLL after installation, so it would remain a constant. But the string
constant size is used to build the std::string and "/tzdata.zi" is appended to
that. So I switched to use a runtime approach.
+ {
+ char dll_path[MAX_PATH];
+ if (GetModuleFileNameA(dll_module, dll_path, MAX_PATH) != 0)
+ {
+ string_view dll_path_view = dll_path;
+ auto pos = dll_path_view.find_last_of('\\');
+ dll_path_view = dll_path_view.substr(0, pos);
+ if (dll_path_view.ends_with("\\bin"))
+ {
+ constexpr string_view remaining_path = "share\\zoneinfo";
+ dll_path_view.remove_suffix(3); // Remove bin
+ path.reserve(dll_path_view.size()
+ + remaining_path.size());
+ path = dll_path_view;
+ path += remaining_path;
+ }
+ }
+ }
+ }
#endif
if (!path.empty())
path.append(filename);
--
2.50.0