public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Kefu Chai <tchaikov@gmail.com>
To: git-commits@fedoraproject.org
Subject: [rpms/dolphin-emu] rawhide: Fix FTBFS with fmt 12 (fmt::localtime removed)
Date: Mon, 29 Jun 2026 16:47:34 GMT	[thread overview]
Message-ID: <178275165496.1.364076164651409593.rpms-dolphin-emu-22655ec7ab34@fedoraproject.org> (raw)

            A new commit has been pushed.

            Repo   : rpms/dolphin-emu
            Branch : rawhide
            Commit : 22655ec7ab34a2412812b2a1d27368cc055f8711
            Author : Kefu Chai <tchaikov@gmail.com>
            Date   : 2026-06-29T23:07:30+08:00
            Stats  : +228/-0 in 2 file(s)
            URL    : https://src.fedoraproject.org/rpms/dolphin-emu/c/22655ec7ab34a2412812b2a1d27368cc055f8711?branch=rawhide

            Log:
            Fix FTBFS with fmt 12 (fmt::localtime removed)

fmt 12 removed fmt::localtime(). Backport upstream commit 4b65cc9a4c,
which switches the five call sites to the thread-safe Common::LocalTime()
helper. It is already in master, so drop this patch on the next snapshot
bump. Builds cleanly against fmt 12.1.0.

---
diff --git a/dolphin-emu-fmt12-localtime.patch b/dolphin-emu-fmt12-localtime.patch
new file mode 100644
index 0000000..8d74550
--- /dev/null
+++ b/dolphin-emu-fmt12-localtime.patch
@@ -0,0 +1,225 @@
+# fmt 12 removed fmt::localtime(). Backport the upstream fix, which routes all
+# uses through the thread-safe Common::LocalTime() helper (and simplifies the
+# serial-number generator in SettingsHandler).
+#
+# Upstream commit 4b65cc9a4c51af4308f748b3e7bf25d80db83860
+#   "fmt: Replace deprecated `fmt::localtime` usage with `Common::LocalTime`"
+#   by Joshua Vandaele, already in dolphin-emu master.
+
+diff --git a/Source/Core/AudioCommon/AudioCommon.cpp b/Source/Core/AudioCommon/AudioCommon.cpp
+--- a/Source/Core/AudioCommon/AudioCommon.cpp
++++ b/Source/Core/AudioCommon/AudioCommon.cpp
+@@ -17,6 +17,7 @@
+ #include "Common/Common.h"
+ #include "Common/FileUtil.h"
+ #include "Common/Logging/Log.h"
++#include "Common/TimeUtil.h"
+ #include "Core/Config/MainSettings.h"
+ #include "Core/ConfigManager.h"
+ #include "Core/System.h"
+@@ -219,8 +220,11 @@
+ 
+   std::string path_prefix = File::GetUserPath(D_DUMPAUDIO_IDX) + SConfig::GetInstance().GetGameID();
+ 
+-  std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(start_time));
++  const auto local_time = Common::LocalTime(start_time);
++  if (!local_time)
++    return;
++
++  std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
+ 
+   const std::string audio_file_name_dtk = fmt::format("{}_dtkdump.wav", base_name);
+   const std::string audio_file_name_dsp = fmt::format("{}_dspdump.wav", base_name);
+diff --git a/Source/Core/Common/FatFsUtil.cpp b/Source/Core/Common/FatFsUtil.cpp
+--- a/Source/Core/Common/FatFsUtil.cpp
++++ b/Source/Core/Common/FatFsUtil.cpp
+@@ -25,6 +25,7 @@
+ #include "Common/Logging/Log.h"
+ #include "Common/ScopeGuard.h"
+ #include "Common/StringUtil.h"
++#include "Common/TimeUtil.h"
+ 
+ #include "Core/Config/MainSettings.h"
+ 
+@@ -95,12 +96,7 @@
+ u32 GetSystemTimeFAT()
+ {
+   const std::time_t time = std::time(nullptr);
+-  std::tm tm;
+-#ifdef _WIN32
+-  localtime_s(&tm, &time);
+-#else
+-  localtime_r(&time, &tm);
+-#endif
++  std::tm tm = *Common::LocalTime(time);
+ 
+   DWORD fattime = 0;
+   fattime |= (tm.tm_year - 80) << 25;
+diff --git a/Source/Core/Common/SettingsHandler.cpp b/Source/Core/Common/SettingsHandler.cpp
+--- a/Source/Core/Common/SettingsHandler.cpp
++++ b/Source/Core/Common/SettingsHandler.cpp
+@@ -122,7 +122,6 @@
+ 
+   // Must be 9 characters at most; otherwise the serial number will be rejected by SDK libraries,
+   // as there is a check to ensure the string length is strictly lower than 10.
+-  // 3 for %j, 2 for %H, 2 for %M, 2 for %S.
+-  return fmt::format("{:%j%H%M%S}", fmt::localtime(t));
++  return fmt::format("{:09}", t % 1000000000);
+ }
+ }  // namespace Common
+diff --git a/Source/Core/Common/TimeUtil.cpp b/Source/Core/Common/TimeUtil.cpp
+--- a/Source/Core/Common/TimeUtil.cpp
++++ b/Source/Core/Common/TimeUtil.cpp
+@@ -2,23 +2,25 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ 
+ #include "Common/TimeUtil.h"
++#include "Common/Logging/Log.h"
+ 
+ #include <ctime>
+ #include <optional>
+ 
+ namespace Common
+ {
+-std::optional<std::tm> Localtime(std::time_t time)
++std::optional<std::tm> LocalTime(std::time_t time)
+ {
+   std::tm local_time;
+ #ifdef _MSC_VER
+   if (localtime_s(&local_time, &time) != 0)
+-    return std::nullopt;
+ #else
+-  std::tm* result = localtime_r(&time, &local_time);
+-  if (result != &local_time)
+-    return std::nullopt;
++  if (localtime_r(&time, &local_time) == NULL)
+ #endif
++  {
++    ERROR_LOG_FMT(COMMON, "Failed to convert time to local time: {}", std::strerror(errno));
++    return std::nullopt;
++  }
+   return local_time;
+ }
+ }  // Namespace Common
+diff --git a/Source/Core/Common/TimeUtil.h b/Source/Core/Common/TimeUtil.h
+--- a/Source/Core/Common/TimeUtil.h
++++ b/Source/Core/Common/TimeUtil.h
+@@ -9,5 +9,5 @@
+ namespace Common
+ {
+ // Threadsafe and error-checking variant of std::localtime()
+-std::optional<std::tm> Localtime(std::time_t time);
++std::optional<std::tm> LocalTime(std::time_t time);
+ }  // Namespace Common
+diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
+--- a/Source/Core/Core/Core.cpp
++++ b/Source/Core/Core/Core.cpp
+@@ -8,6 +8,7 @@
+ #include <cstring>
+ #include <functional>
+ #include <mutex>
++#include <optional>
+ #include <queue>
+ #include <utility>
+ #include <variant>
+@@ -36,6 +37,7 @@
+ #include "Common/ScopeGuard.h"
+ #include "Common/StringUtil.h"
+ #include "Common/Thread.h"
++#include "Common/TimeUtil.h"
+ #include "Common/Timer.h"
+ #include "Common/Version.h"
+ 
+@@ -760,15 +762,17 @@
+   return path;
+ }
+ 
+-static std::string GenerateScreenshotName()
++static std::optional<std::string> GenerateScreenshotName()
+ {
+   // append gameId, path only contains the folder here.
+   const std::string path_prefix =
+       GenerateScreenshotFolderPath() + SConfig::GetInstance().GetGameID();
+ 
+   const std::time_t cur_time = std::time(nullptr);
+-  const std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, fmt::localtime(cur_time));
++  const auto local_time = Common::LocalTime(cur_time);
++  if (!local_time)
++    return std::nullopt;
++  const std::string base_name = fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}", path_prefix, *local_time);
+ 
+   // First try a filename without any suffixes, if already exists then append increasing numbers
+   std::string name = fmt::format("{}.png", base_name);
+@@ -784,7 +788,9 @@
+ void SaveScreenShot()
+ {
+   const Core::CPUThreadGuard guard(Core::System::GetInstance());
+-  g_frame_dumper->SaveScreenshot(GenerateScreenshotName());
++  std::optional<std::string> name = GenerateScreenshotName();
++  if (name)
++    g_frame_dumper->SaveScreenshot(*name);
+ }
+ 
+ void SaveScreenShot(std::string_view name)
+diff --git a/Source/Core/Core/NetworkCaptureLogger.cpp b/Source/Core/Core/NetworkCaptureLogger.cpp
+--- a/Source/Core/Core/NetworkCaptureLogger.cpp
++++ b/Source/Core/Core/NetworkCaptureLogger.cpp
+@@ -16,6 +16,7 @@
+ #include "Common/Network.h"
+ #include "Common/PcapFile.h"
+ #include "Common/ScopeGuard.h"
++#include "Common/TimeUtil.h"
+ #include "Core/Config/MainSettings.h"
+ #include "Core/ConfigManager.h"
+ 
+@@ -82,7 +83,7 @@
+ {
+   const std::string filepath =
+       fmt::format("{}{} {:%Y-%m-%d %Hh%Mm%Ss}.pcap", File::GetUserPath(D_DUMPSSL_IDX),
+-                  SConfig::GetInstance().GetGameID(), fmt::localtime(std::time(nullptr)));
++                  SConfig::GetInstance().GetGameID(), *Common::LocalTime(std::time(nullptr)));
+   m_file = std::make_unique<Common::PCAP>(
+       new File::IOFile(filepath, "wb", File::SharedAccess::Read), Common::PCAP::LinkType::Ethernet);
+ }
+diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
+--- a/Source/Core/Core/State.cpp
++++ b/Source/Core/Core/State.cpp
+@@ -284,7 +284,7 @@
+ {
+   // revert adjustments from GetSystemTimeAsDouble() to get a normal Unix timestamp again
+   const time_t seconds = static_cast<time_t>(time) + DOUBLE_TIME_OFFSET;
+-  const auto local_time = Common::Localtime(seconds);
++  const auto local_time = Common::LocalTime(seconds);
+   if (!local_time)
+     return "";
+ 
+diff --git a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
+--- a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
++++ b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp
+@@ -2,6 +2,7 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ 
+ #include "VideoCommon/FrameDumpFFMpeg.h"
++#include "Common/TimeUtil.h"
+ 
+ #if defined(__FreeBSD__)
+ #define __STDC_CONSTANT_MACROS 1
+@@ -125,11 +126,15 @@
+   if (!g_Config.sDumpPath.empty())
+     return g_Config.sDumpPath;
+ 
++  const auto local_time = Common::LocalTime(time);
++  if (!local_time)
++    return "";
++
+   const std::string path_prefix =
+       File::GetUserPath(D_DUMPFRAMES_IDX) + SConfig::GetInstance().GetGameID();
+ 
+   const std::string base_name =
+-      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, fmt::localtime(time), index);
++      fmt::format("{}_{:%Y-%m-%d_%H-%M-%S}_{}", path_prefix, *local_time, index);
+ 
+   const std::string path = fmt::format("{}.{}", base_name, extension);
+ 

diff --git a/dolphin-emu.spec b/dolphin-emu.spec
index 03778e4..71b2ef3 100644
--- a/dolphin-emu.spec
+++ b/dolphin-emu.spec
@@ -62,6 +62,9 @@ Patch4:         0005-mbedtls-CVE-2026-34871-fix.patch
 
 Patch10:        dolphin-emu-fix-build-against-qt-6-10.patch
 
+# fmt 12 removed fmt::localtime(); backport of upstream commit 4b65cc9a4c
+Patch11:        dolphin-emu-fmt12-localtime.patch
+
 ###Bundled code ahoy, I've added my best guess for versions and upstream urls
 ##The following isn't in Fedora yet:
 #https://github.com/weisslj/cpp-optparse

                 reply	other threads:[~2026-06-29 16:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178275165496.1.364076164651409593.rpms-dolphin-emu-22655ec7ab34@fedoraproject.org \
    --to=tchaikov@gmail.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox