mirror of
https://git.citron-emu.org/citron/emulator
synced 2026-01-03 08:43:47 +00:00
Merge branch 'clang_compiler_fix' into 'main'
fix: Resolve compilation failures and warnings with Clang See merge request citron/emulator!83
This commit is contained in:
@@ -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)
|
||||
@@ -749,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()
|
||||
|
||||
112
patches/mcl_clang_template_fix.patch
Normal file
112
patches/mcl_clang_template_fix.patch
Normal file
@@ -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<template<class...> class F, class L>
|
||||
+ struct map_impl;
|
||||
+
|
||||
+ template<template<class...> class F, template<class...> class LT, class... Es>
|
||||
+ struct map_impl<F, LT<Es...>> {
|
||||
+ using type = LT<F<Es>...>;
|
||||
+ };
|
||||
|
||||
-template<template<class...> class F, class L>
|
||||
-struct map_impl;
|
||||
|
||||
-template<template<class...> class F, template<class...> class LT, class... Es>
|
||||
-struct map_impl<F, LT<Es...>> {
|
||||
- using type = LT<F<Es>...>;
|
||||
-};
|
||||
+ #if defined(__clang__) && !defined(_MSC_VER)
|
||||
+ template <template<class...> class F, class... Es>
|
||||
+ struct map_impl<F, mcl::mp::list<Es...>> {
|
||||
+ using type = mcl::mp::list<F<Es>...>;
|
||||
+ };
|
||||
+ #endif
|
||||
|
||||
-} // namespace detail
|
||||
+ } // namespace detail
|
||||
|
||||
-/// Applies each element of list L to metafunction F
|
||||
-template<template<class...> class F, class L>
|
||||
-using map = typename detail::map_impl<F, L>::type;
|
||||
+ /// Applies each element of list L to metafunction F
|
||||
+ template<template<class...> class F, class L>
|
||||
+ using map = typename detail::map_impl<F, L>::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 <type_traits>
|
||||
+#include <utility>
|
||||
|
||||
#include "mcl/mp/typelist/list.hpp"
|
||||
|
||||
namespace mcl::mp {
|
||||
|
||||
-namespace detail {
|
||||
+ namespace detail {
|
||||
|
||||
-template<class VL>
|
||||
-struct lift_sequence_impl;
|
||||
+ template <class VL>
|
||||
+ struct lift_sequence_impl; // Forward declaration
|
||||
|
||||
-template<class T, template<class, T...> class VLT, T... values>
|
||||
-struct lift_sequence_impl<VLT<T, values...>> {
|
||||
- using type = list<std::integral_constant<T, values>...>;
|
||||
-};
|
||||
+ // Original specialization (works for GCC/MSVC)
|
||||
+ template <class T, template <class, T...> class VLT, T... values>
|
||||
+ struct lift_sequence_impl<VLT<T, values...>> {
|
||||
+ using type = list<std::integral_constant<T, values>...>;
|
||||
+ };
|
||||
|
||||
-} // 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 <class T, T... Ints>
|
||||
+ struct lift_sequence_impl<std::integer_sequence<T, Ints...>> {
|
||||
+ using type = list<std::integral_constant<T, Ints>...>;
|
||||
+ };
|
||||
+ #endif
|
||||
|
||||
-/// Lifts values in value list VL to create a type list.
|
||||
-template<class VL>
|
||||
-using lift_sequence = typename detail::lift_sequence_impl<VL>::type;
|
||||
+ } // namespace detail
|
||||
+
|
||||
+ /// Lifts values in value list VL to create a type list.
|
||||
+ template <class VL>
|
||||
+ using lift_sequence = typename detail::lift_sequence_impl<VL>::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<typename FPT, bool needs_rounding_correction, bool needs_nan_correction>
|
||||
static void EmitFPVectorMulAddFallback(VectorArray<FPT>& result, const VectorArray<FPT>& addend, const VectorArray<FPT>& op1, const VectorArray<FPT>& 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<FPT>::exponent_mask | FP::FPInfo<FPT>::mantissa_mask;
|
||||
@@ -21,7 +21,7 @@ namespace Core {
|
||||
class System;
|
||||
}
|
||||
namespace VkDeviceInfo {
|
||||
struct Record;
|
||||
class Record;
|
||||
}
|
||||
namespace Ui {
|
||||
class ConfigureDialog;
|
||||
|
||||
@@ -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 <algorithm>
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 <ctime>
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user