From fc480dcb6943602cc83d1e9ccab95773b90b5623 Mon Sep 17 00:00:00 2001 From: "Boss.sfc" Date: Tue, 22 Jul 2025 21:37:37 +0700 Subject: [PATCH] fix: CachyOS LTO Compilation Fix LTO linking issues on CachyOS with GCC 15.x - Add LTO support to all core library targets (input_common, frontend_common, network, shader_recompiler, web_service) that were missing LTO configuration - Create citron_configure_lto() helper function for consistent LTO handling - Implement CachyOS-specific detection via /etc/os-release and kernel version - Apply conservative LTO flags (-flto=auto -ffat-lto-objects) only for CachyOS + GCC 15+ to resolve linking errors with newer toolchains - Other distributions continue using aggressive LTO settings for maximum performance - Disable LTO on executable targets to prevent main function optimization issues This resolves "undefined symbol" errors when building with -DCITRON_ENABLE_LTO=ON on CachyOS while maintaining optimal LTO performance on other distributions. Fixes linking errors including: - Core::Frontend::EmuWindow symbols - Core::System methods - Settings::values - Common logging functions Tested on CachyOS with GCC 15.1.1 + LLD 20.1.8 Signed-off-by: Boss.sfc --- CMakeLists.txt | 31 ++++++++++++++++++++++++++++ src/audio_core/CMakeLists.txt | 2 ++ src/common/CMakeLists.txt | 2 ++ src/core/CMakeLists.txt | 4 +--- src/frontend_common/CMakeLists.txt | 2 ++ src/hid_core/CMakeLists.txt | 2 ++ src/input_common/CMakeLists.txt | 2 ++ src/network/CMakeLists.txt | 2 ++ src/shader_recompiler/CMakeLists.txt | 2 ++ src/video_core/CMakeLists.txt | 4 +--- src/web_service/CMakeLists.txt | 2 ++ 11 files changed, 49 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae9e9f3b8..cf3a12b78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -686,6 +686,37 @@ function(create_target_directory_groups target_name) endforeach() endfunction() +# Helper function to configure LTO for a target with CachyOS-specific compatibility +function(citron_configure_lto target_name) + if (CITRON_ENABLE_LTO) + set_property(TARGET ${target_name} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) + + # Detect CachyOS and apply conservative LTO settings only for CachyOS + set(IS_CACHYOS FALSE) + if (EXISTS "/etc/os-release") + file(READ "/etc/os-release" OS_RELEASE_CONTENT) + if (OS_RELEASE_CONTENT MATCHES "ID=cachyos") + set(IS_CACHYOS TRUE) + endif() + endif() + + # Alternative detection via kernel name + if (NOT IS_CACHYOS) + execute_process(COMMAND uname -r OUTPUT_VARIABLE KERNEL_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + if (KERNEL_VERSION MATCHES "cachyos") + set(IS_CACHYOS TRUE) + endif() + endif() + + # Apply conservative LTO settings only for CachyOS with GCC 15+ + if (IS_CACHYOS AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0") + message(STATUS "Detected CachyOS with GCC ${CMAKE_CXX_COMPILER_VERSION} - using conservative LTO settings for ${target_name}") + target_compile_options(${target_name} PRIVATE "-flto=auto" "-ffat-lto-objects") + target_link_options(${target_name} PRIVATE "-flto=auto" "-ffat-lto-objects") + endif() + endif() +endfunction() + # Prevent boost from linking against libs when building target_link_libraries(Boost::headers INTERFACE Boost::disable_autolinking) # Adjustments for MSVC + Ninja diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index b247d7f26..8eafdd45b 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -232,6 +232,8 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) target_link_libraries(audio_core PRIVATE dynarmic::dynarmic) endif() +citron_configure_lto(audio_core) + if (ENABLE_CUBEB) target_sources(audio_core PRIVATE sink/cubeb_sink.cpp diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 823db6d64..4498658e9 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -266,4 +266,6 @@ if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(common PRIVATE precompiled_headers.h) endif() +citron_configure_lto(common) + create_target_directory_groups(common) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 12bd84a3f..889835c61 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1294,8 +1294,6 @@ if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(core PRIVATE precompiled_headers.h) endif() -if (CITRON_ENABLE_LTO) - set_property(TARGET core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) -endif() +citron_configure_lto(core) create_target_directory_groups(core) diff --git a/src/frontend_common/CMakeLists.txt b/src/frontend_common/CMakeLists.txt index 94d8cc4c3..ecf879b21 100644 --- a/src/frontend_common/CMakeLists.txt +++ b/src/frontend_common/CMakeLists.txt @@ -9,3 +9,5 @@ add_library(frontend_common STATIC create_target_directory_groups(frontend_common) target_link_libraries(frontend_common PUBLIC core SimpleIni::SimpleIni PRIVATE common Boost::headers) + +citron_configure_lto(frontend_common) diff --git a/src/hid_core/CMakeLists.txt b/src/hid_core/CMakeLists.txt index 7dbb7acd8..6c10531a3 100644 --- a/src/hid_core/CMakeLists.txt +++ b/src/hid_core/CMakeLists.txt @@ -164,3 +164,5 @@ target_link_libraries(hid_core PUBLIC core) if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(hid_core PRIVATE precompiled_headers.h) endif() + +citron_configure_lto(hid_core) diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index c097e6476..10f34a80d 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -93,6 +93,8 @@ if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(input_common PRIVATE precompiled_headers.h) endif() +citron_configure_lto(input_common) + if (ANDROID) target_sources(input_common PRIVATE drivers/android.cpp diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 8ac323c82..cab83aa72 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -28,3 +28,5 @@ endif() if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(network PRIVATE precompiled_headers.h) endif() + +citron_configure_lto(network) diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 35828b5a6..da8859843 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -266,3 +266,5 @@ create_target_directory_groups(shader_recompiler) if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(shader_recompiler PRIVATE precompiled_headers.h) endif() + +citron_configure_lto(shader_recompiler) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 49a24f5ad..28b773688 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -388,9 +388,7 @@ if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(video_core PRIVATE precompiled_headers.h) endif() -if (CITRON_ENABLE_LTO) - set_property(TARGET video_core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) -endif() +citron_configure_lto(video_core) if (ANDROID AND ARCHITECTURE_arm64) target_link_libraries(video_core PRIVATE adrenotools) diff --git a/src/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index 473b4ff2a..a96089cb5 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt @@ -22,3 +22,5 @@ target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann if (CITRON_USE_PRECOMPILED_HEADERS) target_precompile_headers(web_service PRIVATE precompiled_headers.h) endif() + +citron_configure_lto(web_service)