From 4cc9083d00a69d3b2854c82d621f509e3a1e297c Mon Sep 17 00:00:00 2001 From: crueter Date: Mon, 8 Sep 2025 21:51:00 -0400 Subject: [PATCH] [cmake, ci] "force" clang to use relwithdebinfo; add compiler build id Signed-off-by: crueter --- .ci/windows/build.sh | 67 +++++++++++---------------- CMakeLists.txt | 20 +++++--- CMakeModules/GenerateSCMRev.cmake | 2 + src/CMakeLists.txt | 20 +++++--- src/common/CMakeLists.txt | 2 +- src/common/scm_rev.cpp.in | 76 +++++++------------------------ src/common/scm_rev.h | 10 ++-- src/dynarmic/CMakeLists.txt | 6 +-- src/video_core/CMakeLists.txt | 2 +- src/yuzu/about_dialog.cpp | 9 ++-- src/yuzu/main.cpp | 9 ++-- 11 files changed, 94 insertions(+), 129 deletions(-) diff --git a/.ci/windows/build.sh b/.ci/windows/build.sh index 681f327793..a0ab69a440 100644 --- a/.ci/windows/build.sh +++ b/.ci/windows/build.sh @@ -1,59 +1,45 @@ -#!/bin/bash -e +#!/bin/bash -ex -# SPDX-FileCopyrightText: 2025 eden Emulator Project +# SPDX-FileCopyrightText: 2025 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later -if [ "$DEVEL" != "true" ]; then - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_QT_UPDATE_CHECKER=ON) +if [ "$COMPILER" == "clang" ] +then + EXTRA_CMAKE_FLAGS+=( + -DCMAKE_CXX_COMPILER=clang-cl + -DCMAKE_C_COMPILER=clang-cl + -DCMAKE_CXX_FLAGS="-O3" + -DCMAKE_C_FLAGS="-O3" + ) + + BUILD_TYPE="RelWithDebInfo" fi -if [ "$CCACHE" = "true" ]; then - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DUSE_CCACHE=ON) -fi +[ -z "$WINDEPLOYQT" ] && { echo "WINDEPLOYQT environment variable required."; exit 1; } -if [ "$BUNDLE_QT" = "true" ]; then - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DYUZU_USE_BUNDLED_QT=ON) -else - export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DYUZU_USE_BUNDLED_QT=OFF) -fi - -if [ -z "$BUILD_TYPE" ]; then - export BUILD_TYPE="Release" -fi - -if [ "$WINDEPLOYQT" == "" ]; then - echo "You must supply the WINDEPLOYQT environment variable." - exit 1 -fi - -if [ "$USE_WEBENGINE" = "true" ]; then - WEBENGINE=ON -else - WEBENGINE=OFF -fi - -if [ "$USE_MULTIMEDIA" = "false" ]; then - MULTIMEDIA=OFF -else - MULTIMEDIA=ON -fi - -export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@) +echo $EXTRA_CMAKE_FLAGS mkdir -p build && cd build cmake .. -G Ninja \ - -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ - -DENABLE_QT_TRANSLATION=ON \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE:-Release}" \ + -DENABLE_QT_TRANSLATION=ON \ -DUSE_DISCORD_PRESENCE=ON \ -DYUZU_USE_BUNDLED_SDL2=ON \ + -DBUILD_TESTING=OFF \ -DYUZU_TESTS=OFF \ + -DDYNARMIC_TESTS=OFF \ -DYUZU_CMD=OFF \ -DYUZU_ROOM_STANDALONE=OFF \ - -DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \ - -DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \ + -DYUZU_USE_QT_MULTIMEDIA=${USE_MULTIMEDIA:-false} \ + -DYUZU_USE_QT_WEB_ENGINE=${USE_WEBENGINE:-false} \ -DYUZU_ENABLE_LTO=ON \ + -DCMAKE_EXE_LINKER_FLAGS=" /LTCG" \ -DDYNARMIC_ENABLE_LTO=ON \ - "${EXTRA_CMAKE_FLAGS[@]}" + -DYUZU_USE_BUNDLED_QT=${BUNDLE_QT:-false} \ + -DUSE_CCACHE=${CCACHE:-false} \ + -DENABLE_QT_UPDATE_CHECKER=${DEVEL:-true} \ + "${EXTRA_CMAKE_FLAGS[@]}" \ + "$@" ninja @@ -62,4 +48,5 @@ rm -f bin/*.pdb set -e $WINDEPLOYQT --release --no-compiler-runtime --no-opengl-sw --no-system-dxc-compiler --no-system-d3d-compiler --dir pkg bin/eden.exe + cp bin/* pkg diff --git a/CMakeLists.txt b/CMakeLists.txt index f8b8ce3586..2c38127dcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,17 @@ endif() if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(CXX_CLANG ON) + if (MSVC) + set(CXX_CLANG_CL ON) + endif() +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + set(CXX_GCC ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CXX_CL ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") + set(CXX_ICC ON) +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(CXX_APPLE ON) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") @@ -81,7 +92,7 @@ if (MSVC AND ARCHITECTURE_x86) instead, run vcvars64.bat directly, located at C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat") endif() -if (MSVC AND CXX_CLANG) +if (CXX_CLANG_CL) add_compile_options( # clang-cl prints literally 10000+ warnings without this $<$:-Wno-unused-command-line-argument> @@ -92,6 +103,7 @@ if (MSVC AND CXX_CLANG) $<$:-Wno-reserved-identifier> $<$:-Wno-deprecated-declarations> $<$:-Wno-cast-function-type-mismatch> + $<$:/EHsc> # thanks microsoft ) if (ARCHITECTURE_x86_64) @@ -101,10 +113,6 @@ if (MSVC AND CXX_CLANG) $<$:-mcx16> ) endif() - - if(CMAKE_ASM_MASM_COMPILER) - set(CMAKE_ASM_MASM_FLAGS "/nologo" CACHE STRING "Flags for MASM assembler" FORCE) - endif() endif() set(CPM_SOURCE_CACHE ${CMAKE_SOURCE_DIR}/.cache/cpm) @@ -114,7 +122,7 @@ include(CMakeDependentOption) include(CTest) # Disable Warnings as Errors for MSVC -if (MSVC AND NOT CXX_CLANG) +if (CXX_CL) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX-") endif() diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake index 3b8e996751..bcb5dc466a 100644 --- a/CMakeModules/GenerateSCMRev.cmake +++ b/CMakeModules/GenerateSCMRev.cmake @@ -35,4 +35,6 @@ set(REPO_NAME "Eden") set(BUILD_ID ${GIT_BRANCH}) set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ") +set(CXX_COMPILER "${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") + configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dae4095022..ac685830cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,8 +14,10 @@ if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)) endif() # CMake seems to only define _DEBUG on Windows -set_property(DIRECTORY APPEND PROPERTY - COMPILE_DEFINITIONS $<$:_DEBUG> $<$>:NDEBUG>) +if (NOT (MSVC AND CXX_CLANG)) + set_property(DIRECTORY APPEND PROPERTY + COMPILE_DEFINITIONS $<$:_DEBUG> $<$>:NDEBUG>) +endif() # Set compilation flags if (MSVC AND NOT CXX_CLANG) @@ -122,9 +124,13 @@ if (MSVC AND NOT CXX_CLANG) set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE) set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE) else() - add_compile_options( - -fwrapv + if (NOT MSVC) + add_compile_options( + -fwrapv + ) + endif() + add_compile_options( -Werror=all -Werror=extra -Werror=missing-declarations @@ -137,7 +143,7 @@ else() -Wno-missing-field-initializers ) - if (CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID MATCHES IntelLLVM) # Clang or AppleClang but NOT clang-cl + if (CXX_CLANG OR CXX_ICC) # Clang or AppleClang if (NOT MSVC) add_compile_options( -Werror=shadow-uncaptured-local @@ -157,12 +163,12 @@ else() add_compile_options("-mcx16") endif() - if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang) + if (APPLE AND CXX_CLANG) add_compile_options("-stdlib=libc++") endif() # GCC bugs - if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11" AND CXX_GCC) # These diagnostics would be great if they worked, but are just completely broken # and produce bogus errors on external libraries like fmt. add_compile_options( diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 986cb35664..665143900a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -237,7 +237,7 @@ else() ) # Get around GCC failing with intrinsics in Debug - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_BUILD_TYPE MATCHES "Debug") + if(CXX_GCC AND CMAKE_BUILD_TYPE MATCHES "Debug") set_property( SOURCE stb.cpp APPEND diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index b6bff72867..a157d03878 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -1,12 +1,11 @@ +// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/scm_rev.h" -#include -#include -#include - #define GIT_REV "@GIT_REV@" #define GIT_BRANCH "@GIT_BRANCH@" #define GIT_DESC "@GIT_DESC@" @@ -18,64 +17,21 @@ #define TITLE_BAR_FORMAT_IDLE "@TITLE_BAR_FORMAT_IDLE@" #define TITLE_BAR_FORMAT_RUNNING "@TITLE_BAR_FORMAT_RUNNING@" #define IS_DEV_BUILD @IS_DEV_BUILD@ +#define COMPILER_ID "@CXX_COMPILER@" namespace Common { -const char* g_scm_rev; -const char* g_scm_branch; -const char* g_scm_desc; -const char g_build_name[] = BUILD_NAME; -const char g_build_date[] = BUILD_DATE; -const char g_build_fullname[] = BUILD_FULLNAME; -const char g_build_version[] = BUILD_VERSION; -const char g_build_id[] = BUILD_ID; -const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE; -const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; -const bool g_is_dev_build = IS_DEV_BUILD; +constexpr const char g_scm_rev[] = GIT_REV; +constexpr const char g_scm_branch[] = GIT_BRANCH; +constexpr const char g_scm_desc[] = GIT_DESC; +constexpr const char g_build_name[] = BUILD_NAME; +constexpr const char g_build_date[] = BUILD_DATE; +constexpr const char g_build_fullname[] = BUILD_FULLNAME; +constexpr const char g_build_version[] = BUILD_VERSION; +constexpr const char g_build_id[] = BUILD_ID; +constexpr const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE; +constexpr const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; +constexpr const bool g_is_dev_build = IS_DEV_BUILD; +constexpr const char g_compiler_id[] = COMPILER_ID; -/// Anonymizes SCM data -/// This is quite weak. But better than nothing. -class scm_encrypt { - std::string m_scm_rev, m_scm_branch, m_scm_desc; - -public: - scm_encrypt() { - // Get a key that is easy to obtain when asking the person directly but (usually) hard to - // guess - std::string key; -#ifdef __linux__ - if (!std::getline(std::ifstream("/proc/sys/kernel/hostname"), key)) - key = "linux_error_key"; -#else - // Not a good fallback, but better than nothing I guess? - key = g_build_date; -#endif - // Copy strings in place - m_scm_rev = GIT_REV; - m_scm_branch = GIT_BRANCH; - m_scm_desc = GIT_DESC; - // XOR each string with key - auto key_it = key.begin(); - for (auto& string : {&m_scm_rev, &m_scm_branch, &m_scm_desc}) { - for (auto& c : *string) { - c ^= *key_it; - if (++key_it == key.end()) - key_it = key.begin(); - } - } - // Make each string human-readable - for (auto& string : {&m_scm_rev, &m_scm_branch, &m_scm_desc}) { - const std::string original = *string; - string->clear(); - for (const auto c : original) { - string->append(fmt::format("{:x}", unsigned(c))); - } - string->pop_back(); - } - // Set pointers - g_scm_rev = m_scm_rev.c_str(); - g_scm_branch = m_scm_branch.c_str(); - g_scm_desc = m_scm_desc.c_str(); - } -} scm_encrypt_instance; } // namespace Common diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index ee1997950a..84356ad64a 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,9 +8,9 @@ namespace Common { -extern const char* g_scm_rev; -extern const char* g_scm_branch; -extern const char* g_scm_desc; +extern const char g_scm_rev[]; +extern const char g_scm_branch[]; +extern const char g_scm_desc[]; extern const char g_build_name[]; extern const char g_build_date[]; extern const char g_build_fullname[]; @@ -17,5 +20,6 @@ extern const char g_title_bar_format_idle[]; extern const char g_title_bar_format_running[]; extern const char g_shader_cache_version[]; extern const bool g_is_dev_build; +extern const char g_compiler_id[]; } // namespace Common diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt index 0065b1cf7f..38457deb50 100644 --- a/src/dynarmic/CMakeLists.txt +++ b/src/dynarmic/CMakeLists.txt @@ -103,7 +103,7 @@ if (MSVC) /WX) endif() - if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + if (CXX_CLANG) list(APPEND DYNARMIC_CXX_FLAGS -Qunused-arguments -Wno-missing-braces) @@ -131,7 +131,7 @@ else() -Wfatal-errors) endif() - if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") + if (CXX_GCC) # GCC produces bogus -Warray-bounds warnings from xbyak headers for code paths that are not # actually reachable. Specifically, it happens in cases where some code casts an Operand& # to Address& after first checking isMEM(), and that code is inlined in a situation where @@ -141,7 +141,7 @@ else() list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096) endif() - if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang") + if (CXX_CLANG) # Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6. # And this in turns limits the size of a std::array. list(APPEND DYNARMIC_CXX_FLAGS -fbracket-depth=1024) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index e0f7f82fbe..3c2473266a 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -373,7 +373,7 @@ else() set_source_files_properties(vulkan_common/vma.cpp PROPERTIES COMPILE_OPTIONS "-Wno-conversion;-Wno-unused-variable;-Wno-unused-parameter;-Wno-missing-field-initializers") # Get around GCC failing with intrinsics in Debug - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_BUILD_TYPE MATCHES "Debug") + if (CXX_GCC AND CMAKE_BUILD_TYPE MATCHES "Debug") set_source_files_properties(host1x/vic.cpp PROPERTIES COMPILE_OPTIONS "-O2") endif() endif() diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp index 5b6e32149d..c8edb90268 100644 --- a/src/yuzu/about_dialog.cpp +++ b/src/yuzu/about_dialog.cpp @@ -11,14 +11,15 @@ AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent) , ui{std::make_unique()} { - const auto description = std::string(Common::g_build_version); - const auto build_id = std::string(Common::g_build_id); + static const std::string description = std::string(Common::g_build_version); + static const std::string build_id = std::string(Common::g_build_id); + static const std::string compiler = std::string(Common::g_compiler_id); std::string yuzu_build; if (Common::g_is_dev_build) { - yuzu_build = fmt::format("Eden Nightly | {}-{}", description, build_id); + yuzu_build = fmt::format("Eden Nightly | {}-{} | {}", description, build_id, compiler); } else { - yuzu_build = fmt::format("Eden | {}", description); + yuzu_build = fmt::format("Eden | {} | {}", description, compiler); } const auto override_build = fmt::format(fmt::runtime( diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 979bc5df97..c6e004813c 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -5022,14 +5022,15 @@ void GMainWindow::OnEmulatorUpdateAvailable() { void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version, std::string_view gpu_vendor) { - const auto description = std::string(Common::g_build_version); - const auto build_id = std::string(Common::g_build_id); + static const std::string description = std::string(Common::g_build_version); + static const std::string build_id = std::string(Common::g_build_id); + static const std::string compiler = std::string(Common::g_compiler_id); std::string yuzu_title; if (Common::g_is_dev_build) { - yuzu_title = fmt::format("Eden Nightly | {}-{}", description, build_id); + yuzu_title = fmt::format("Eden Nightly | {}-{} | {}", description, build_id, compiler); } else { - yuzu_title = fmt::format("Eden | {}", description); + yuzu_title = fmt::format("Eden | {} | {}", description, compiler); } const auto override_title =