On Tue, 8 Jul 2025 at 11:31, Björn Schäpers <g...@hazardy.de> wrote: > > 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.
Makes sense. So the configure option might work, but if it doesn't, the runtime approach might work (if libstdc++-6.dll and tzdata.zi have the expected relative layout), and if not, we use the static copy of tzdata.zi in the library. Thanks, this still seems like a net improvement, even if it's not 100% guaranteed to work. > > > > >> + { > >> + 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 > >> > > >