From ecbe2f421d82a729d463f2916cab9fd153e1ba1f Mon Sep 17 00:00:00 2001
From: Andrew Udvare <audvare@gmail.com>
Date: Sun, 8 Feb 2026 18:23:10 -0500
Subject: [PATCH 05/23] Add USE_SYSTEM_FMT option for system libfmt

- third_party/CMakeLists.txt: link system fmt (pkg-config) when USE_SYSTEM_FMT
  is set, else build the bundled copy.
- src/xenia/base/fmt_include.h: new wrapper selecting <fmt/...> headers when
  XENIA_USE_SYSTEM_FMT is defined.
- Replace direct third_party/fmt includes throughout src with the wrapper.

Co-authored-by: Cursor <cursoragent@cursor.com>
---
 src/xenia/app/console_settings_dialog.cc      |  2 +-
 src/xenia/base/cvar.h                         |  2 +-
 src/xenia/base/debugging.h                    |  2 +-
 src/xenia/base/fmt_include.h                  | 17 +++++++++++++++++
 src/xenia/base/logging.cc                     |  2 +-
 src/xenia/base/logging.h                      |  3 +--
 src/xenia/base/mapped_memory_win.cc           |  2 +-
 src/xenia/base/profiling.cc                   |  2 +-
 src/xenia/base/string_buffer.h                |  2 +-
 src/xenia/base/string_util.h                  |  2 +-
 src/xenia/base/testing/memory_test.cc         |  2 +-
 src/xenia/base/vec128.cc                      |  2 +-
 src/xenia/config.cc                           |  2 +-
 src/xenia/cpu/backend/code_cache_base.h       |  2 +-
 src/xenia/cpu/backend/x64/x64_code_cache.cc   |  2 +-
 src/xenia/cpu/backend/x64/x64_emitter.cc      |  2 +-
 .../cpu/compiler/passes/finalization_pass.cc  |  2 +-
 src/xenia/cpu/hir/hir_builder.h               |  2 +-
 src/xenia/cpu/ppc/ppc_hir_builder.cc          |  2 +-
 src/xenia/cpu/xex_module.cc                   |  2 +-
 src/xenia/emulator.cc                         |  2 +-
 src/xenia/gpu/command_processor.cc            |  2 +-
 .../gpu/d3d12/d3d12_render_target_cache.cc    |  2 +-
 src/xenia/gpu/d3d12/pipeline_cache.cc         |  4 ++--
 src/xenia/gpu/dxbc_shader_translator_fetch.cc |  2 +-
 src/xenia/gpu/render_target_cache.h           |  2 +-
 src/xenia/gpu/shader.cc                       |  2 +-
 src/xenia/gpu/shader_storage.h                |  2 +-
 src/xenia/gpu/spirv_shader_translator.cc      |  2 +-
 .../gpu/spirv_shader_translator_fetch.cc      |  2 +-
 src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc |  2 +-
 src/xenia/hid/hid_demo.cc                     |  2 +-
 .../kernel/util/presence_string_builder.cc    |  2 +-
 src/xenia/kernel/xam/content_manager.cc       |  2 +-
 src/xenia/kernel/xam/profile_manager.h        |  2 +-
 src/xenia/kernel/xam/user_profile.cc          |  2 +-
 src/xenia/kernel/xam/user_settings.cc         |  2 +-
 src/xenia/kernel/xam/user_tracker.cc          |  2 +-
 src/xenia/kernel/xam/xam_enum.cc              |  2 +-
 src/xenia/kernel/xam/xam_info.cc              |  3 +--
 src/xenia/kernel/xam/xam_locale.cc            |  3 +--
 src/xenia/kernel/xam/xam_task.cc              |  2 +-
 src/xenia/kernel/xconfig.h                    |  2 +-
 src/xenia/memory.cc                           |  2 +-
 third_party/CMakeLists.txt                    | 19 ++++++++++++++-----
 45 files changed, 75 insertions(+), 52 deletions(-)
 create mode 100644 src/xenia/base/fmt_include.h

diff --git a/src/xenia/app/console_settings_dialog.cc b/src/xenia/app/console_settings_dialog.cc
index 03c9b5b01..6d752af2a 100644
--- a/src/xenia/app/console_settings_dialog.cc
+++ b/src/xenia/app/console_settings_dialog.cc
@@ -16,7 +16,7 @@
 
 #include "xenia/app/console_settings_dialog.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 namespace app {
diff --git a/src/xenia/base/cvar.h b/src/xenia/base/cvar.h
index 4d8f803ae..7b53c47fe 100644
--- a/src/xenia/base/cvar.h
+++ b/src/xenia/base/cvar.h
@@ -16,7 +16,7 @@
 #include <vector>
 
 #include "third_party/cxxopts/include/cxxopts.hpp"
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/tomlplusplus/include/toml++/toml.hpp"
 #include "xenia/base/assert.h"
 #include "xenia/base/filesystem.h"
diff --git a/src/xenia/base/debugging.h b/src/xenia/base/debugging.h
index 1933bdd58..df88f3982 100644
--- a/src/xenia/base/debugging.h
+++ b/src/xenia/base/debugging.h
@@ -12,7 +12,7 @@
 
 #include <cstdint>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 namespace debugging {
diff --git a/src/xenia/base/fmt_include.h b/src/xenia/base/fmt_include.h
new file mode 100644
index 000000000..20bd0d375
--- /dev/null
+++ b/src/xenia/base/fmt_include.h
@@ -0,0 +1,17 @@
+// Wrapper so Xenia can use either bundled fmt or system libfmt (XENIA_USE_SYSTEM_FMT).
+#ifndef XENIA_BASE_FMT_INCLUDE_H_
+#define XENIA_BASE_FMT_INCLUDE_H_
+
+#ifdef XENIA_USE_SYSTEM_FMT
+#include <fmt/format.h>
+#include <fmt/printf.h>
+#include <fmt/xchar.h>
+#include <fmt/std.h>
+#else
+#include "third_party/fmt/include/fmt/format.h"
+#include "third_party/fmt/include/fmt/printf.h"
+#include "third_party/fmt/include/fmt/xchar.h"
+#include "third_party/fmt/include/fmt/std.h"
+#endif
+
+#endif  // XENIA_BASE_FMT_INCLUDE_H_
diff --git a/src/xenia/base/logging.cc b/src/xenia/base/logging.cc
index e40b29319..405ff012d 100644
--- a/src/xenia/base/logging.cc
+++ b/src/xenia/base/logging.cc
@@ -40,7 +40,7 @@
 #include "xenia/base/platform_win.h"
 #endif  // XE_PLATFORM
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 #if XE_PLATFORM_ANDROID
 DEFINE_bool(log_to_logcat, true, "Write log output to Android Logcat.",
diff --git a/src/xenia/base/logging.h b/src/xenia/base/logging.h
index 0541413f2..afb35e33c 100644
--- a/src/xenia/base/logging.h
+++ b/src/xenia/base/logging.h
@@ -14,8 +14,7 @@
 #include <cstdint>
 #include <string>
 
-#include "third_party/fmt/include/fmt/format.h"
-#include "third_party/fmt/include/fmt/std.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/string.h"
 
 namespace xe {
diff --git a/src/xenia/base/mapped_memory_win.cc b/src/xenia/base/mapped_memory_win.cc
index 9c1e52bdb..09f3d7aed 100644
--- a/src/xenia/base/mapped_memory_win.cc
+++ b/src/xenia/base/mapped_memory_win.cc
@@ -9,7 +9,7 @@
 
 #include <mutex>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/logging.h"
 #include "xenia/base/mapped_memory.h"
 #include "xenia/base/math.h"
diff --git a/src/xenia/base/profiling.cc b/src/xenia/base/profiling.cc
index d97ba81cc..7b3e6b5e5 100644
--- a/src/xenia/base/profiling.cc
+++ b/src/xenia/base/profiling.cc
@@ -11,7 +11,7 @@
 // XELOGI.
 #include "xenia/base/logging.h"
 
-#include "third_party/fmt/include/fmt/printf.h"
+#include "xenia/base/fmt_include.h"
 
 // NOTE: microprofile must be setup first, before profiling.h is included.
 #define MICROPROFILE_ENABLED 1
diff --git a/src/xenia/base/string_buffer.h b/src/xenia/base/string_buffer.h
index 9a4743deb..6d3f5e613 100644
--- a/src/xenia/base/string_buffer.h
+++ b/src/xenia/base/string_buffer.h
@@ -14,7 +14,7 @@
 #include <string>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 
diff --git a/src/xenia/base/string_util.h b/src/xenia/base/string_util.h
index 77fc1a9f3..76504c70e 100644
--- a/src/xenia/base/string_util.h
+++ b/src/xenia/base/string_util.h
@@ -18,7 +18,7 @@
 #include <string>
 #include <variant>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/memory.h"
 #include "xenia/base/platform.h"
diff --git a/src/xenia/base/testing/memory_test.cc b/src/xenia/base/testing/memory_test.cc
index 11125ad8f..8127fef3a 100644
--- a/src/xenia/base/testing/memory_test.cc
+++ b/src/xenia/base/testing/memory_test.cc
@@ -10,7 +10,7 @@
 #include "xenia/base/memory.h"
 
 #include "third_party/catch/include/catch.hpp"
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 #include "xenia/base/clock.h"
 
diff --git a/src/xenia/base/vec128.cc b/src/xenia/base/vec128.cc
index 79f7820cc..d2339fe63 100644
--- a/src/xenia/base/vec128.cc
+++ b/src/xenia/base/vec128.cc
@@ -10,7 +10,7 @@
 #include <ostream>
 #include <string>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/math.h"
 #include "xenia/base/platform.h"
 #include "xenia/base/string_util.h"
diff --git a/src/xenia/config.cc b/src/xenia/config.cc
index ecb53a9c1..95f7113ea 100644
--- a/src/xenia/config.cc
+++ b/src/xenia/config.cc
@@ -9,7 +9,7 @@
 
 #include "config.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/cvar.h"
 #include "xenia/base/filesystem.h"
diff --git a/src/xenia/cpu/backend/code_cache_base.h b/src/xenia/cpu/backend/code_cache_base.h
index 9477cc7a8..86bf886d5 100644
--- a/src/xenia/cpu/backend/code_cache_base.h
+++ b/src/xenia/cpu/backend/code_cache_base.h
@@ -20,7 +20,7 @@
 #include <utility>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/clock.h"
 #include "xenia/base/literals.h"
diff --git a/src/xenia/cpu/backend/x64/x64_code_cache.cc b/src/xenia/cpu/backend/x64/x64_code_cache.cc
index 24defe124..4275bcad7 100644
--- a/src/xenia/cpu/backend/x64/x64_code_cache.cc
+++ b/src/xenia/cpu/backend/x64/x64_code_cache.cc
@@ -17,7 +17,7 @@
 #endif
 
 #if ENABLE_VTUNE
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/cpu/module.h"
 #endif
 
diff --git a/src/xenia/cpu/backend/x64/x64_emitter.cc b/src/xenia/cpu/backend/x64/x64_emitter.cc
index ec49d3433..1ab2cbb67 100644
--- a/src/xenia/cpu/backend/x64/x64_emitter.cc
+++ b/src/xenia/cpu/backend/x64/x64_emitter.cc
@@ -14,7 +14,7 @@
 #include <climits>
 #include <cstring>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/atomic.h"
 #include "xenia/base/debugging.h"
diff --git a/src/xenia/cpu/compiler/passes/finalization_pass.cc b/src/xenia/cpu/compiler/passes/finalization_pass.cc
index 1afd9d6bb..1afbe14e7 100644
--- a/src/xenia/cpu/compiler/passes/finalization_pass.cc
+++ b/src/xenia/cpu/compiler/passes/finalization_pass.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/cpu/compiler/passes/finalization_pass.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/profiling.h"
 #include "xenia/cpu/backend/backend.h"
 #include "xenia/cpu/compiler/compiler.h"
diff --git a/src/xenia/cpu/hir/hir_builder.h b/src/xenia/cpu/hir/hir_builder.h
index e8a80415a..23b2390b7 100644
--- a/src/xenia/cpu/hir/hir_builder.h
+++ b/src/xenia/cpu/hir/hir_builder.h
@@ -12,7 +12,7 @@
 
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/arena.h"
 #include "xenia/base/string_buffer.h"
 
diff --git a/src/xenia/cpu/ppc/ppc_hir_builder.cc b/src/xenia/cpu/ppc/ppc_hir_builder.cc
index 42d996cba..5952dd0ff 100644
--- a/src/xenia/cpu/ppc/ppc_hir_builder.cc
+++ b/src/xenia/cpu/ppc/ppc_hir_builder.cc
@@ -12,7 +12,7 @@
 #include <stddef.h>
 #include <cstring>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 #include "xenia/base/byte_order.h"
 #include "xenia/base/cvar.h"
diff --git a/src/xenia/cpu/xex_module.cc b/src/xenia/cpu/xex_module.cc
index 7cbc60ac5..82b93c412 100644
--- a/src/xenia/cpu/xex_module.cc
+++ b/src/xenia/cpu/xex_module.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/cpu/xex_module.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 #include "xenia/base/byte_order.h"
 #include "xenia/base/cvar.h"
diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc
index 22cd25220..3d81d63eb 100644
--- a/src/xenia/emulator.cc
+++ b/src/xenia/emulator.cc
@@ -12,7 +12,7 @@
 #include "xenia/emulator.h"
 
 #include "config.h"
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/tabulate/single_include/tabulate/tabulate.hpp"
 #include "third_party/zarchive/include/zarchive/zarchivecommon.h"
 #include "third_party/zarchive/include/zarchive/zarchivewriter.h"
diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc
index 940a9a48a..88f339fa3 100644
--- a/src/xenia/gpu/command_processor.cc
+++ b/src/xenia/gpu/command_processor.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/gpu/command_processor.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/byte_stream.h"
 #include "xenia/base/clock.h"
 #include "xenia/base/cvar.h"
diff --git a/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc b/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc
index 3cc4c4bbe..861bd0289 100644
--- a/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc
+++ b/src/xenia/gpu/d3d12/d3d12_render_target_cache.cc
@@ -13,7 +13,7 @@
 #include <cstring>
 
 #include "third_party/dxbc/DXBCChecksum.h"
-#include "third_party/fmt/include/fmt/xchar.h"
+#include "xenia/base/fmt_include.h"
 
 #include "xenia/base/assert.h"
 #include "xenia/base/cvar.h"
diff --git a/src/xenia/gpu/d3d12/pipeline_cache.cc b/src/xenia/gpu/d3d12/pipeline_cache.cc
index 6122979d1..edd536ef4 100644
--- a/src/xenia/gpu/d3d12/pipeline_cache.cc
+++ b/src/xenia/gpu/d3d12/pipeline_cache.cc
@@ -14,7 +14,7 @@
 #include <thread>
 
 #include "third_party/dxbc/DXBCChecksum.h"
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/byte_order.h"
 #include "xenia/base/clock.h"
@@ -37,7 +37,7 @@
 #include "xenia/gpu/xenos.h"
 #include "xenia/ui/d3d12/d3d12_util.h"
 
-#include "third_party/fmt/include/fmt/xchar.h"
+#include "xenia/base/fmt_include.h"
 
 DEFINE_bool(d3d12_dxbc_disasm, false,
             "Disassemble DXBC shaders after generation.", "D3D12");
diff --git a/src/xenia/gpu/dxbc_shader_translator_fetch.cc b/src/xenia/gpu/dxbc_shader_translator_fetch.cc
index 493b22a14..9af500bf8 100644
--- a/src/xenia/gpu/dxbc_shader_translator_fetch.cc
+++ b/src/xenia/gpu/dxbc_shader_translator_fetch.cc
@@ -9,7 +9,7 @@
 
 #include <cmath>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/math.h"
 #include "xenia/base/string.h"
diff --git a/src/xenia/gpu/render_target_cache.h b/src/xenia/gpu/render_target_cache.h
index c619541c8..4f02b227c 100644
--- a/src/xenia/gpu/render_target_cache.h
+++ b/src/xenia/gpu/render_target_cache.h
@@ -18,7 +18,7 @@
 #include <utility>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/cvar.h"
 #include "xenia/gpu/draw_extent_estimator.h"
diff --git a/src/xenia/gpu/shader.cc b/src/xenia/gpu/shader.cc
index b34a8a83b..7e3a52d26 100644
--- a/src/xenia/gpu/shader.cc
+++ b/src/xenia/gpu/shader.cc
@@ -11,7 +11,7 @@
 
 #include <cstring>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/filesystem.h"
 #include "xenia/base/math.h"
 #include "xenia/base/memory.h"
diff --git a/src/xenia/gpu/shader_storage.h b/src/xenia/gpu/shader_storage.h
index 70c2c91d6..a1d949392 100644
--- a/src/xenia/gpu/shader_storage.h
+++ b/src/xenia/gpu/shader_storage.h
@@ -21,7 +21,7 @@
 #include <set>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/byte_order.h"
 #include "xenia/base/filesystem.h"
diff --git a/src/xenia/gpu/spirv_shader_translator.cc b/src/xenia/gpu/spirv_shader_translator.cc
index 1171e365a..c24423a46 100644
--- a/src/xenia/gpu/spirv_shader_translator.cc
+++ b/src/xenia/gpu/spirv_shader_translator.cc
@@ -12,7 +12,7 @@
 #include <cstddef>
 #include <cstdint>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/glslang/SPIRV/GLSL.std.450.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/logging.h"
diff --git a/src/xenia/gpu/spirv_shader_translator_fetch.cc b/src/xenia/gpu/spirv_shader_translator_fetch.cc
index e0f519275..b0bb95615 100644
--- a/src/xenia/gpu/spirv_shader_translator_fetch.cc
+++ b/src/xenia/gpu/spirv_shader_translator_fetch.cc
@@ -12,7 +12,7 @@
 #include <climits>
 #include <cmath>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/glslang/SPIRV/GLSL.std.450.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/math.h"
diff --git a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc
index 003ef86b2..63252a007 100644
--- a/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc
+++ b/src/xenia/gpu/vulkan/vulkan_pipeline_cache.cc
@@ -13,7 +13,7 @@
 #include <cstring>
 #include <set>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/byte_order.h"
 #include "xenia/base/filesystem.h"
diff --git a/src/xenia/hid/hid_demo.cc b/src/xenia/hid/hid_demo.cc
index 37692149f..d22170cb1 100644
--- a/src/xenia/hid/hid_demo.cc
+++ b/src/xenia/hid/hid_demo.cc
@@ -16,7 +16,7 @@
 #include <unordered_map>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/imgui/imgui.h"
 #include "xenia/base/clock.h"
 #include "xenia/base/cvar.h"
diff --git a/src/xenia/kernel/util/presence_string_builder.cc b/src/xenia/kernel/util/presence_string_builder.cc
index 91b0cf982..30975fb28 100644
--- a/src/xenia/kernel/util/presence_string_builder.cc
+++ b/src/xenia/kernel/util/presence_string_builder.cc
@@ -8,7 +8,7 @@
  */
 
 #include "xenia/kernel/util/presence_string_builder.h"
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 #include "xenia/base/string.h"
 
diff --git a/src/xenia/kernel/xam/content_manager.cc b/src/xenia/kernel/xam/content_manager.cc
index e91608fc0..8eceef4c2 100644
--- a/src/xenia/kernel/xam/content_manager.cc
+++ b/src/xenia/kernel/xam/content_manager.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/kernel/xam/content_manager.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/filesystem.h"
 #include "xenia/base/logging.h"
 #include "xenia/base/string.h"
diff --git a/src/xenia/kernel/xam/profile_manager.h b/src/xenia/kernel/xam/profile_manager.h
index ad9bf5321..f5fe2e872 100644
--- a/src/xenia/kernel/xam/profile_manager.h
+++ b/src/xenia/kernel/xam/profile_manager.h
@@ -15,7 +15,7 @@
 #include <string>
 #include <vector>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/string.h"
 #include "xenia/kernel/title_id_utils.h"
 #include "xenia/kernel/xam/user_profile.h"
diff --git a/src/xenia/kernel/xam/user_profile.cc b/src/xenia/kernel/xam/user_profile.cc
index 1ca5d3d84..75ed6b0f6 100644
--- a/src/xenia/kernel/xam/user_profile.cc
+++ b/src/xenia/kernel/xam/user_profile.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/kernel/xam/user_profile.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/kernel/kernel_state.h"
 #include "xenia/kernel/util/shim_utils.h"
 #include "xenia/kernel/xam/xdbf/gpd_info.h"
diff --git a/src/xenia/kernel/xam/user_settings.cc b/src/xenia/kernel/xam/user_settings.cc
index 074162b5a..d05a4c45f 100644
--- a/src/xenia/kernel/xam/user_settings.cc
+++ b/src/xenia/kernel/xam/user_settings.cc
@@ -9,7 +9,7 @@
 
 #include "xenia/kernel/xam/user_settings.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/kernel/kernel_state.h"
 #include "xenia/kernel/util/shim_utils.h"
 
diff --git a/src/xenia/kernel/xam/user_tracker.cc b/src/xenia/kernel/xam/user_tracker.cc
index d6dc2686e..98cb801c9 100644
--- a/src/xenia/kernel/xam/user_tracker.cc
+++ b/src/xenia/kernel/xam/user_tracker.cc
@@ -10,7 +10,7 @@
 #include "xenia/emulator.h"
 #include "xenia/kernel/xam/user_profile.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "third_party/stb/stb_image.h"
 #include "xenia/kernel/kernel_state.h"
 #include "xenia/kernel/util/shim_utils.h"
diff --git a/src/xenia/kernel/xam/xam_enum.cc b/src/xenia/kernel/xam/xam_enum.cc
index 1a5afb370..6c3260560 100644
--- a/src/xenia/kernel/xam/xam_enum.cc
+++ b/src/xenia/kernel/xam/xam_enum.cc
@@ -16,7 +16,7 @@
 #include "xenia/kernel/xenumerator.h"
 #include "xenia/xbox.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 namespace kernel {
diff --git a/src/xenia/kernel/xam/xam_info.cc b/src/xenia/kernel/xam/xam_info.cc
index 0f57f7334..dfc8b92dc 100644
--- a/src/xenia/kernel/xam/xam_info.cc
+++ b/src/xenia/kernel/xam/xam_info.cc
@@ -31,8 +31,7 @@
 #include "xenia/ui/windowed_app_context.h"
 #include "xenia/xbox.h"
 
-#include "third_party/fmt/include/fmt/format.h"
-#include "third_party/fmt/include/fmt/xchar.h"
+#include "xenia/base/fmt_include.h"
 
 DEFINE_int32(avpack, 8,
              "Video modes\n"
diff --git a/src/xenia/kernel/xam/xam_locale.cc b/src/xenia/kernel/xam/xam_locale.cc
index 37445f0f7..775327787 100644
--- a/src/xenia/kernel/xam/xam_locale.cc
+++ b/src/xenia/kernel/xam/xam_locale.cc
@@ -18,8 +18,7 @@
 #include "xenia/kernel/xthread.h"
 #include "xenia/xbox.h"
 
-#include "third_party/fmt/include/fmt/format.h"
-#include "third_party/fmt/include/fmt/xchar.h"
+#include "xenia/base/fmt_include.h"
 
 // TODO(gibbed): put these forward decls in a header somewhere.
 
diff --git a/src/xenia/kernel/xam/xam_task.cc b/src/xenia/kernel/xam/xam_task.cc
index 7844b6437..b85b25aa5 100644
--- a/src/xenia/kernel/xam/xam_task.cc
+++ b/src/xenia/kernel/xam/xam_task.cc
@@ -17,7 +17,7 @@
 #include "xenia/kernel/xthread.h"
 #include "xenia/xbox.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 namespace kernel {
diff --git a/src/xenia/kernel/xconfig.h b/src/xenia/kernel/xconfig.h
index 82b35e070..94459530b 100644
--- a/src/xenia/kernel/xconfig.h
+++ b/src/xenia/kernel/xconfig.h
@@ -18,7 +18,7 @@
 #include "xenia/base/byte_order.h"
 #include "xenia/base/mutex.h"
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 
 namespace xe {
 namespace kernel {
diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc
index 1b64b754d..3d0ac3188 100644
--- a/src/xenia/memory.cc
+++ b/src/xenia/memory.cc
@@ -12,7 +12,7 @@
 #include <cstring>
 #include <random>
 
-#include "third_party/fmt/include/fmt/format.h"
+#include "xenia/base/fmt_include.h"
 #include "xenia/base/assert.h"
 #include "xenia/base/byte_stream.h"
 #include "xenia/base/clock.h"
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 34810c86e..c6b5acb4b 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -137,11 +137,20 @@ endif()
 # ==============================================================================
 # fmt
 # ==============================================================================
-add_library(fmt STATIC
-  fmt/src/format.cc
-  fmt/src/os.cc
-)
-target_include_directories(fmt PUBLIC fmt/include)
+if(USE_SYSTEM_FMT)
+  find_package(PkgConfig REQUIRED)
+  pkg_check_modules(FMT REQUIRED fmt)
+  add_library(fmt INTERFACE)
+  target_include_directories(fmt SYSTEM INTERFACE ${FMT_INCLUDE_DIRS})
+  target_link_libraries(fmt INTERFACE ${FMT_LDFLAGS})
+  target_compile_options(fmt INTERFACE ${FMT_CFLAGS_OTHER})
+else()
+  add_library(fmt STATIC
+    fmt/src/format.cc
+    fmt/src/os.cc
+  )
+  target_include_directories(fmt PUBLIC fmt/include)
+endif()
 
 # ==============================================================================
 # glslang-spirv (not needed on macOS — no Vulkan/SPIR-V backend)
-- 
2.54.0

