From 696f9f6c5e19c43bea297866ae7ec1d128a2c577 Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 02:20:48 +0000 Subject: [PATCH 1/6] add: Clang Patch --- CMakeLists.txt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 947a1615b..a6c61bc08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -414,6 +414,28 @@ if(USE_DISCORD_PRESENCE) endif() endif() +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(STATUS "Applying custom patch to submodule's mcl for Clang compatibility...") + + set(MCL_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/patches/mcl_clang_template_fix.patch") + set(MCL_PATCH_TARGET_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/dynarmic/externals/mcl") + + if(EXISTS "${MCL_PATCH_TARGET_DIR}") + execute_process( + COMMAND git apply --ignore-whitespace "${MCL_PATCH_FILE}" + WORKING_DIRECTORY "${MCL_PATCH_TARGET_DIR}" + RESULT_VARIABLE MCL_PATCH_RESULT + OUTPUT_QUIET + ERROR_QUIET + ) + + if(NOT MCL_PATCH_RESULT EQUAL 0) + message(WARNING "Failed to apply mcl Clang compatibility patch! This might be okay if it's already applied.") + endif() + else() + message(WARNING "Could not find mcl directory to patch. It may not have been downloaded yet.") + endif() +endif() if (ENABLE_QT) if (NOT USE_SYSTEM_QT) @@ -681,7 +703,7 @@ if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja") ) endif() -if (CITRON_USE_FASTER_LD AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") +if (CITRON_USE_FASTER_LD AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")) # We will assume that if the compiler is GCC, it will attempt to use ld.bfd by default. # Try to pick a faster linker. find_program(LLD lld) From fbc4077585cf46acb917ac68e68ac75af9c93ad9 Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 02:21:45 +0000 Subject: [PATCH 2/6] Clang Compiler Patch --- patches/mcl_clang_template_fix.patch | 112 +++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 patches/mcl_clang_template_fix.patch diff --git a/patches/mcl_clang_template_fix.patch b/patches/mcl_clang_template_fix.patch new file mode 100644 index 000000000..352a6c55b --- /dev/null +++ b/patches/mcl_clang_template_fix.patch @@ -0,0 +1,112 @@ +diff --git a/externals/mcl/include/mcl/mp/metafunction/map.hpp b/externals/mcl/include/mcl/mp/metafunction/map.hpp +index 13fcaecd..6bbe1a23 100644 +--- a/externals/mcl/include/mcl/mp/metafunction/map.hpp ++++ b/externals/mcl/include/mcl/mp/metafunction/map.hpp +@@ -4,22 +4,32 @@ + + #pragma once + ++#include "mcl/mp/typelist/list.hpp" ++ + namespace mcl::mp { + +-namespace detail { ++ namespace detail { ++ ++ template class F, class L> ++ struct map_impl; ++ ++ template class F, template class LT, class... Es> ++ struct map_impl> { ++ using type = LT...>; ++ }; + +-template class F, class L> +-struct map_impl; + +-template class F, template class LT, class... Es> +-struct map_impl> { +- using type = LT...>; +-}; ++ #if defined(__clang__) && !defined(_MSC_VER) ++ template class F, class... Es> ++ struct map_impl> { ++ using type = mcl::mp::list...>; ++ }; ++ #endif + +-} // namespace detail ++ } // namespace detail + +-/// Applies each element of list L to metafunction F +-template class F, class L> +-using map = typename detail::map_impl::type; ++ /// Applies each element of list L to metafunction F ++ template class F, class L> ++ using map = typename detail::map_impl::type; + + } // namespace mcl::mp +diff --git a/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp b/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp +index ba2617b8..10f7d6c5 100644 +--- a/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp ++++ b/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp +@@ -5,25 +5,36 @@ + #pragma once + + #include ++#include + + #include "mcl/mp/typelist/list.hpp" + + namespace mcl::mp { + +-namespace detail { ++ namespace detail { + +-template +-struct lift_sequence_impl; ++ template ++ struct lift_sequence_impl; // Forward declaration + +-template class VLT, T... values> +-struct lift_sequence_impl> { +- using type = list...>; +-}; ++ // Original specialization (works for GCC/MSVC) ++ template class VLT, T... values> ++ struct lift_sequence_impl> { ++ using type = list...>; ++ }; + +-} // namespace detail ++ // Clang-specific fix: Add a more explicit specialization that Clang can match. ++ // We check for __clang__ but not _MSC_VER, as clang-cl on Windows might not need this. ++ #if defined(__clang__) && !defined(_MSC_VER) ++ template ++ struct lift_sequence_impl> { ++ using type = list...>; ++ }; ++ #endif + +-/// Lifts values in value list VL to create a type list. +-template +-using lift_sequence = typename detail::lift_sequence_impl::type; ++ } // namespace detail ++ ++ /// Lifts values in value list VL to create a type list. ++ template ++ using lift_sequence = typename detail::lift_sequence_impl::type; + + } // namespace mcl::mp +diff --git a/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp b/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp +index b8aa3eb6..b6eda4e4 100644 +--- a/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp ++++ b/src/dynarmic/backend/x64/emit_x64_vector_floating_point.cpp +@@ -1285,6 +1285,7 @@ void EmitX64::EmitFPVectorMul64(EmitContext& ctx, IR::Inst* inst) { + + template + static void EmitFPVectorMulAddFallback(VectorArray& result, const VectorArray& addend, const VectorArray& op1, const VectorArray& op2, FP::FPCR fpcr, [[maybe_unused]] FP::FPSR& fpsr) { ++ #pragma clang loop vectorize(enable) + for (size_t i = 0; i < result.size(); i++) { + if constexpr (needs_rounding_correction) { + constexpr FPT non_sign_mask = FP::FPInfo::exponent_mask | FP::FPInfo::mantissa_mask; From 5a87a11917c9c57fea8668ad9d87847a992ad100 Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 02:25:14 +0000 Subject: [PATCH 3/6] fix: Clang Compiler --- src/core/perf_stats.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 957be9614..5a4412675 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2017 Citra Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -41,7 +42,9 @@ PerfStats::~PerfStats() { const auto path = Common::FS::GetCitronPath(Common::FS::CitronPath::LogDir); // %F Date format expanded is "%Y-%m-%d" - const auto filename = fmt::format("{:%F-%H-%M}_{:016X}.csv", *std::localtime(&t), title_id); + char time_buf[128]; + std::strftime(time_buf, sizeof(time_buf), "%F-%H-%M", std::localtime(&t)); + const auto filename = fmt::format("{}_{:016X}.csv", time_buf, title_id); const auto filepath = path / filename; if (Common::FS::CreateParentDir(filepath)) { From 6491a53e72c9f2f4f9301664d8228a35a3ad889b Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 02:25:57 +0000 Subject: [PATCH 4/6] fix: Clang Compiler --- src/core/reporter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 424bb63c7..929ddeec0 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include @@ -33,7 +34,9 @@ std::filesystem::path GetPath(std::string_view type, u64 title_id, std::string_v std::string GetTimestamp() { const auto time = std::time(nullptr); - return fmt::format("{:%FT%H-%M-%S}", *std::localtime(&time)); + char time_buf[128]; + std::strftime(time_buf, sizeof(time_buf), "%FT%H-%M-%S", std::localtime(&time)); + return std::string(time_buf); } using namespace nlohmann; From ef008771e1b6041a739d51cd0aca1ff6c089dcdb Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 02:33:26 +0000 Subject: [PATCH 5/6] fix: Clang Compiler --- src/citron/configuration/configure_dialog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/citron/configuration/configure_dialog.h b/src/citron/configuration/configure_dialog.h index a7e678acf..9ad6ea1f1 100644 --- a/src/citron/configuration/configure_dialog.h +++ b/src/citron/configuration/configure_dialog.h @@ -21,7 +21,7 @@ namespace Core { class System; } namespace VkDeviceInfo { - struct Record; + class Record; } namespace Ui { class ConfigureDialog; From 58894d95079ca2a1187271d684066159fbf1fc28 Mon Sep 17 00:00:00 2001 From: collecting Date: Sun, 5 Oct 2025 03:45:20 +0000 Subject: [PATCH 6/6] fix: Clang + LTO Failure --- CMakeLists.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6c61bc08..efc43b8cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -771,3 +771,19 @@ if(ENABLE_QT AND UNIX AND NOT APPLE) install(FILES "dist/org.citron_emu.citron.metainfo.xml" DESTINATION "share/metainfo") endif() + +# Final linker cleanup for Clang LTO. +# This forcefully removes any stray "-fuse-ld=bfd" flags that may have been +# incorrectly added by other parts of the build system. +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CITRON_ENABLE_LTO) + message(STATUS "Performing final linker flag cleanup for Clang LTO...") + foreach(target citron citron-cmd citron-room) + if(TARGET ${target}) + get_target_property(link_options ${target} LINK_OPTIONS) + if(link_options) + string(REPLACE "-fuse-ld=bfd" "" link_options "${link_options}") + set_target_properties(${target} PROPERTIES LINK_OPTIONS "${link_options}") + endif() + endif() + endforeach() +endif()