mirror of
https://github.com/citron-neo/emulator.git
synced 2026-07-05 15:21:57 -07:00
deploy qt and its dependencies with cpm/cmake
This commit is contained in:
+24
-56
@@ -89,11 +89,21 @@ CMAKE_DEPENDENT_OPTION(CITRON_ROOM "Compile LDN room server" ON "NOT ANDROID" OF
|
||||
|
||||
CMAKE_DEPENDENT_OPTION(CITRON_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF)
|
||||
|
||||
# CITRON_USE_CPM is the primary way to fetch dependencies on Linux and for Clangtron.
|
||||
# vcpkg is supported primarily for native MSVC and Android builds.
|
||||
option(CITRON_USE_BUNDLED_VCPKG "Use vcpkg for citron dependencies" "${MSVC}")
|
||||
option(CITRON_USE_CPM "Use CPM.cmake to fetch dependencies" OFF)
|
||||
|
||||
option(CITRON_CHECK_SUBMODULES "Check if submodules are present" ON)
|
||||
# Auto-enable CPM for Linux/MinGW if not using vcpkg
|
||||
if (NOT CITRON_USE_BUNDLED_VCPKG AND (UNIX OR MINGW))
|
||||
set(CITRON_USE_CPM ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
option(CITRON_USE_CPM "Use CPM.cmake to fetch dependencies instead of git submodules (Clangtron builds)" OFF)
|
||||
if (CITRON_USE_CPM)
|
||||
set(CITRON_CHECK_SUBMODULES OFF CACHE BOOL "" FORCE)
|
||||
else()
|
||||
option(CITRON_CHECK_SUBMODULES "Check if submodules are present" ON)
|
||||
endif()
|
||||
|
||||
option(CITRON_ENABLE_LTO "Enable link-time optimization" OFF)
|
||||
|
||||
@@ -113,52 +123,6 @@ if (ANDROID OR WIN32 OR APPLE)
|
||||
endif()
|
||||
option(ENABLE_OPENSSL "Enable OpenSSL backend for ISslConnection" ${DEFAULT_ENABLE_OPENSSL})
|
||||
|
||||
if (ANDROID AND CITRON_DOWNLOAD_ANDROID_VVL)
|
||||
set(vvl_version "vulkan-sdk-1.4.328.1")
|
||||
set(vvl_version_plain "1.4.328.1")
|
||||
set(vvl_zip_file "${CMAKE_BINARY_DIR}/externals/vvl-android.zip")
|
||||
set(vvl_extract_dir "${CMAKE_BINARY_DIR}/externals")
|
||||
|
||||
if (NOT EXISTS "${vvl_zip_file}")
|
||||
# Download and extract validation layer release to externals directory
|
||||
set(vvl_base_url "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download")
|
||||
file(DOWNLOAD "${vvl_base_url}/${vvl_version}/android-binaries-${vvl_version_plain}.zip"
|
||||
"${vvl_zip_file}" SHOW_PROGRESS)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${vvl_zip_file}"
|
||||
WORKING_DIRECTORY "${vvl_extract_dir}")
|
||||
endif()
|
||||
|
||||
# Copy the arm64 binary to src/android/app/main/jniLibs
|
||||
# New structure: android-binaries-X.X.X.X/android-binaries-X.X.X.X/arm64-v8a/libVkLayer_khronos_validation.so
|
||||
set(vvl_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/src/android/app/src/main/jniLibs/arm64-v8a/")
|
||||
set(vvl_source_file "${vvl_extract_dir}/android-binaries-${vvl_version_plain}/android-binaries-${vvl_version_plain}/arm64-v8a/libVkLayer_khronos_validation.so")
|
||||
|
||||
if (EXISTS "${vvl_source_file}")
|
||||
file(COPY "${vvl_source_file}" DESTINATION "${vvl_lib_path}")
|
||||
message(STATUS "Successfully copied VVL ${vvl_version_plain} to ${vvl_lib_path}")
|
||||
else()
|
||||
message(WARNING "Could not find Vulkan Validation Layer at: ${vvl_source_file}")
|
||||
message(STATUS "Please manually download from: ${vvl_base_url}/${vvl_version}/android-binaries-${vvl_version_plain}.zip")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# EXPERIMENTAL LIBC++
|
||||
if ((ANDROID OR APPLE OR UNIX) AND (NOT (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") OR ANDROID) AND NOT WIN32)
|
||||
if(CXX_APPLE OR CXX_CLANG)
|
||||
# libc++ has stop_token and jthread as experimental
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexperimental-library")
|
||||
else()
|
||||
# Uses glibc, mostly?
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LIBCPP_ENABLE_EXPERIMENTAL=1")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
set(CMAKE_SKIP_INSTALL_RULES ON)
|
||||
endif()
|
||||
|
||||
if (CITRON_USE_BUNDLED_VCPKG)
|
||||
if (ANDROID)
|
||||
set(ENV{ANDROID_NDK_HOME} "${ANDROID_NDK}")
|
||||
@@ -166,8 +130,6 @@ if (CITRON_USE_BUNDLED_VCPKG)
|
||||
|
||||
if (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
|
||||
set(VCPKG_TARGET_TRIPLET "arm64-android")
|
||||
# this is to avoid CMake using the host pkg-config to find the host
|
||||
# libraries when building for Android targets
|
||||
set(PKG_CONFIG_EXECUTABLE "aarch64-none-linux-android-pkg-config" CACHE FILEPATH "" FORCE)
|
||||
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
|
||||
set(VCPKG_TARGET_TRIPLET "x64-android")
|
||||
@@ -185,9 +147,7 @@ if (CITRON_USE_BUNDLED_VCPKG)
|
||||
|
||||
if (NOT EXISTS ${NASM_DESTINATION_PATH})
|
||||
file(DOWNLOAD ${NASM_DOWNLOAD_URL} ${NASM_DESTINATION_PATH} SHOW_PROGRESS STATUS NASM_STATUS)
|
||||
|
||||
if (NOT NASM_STATUS EQUAL 0)
|
||||
# Warn and not fail since vcpkg is supposed to download this package for us in the first place
|
||||
message(WARNING "External nasm vcpkg package download from ${NASM_DOWNLOAD_URL} failed with status ${NASM_STATUS}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -199,17 +159,15 @@ if (CITRON_USE_BUNDLED_VCPKG)
|
||||
if (ENABLE_WEB_SERVICE)
|
||||
list(APPEND VCPKG_MANIFEST_FEATURES "web-service")
|
||||
endif()
|
||||
if (ANDROID)
|
||||
list(APPEND VCPKG_MANIFEST_FEATURES "android")
|
||||
endif()
|
||||
|
||||
include(${CMAKE_SOURCE_DIR}/externals/vcpkg/scripts/buildsystems/vcpkg.cmake)
|
||||
elseif(NOT "$ENV{VCPKG_TOOLCHAIN_FILE}" STREQUAL "")
|
||||
# Disable manifest mode (use vcpkg classic mode) when using a custom vcpkg installation
|
||||
option(VCPKG_MANIFEST_MODE "")
|
||||
include("$ENV{VCPKG_TOOLCHAIN_FILE}")
|
||||
endif()
|
||||
|
||||
option(CITRON_USE_PRECOMPILED_HEADERS "Use Precompiled Headers" ON)
|
||||
|
||||
if (CITRON_USE_PRECOMPILED_HEADERS)
|
||||
if (MSVC AND CCACHE)
|
||||
# buildcache does not properly cache PCH files, leading to compilation errors.
|
||||
@@ -345,6 +303,16 @@ endif()
|
||||
# Output binaries to bin/
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
if (CITRON_USE_CPM AND CITRON_USE_BUNDLED_QT AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# Build-tree binaries are the portable deliverable for local Linux CPM builds.
|
||||
# Keep their loader search path relative to bin/ instead of embedding Qt or
|
||||
# dependency cache directories from the build host.
|
||||
set(CMAKE_BUILD_RPATH "$ORIGIN/lib")
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
add_link_options("-Wl,--disable-new-dtags")
|
||||
endif()
|
||||
|
||||
# System imported libraries
|
||||
# =======================================================================
|
||||
|
||||
|
||||
@@ -67,44 +67,166 @@ function(copy_citron_Qt6_deps target_dir)
|
||||
qschannelbackend$<$<CONFIG:Debug>:d>.*
|
||||
qopensslbackend$<$<CONFIG:Debug>:d>.*
|
||||
)
|
||||
elseif(MINGW)
|
||||
# For MinGW builds with CITRON_USE_BUNDLED_QT=ON the bundled Qt tree is
|
||||
# at build/externals/qt/<ver>/mingw_64/. CopyMinGWDeps.cmake handles the
|
||||
# runtime DLLs; this function handles the plugin subdirectories that
|
||||
# windeployqt would normally deploy but which are not on the DLL search path.
|
||||
elseif(MINGW OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# For MinGW and Native Linux builds with CITRON_USE_BUNDLED_QT=ON,
|
||||
# copy the plugins and libraries to subdirectories to keep bin/ clean.
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(LIB_DEST "${DLL_DEST}lib/")
|
||||
set(PLUGINS_DEST "${DLL_DEST}plugins/")
|
||||
set(USE_LIB_FOLDER ON)
|
||||
else()
|
||||
# Windows/MinGW: DLLs must be next to the EXE
|
||||
set(LIB_DEST "${DLL_DEST}")
|
||||
set(PLUGINS_DEST "${DLL_DEST}")
|
||||
set(USE_LIB_FOLDER OFF)
|
||||
endif()
|
||||
|
||||
# Resolve the plugin root from Qt6_DIR (which points to lib/cmake/Qt6).
|
||||
set(Qt6_BUNDLED_PLUGINS "${Qt6_DIR}/../../../plugins")
|
||||
|
||||
foreach(plugin_dir platforms styles imageformats iconengines)
|
||||
foreach(plugin_dir platforms styles imageformats iconengines tls wayland-graphics-integration wayland-shell-integration)
|
||||
if (EXISTS "${Qt6_BUNDLED_PLUGINS}/${plugin_dir}")
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${DLL_DEST}${plugin_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${PLUGINS_DEST}${plugin_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${Qt6_BUNDLED_PLUGINS}/${plugin_dir}"
|
||||
"${DLL_DEST}${plugin_dir}"
|
||||
COMMENT "Copying Qt6 ${plugin_dir} plugins (MinGW bundled)"
|
||||
"${PLUGINS_DEST}${plugin_dir}"
|
||||
COMMENT "Bundling Qt6 ${plugin_dir} plugins"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# TLS plugins — critical for HTTPS/SSL.
|
||||
if (EXISTS "${Qt6_BUNDLED_PLUGINS}/tls")
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
# For Linux, also copy the shared libraries.
|
||||
set(_qt_libs Core Gui Widgets Network Svg OpenGL DBus WaylandClient WaylandEglClient WaylandEglClientHwIntegration XcbQpa)
|
||||
if (CITRON_USE_QT_MULTIMEDIA)
|
||||
list(APPEND _qt_libs Multimedia MultimediaWidgets)
|
||||
endif()
|
||||
|
||||
foreach(_lib ${_qt_libs})
|
||||
if (EXISTS "${Qt6_DLL_DIR}libQt6${_lib}.so.6")
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${Qt6_DLL_DIR}libQt6${_lib}.so.6"
|
||||
"${LIB_DEST}"
|
||||
COMMENT "Bundling libQt6${_lib}.so.6"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
find_program(PATCHELF_EXE patchelf)
|
||||
if (NOT PATCHELF_EXE)
|
||||
message(FATAL_ERROR
|
||||
"patchelf is required for portable Linux CPM bundles. "
|
||||
"Run ./build-citron-linux.sh setup or install patchelf with your package manager.")
|
||||
endif()
|
||||
|
||||
# Bundle ICU libraries (required by QtCore)
|
||||
if (DEFINED ICU_BINARY_DIR)
|
||||
# If we built it ourselves, we know what we expect.
|
||||
# Note: We can't use GLOB at configuration time if it's a fresh build.
|
||||
set(_icu_libs data i18n io test tu uc)
|
||||
foreach(_icu_comp ${_icu_libs})
|
||||
set(_icu_lib "${ICU_BINARY_DIR}/libicu${_icu_comp}.so.73")
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_icu_lib}" "${LIB_DEST}"
|
||||
COMMENT "Bundling ICU library: ${_icu_lib}"
|
||||
)
|
||||
endforeach()
|
||||
else()
|
||||
file(GLOB _icu_libs "${Qt6_DLL_DIR}libicu*.so.[0-9]*")
|
||||
foreach(_icu_lib ${_icu_libs})
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_icu_lib}" "${LIB_DEST}"
|
||||
COMMENT "Bundling ICU library: ${_icu_lib}"
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Bundle additional XCB support libraries
|
||||
set(_xcb_deps
|
||||
xcb.so.1 Xau.so.6 xcb-xkb.so.1
|
||||
xcb-cursor.so.0 xcb-icccm.so.4 xcb-image.so.0 xcb-keysyms.so.1
|
||||
xcb-util.so.1
|
||||
xcb-render-util.so.0 xcb-xinerama.so.0 xcb-xinput.so.0
|
||||
xcb-shm.so.0 xcb-render.so.0 xcb-randr.so.0 xcb-shape.so.0
|
||||
xcb-xfixes.so.0 xcb-sync.so.1 xcb-dri3.so.0
|
||||
# Additional system libs needed by Qt XCB plugin
|
||||
xkbcommon.so.0 xkbcommon-x11.so.0 X11-xcb.so.1 Xdmcp.so.6
|
||||
)
|
||||
|
||||
if (DEFINED XCB_BINARY_DIR)
|
||||
set(_xcb_search_dir "${XCB_BINARY_DIR}/")
|
||||
else()
|
||||
set(_xcb_search_dir "SYSTEM")
|
||||
endif()
|
||||
|
||||
foreach(_xcb_lib ${_xcb_deps})
|
||||
if (_xcb_search_dir STREQUAL "SYSTEM" OR _xcb_lib MATCHES "xkbcommon|X11-xcb")
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=lib${_xcb_lib} OUTPUT_VARIABLE _LIB_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (NOT EXISTS "${_LIB_PATH}")
|
||||
# Fallback for some systems where print-file-name doesn't work well
|
||||
set(_LIB_PATH "/usr/lib/x86_64-linux-gnu/lib${_xcb_lib}")
|
||||
endif()
|
||||
else()
|
||||
set(_LIB_PATH "${_xcb_search_dir}lib${_xcb_lib}")
|
||||
endif()
|
||||
|
||||
# Always add the bundling command for built libs, or if system lib exists
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_LIB_PATH}" "${LIB_DEST}"
|
||||
COMMENT "Bundling XCB support library: ${_xcb_lib}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Bundle libstdc++ and libgcc_s
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=libstdc++.so.6 OUTPUT_VARIABLE _STDCXX_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -print-file-name=libgcc_s.so.1 OUTPUT_VARIABLE _GCC_S_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if (EXISTS "${_STDCXX_PATH}")
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_STDCXX_PATH}" "${LIB_DEST}"
|
||||
COMMENT "Bundling libstdc++.so.6"
|
||||
)
|
||||
endif()
|
||||
if (EXISTS "${_GCC_S_PATH}")
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${LIB_DEST}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_GCC_S_PATH}" "${LIB_DEST}"
|
||||
COMMENT "Bundling libgcc_s.so.1"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(_runtime_dependency_dirs "${LIB_DEST}" "${Qt6_DLL_DIR}")
|
||||
if (DEFINED ICU_BINARY_DIR)
|
||||
list(APPEND _runtime_dependency_dirs "${ICU_BINARY_DIR}")
|
||||
endif()
|
||||
if (DEFINED XCB_BINARY_DIR)
|
||||
list(APPEND _runtime_dependency_dirs "${XCB_BINARY_DIR}")
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _runtime_dependency_dirs)
|
||||
string(REPLACE ";" "|" _runtime_dependency_dirs_arg "${_runtime_dependency_dirs}")
|
||||
|
||||
add_custom_command(TARGET ${target_dir} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${TLS}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${Qt6_BUNDLED_PLUGINS}/tls"
|
||||
"${TLS}"
|
||||
COMMENT "Copying Qt6 TLS plugins (MinGW bundled)"
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DBUNDLE_BIN_DIR="${DLL_DEST}"
|
||||
-DPATCHELF_EXE="${PATCHELF_EXE}"
|
||||
-DRUNTIME_DEPENDENCY_DIRS="${_runtime_dependency_dirs_arg}"
|
||||
-P "${CMAKE_SOURCE_DIR}/CMakeModules/FixLinuxBundleRpaths.cmake"
|
||||
COMMENT "Copying Linux runtime dependencies and normalizing RPATHs"
|
||||
)
|
||||
else()
|
||||
message(WARNING "Qt6 TLS plugin directory not found at ${Qt6_BUNDLED_PLUGINS}/tls")
|
||||
message(WARNING "SSL/HTTPS will not work in this build.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Create an empty qt.conf so Qt locates its plugins relative to the executable.
|
||||
add_custom_command(TARGET citron POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${DLL_DEST}qt.conf
|
||||
)
|
||||
# Create a qt.conf next to the executable.
|
||||
file(MAKE_DIRECTORY "${DLL_DEST}")
|
||||
if (USE_LIB_FOLDER)
|
||||
file(WRITE "${DLL_DEST}qt.conf" "[Paths]\nPlugins = plugins\n")
|
||||
else()
|
||||
file(WRITE "${DLL_DEST}qt.conf" "")
|
||||
endif()
|
||||
endfunction(copy_citron_Qt6_deps)
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
# SPDX-FileCopyrightText: 2026 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
if (NOT DEFINED BUNDLE_BIN_DIR)
|
||||
message(FATAL_ERROR "BUNDLE_BIN_DIR is required")
|
||||
endif()
|
||||
if (NOT DEFINED PATCHELF_EXE OR NOT EXISTS "${PATCHELF_EXE}")
|
||||
message(FATAL_ERROR "patchelf is required to make the Linux bundle portable")
|
||||
endif()
|
||||
|
||||
set(_bin_dir "${BUNDLE_BIN_DIR}")
|
||||
set(_lib_dir "${_bin_dir}/lib")
|
||||
set(_plugins_dir "${_bin_dir}/plugins")
|
||||
file(MAKE_DIRECTORY "${_lib_dir}")
|
||||
|
||||
if (DEFINED RUNTIME_DEPENDENCY_DIRS)
|
||||
string(REPLACE "|" ";" _runtime_dependency_dirs "${RUNTIME_DEPENDENCY_DIRS}")
|
||||
endif()
|
||||
list(APPEND _runtime_dependency_dirs "${_lib_dir}")
|
||||
list(REMOVE_DUPLICATES _runtime_dependency_dirs)
|
||||
|
||||
foreach(_candidate citron citron-cmd citron-room shader_tool)
|
||||
if (EXISTS "${_bin_dir}/${_candidate}")
|
||||
list(APPEND _executables "${_bin_dir}/${_candidate}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(GLOB _bundled_libraries "${_lib_dir}/*.so" "${_lib_dir}/*.so.*")
|
||||
if (EXISTS "${_plugins_dir}")
|
||||
file(GLOB_RECURSE _bundled_modules "${_plugins_dir}/*.so")
|
||||
endif()
|
||||
|
||||
if (_executables OR _bundled_libraries OR _bundled_modules)
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
RESOLVED_DEPENDENCIES_VAR _resolved_dependencies
|
||||
UNRESOLVED_DEPENDENCIES_VAR _unresolved_dependencies
|
||||
CONFLICTING_DEPENDENCIES_PREFIX _conflicting
|
||||
EXECUTABLES ${_executables}
|
||||
LIBRARIES ${_bundled_libraries}
|
||||
MODULES ${_bundled_modules}
|
||||
DIRECTORIES ${_runtime_dependency_dirs}
|
||||
PRE_EXCLUDE_REGEXES
|
||||
[[^libgcc_s\.so\..*]]
|
||||
[[^libstdc\+\+\.so\..*]]
|
||||
[[^libglapi\.so\..*]]
|
||||
[[^libGL\.so\..*]]
|
||||
[[^libEGL\.so\..*]]
|
||||
[[^libvulkan\.so\..*]]
|
||||
[[^libXau\.so\..*]]
|
||||
[[^libXdmcp\.so\..*]]
|
||||
[[^libxcb\.so\..*]]
|
||||
POST_EXCLUDE_REGEXES
|
||||
[[/ld-linux[^/]*\.so(\..*)?$]]
|
||||
[[/libc\.so(\..*)?$]]
|
||||
[[/libm\.so(\..*)?$]]
|
||||
[[/libdl\.so(\..*)?$]]
|
||||
[[/libpthread\.so(\..*)?$]]
|
||||
[[/librt\.so(\..*)?$]]
|
||||
[[/libresolv\.so(\..*)?$]]
|
||||
[[/libutil\.so(\..*)?$]]
|
||||
[[/libnss_[^/]*\.so(\..*)?$]]
|
||||
[[/libanl\.so(\..*)?$]]
|
||||
[[/libgcc_s\.so(\..*)?$]]
|
||||
[[/libstdc\+\+\.so(\..*)?$]]
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(_dependency ${_resolved_dependencies})
|
||||
get_filename_component(_dependency_name "${_dependency}" NAME)
|
||||
if (NOT EXISTS "${_lib_dir}/${_dependency_name}")
|
||||
file(COPY "${_dependency}" DESTINATION "${_lib_dir}" FOLLOW_SYMLINK_CHAIN)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (_unresolved_dependencies)
|
||||
list(REMOVE_DUPLICATES _unresolved_dependencies)
|
||||
message(WARNING "Unresolved Linux bundle dependencies: ${_unresolved_dependencies}")
|
||||
endif()
|
||||
|
||||
function(_citron_is_elf output_var file_path)
|
||||
execute_process(
|
||||
COMMAND readelf -h "${file_path}"
|
||||
RESULT_VARIABLE _readelf_result
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET
|
||||
)
|
||||
if (_readelf_result EQUAL 0)
|
||||
set(${output_var} TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(${output_var} FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_citron_set_rpath file_path rpath)
|
||||
_citron_is_elf(_is_elf "${file_path}")
|
||||
if (NOT _is_elf)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND "${PATCHELF_EXE}" --force-rpath --set-rpath "${rpath}" "${file_path}"
|
||||
RESULT_VARIABLE _patchelf_result
|
||||
OUTPUT_VARIABLE _patchelf_stdout
|
||||
ERROR_VARIABLE _patchelf_stderr
|
||||
)
|
||||
if (NOT _patchelf_result EQUAL 0)
|
||||
message(FATAL_ERROR
|
||||
"Failed to set RPATH on ${file_path}\n"
|
||||
"${_patchelf_stdout}\n${_patchelf_stderr}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
foreach(_executable ${_executables})
|
||||
_citron_set_rpath("${_executable}" "$ORIGIN/lib")
|
||||
endforeach()
|
||||
|
||||
file(GLOB _final_libraries "${_lib_dir}/*.so" "${_lib_dir}/*.so.*")
|
||||
foreach(_library ${_final_libraries})
|
||||
_citron_set_rpath("${_library}" "$ORIGIN")
|
||||
endforeach()
|
||||
|
||||
if (EXISTS "${_plugins_dir}")
|
||||
file(GLOB_RECURSE _final_modules "${_plugins_dir}/*.so")
|
||||
foreach(_module ${_final_modules})
|
||||
_citron_set_rpath("${_module}" "$ORIGIN/../../lib")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(_rpath_failures)
|
||||
foreach(_file ${_executables} ${_final_libraries} ${_final_modules})
|
||||
_citron_is_elf(_is_elf "${_file}")
|
||||
if (NOT _is_elf)
|
||||
continue()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND readelf -d "${_file}"
|
||||
OUTPUT_VARIABLE _dynamic_section
|
||||
ERROR_QUIET
|
||||
)
|
||||
if (_dynamic_section MATCHES "(RPATH|RUNPATH)[^\n]*\\[/" OR
|
||||
_dynamic_section MATCHES "(RPATH|RUNPATH)[^\n]*:/")
|
||||
list(APPEND _rpath_failures "${_file}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (_rpath_failures)
|
||||
list(REMOVE_DUPLICATES _rpath_failures)
|
||||
message(FATAL_ERROR "Absolute RPATH/RUNPATH remains in Linux bundle: ${_rpath_failures}")
|
||||
endif()
|
||||
|
||||
message(STATUS "Linux bundle dependencies copied and RPATHs normalized in ${_bin_dir}")
|
||||
@@ -17,6 +17,14 @@
|
||||
# Static linking: BUILD_SHARED_LIBS is forced OFF in externals/CMakeLists.txt;
|
||||
# all CPM packages inherit this setting.
|
||||
|
||||
|
||||
# ── Submodule & vcpkg Policy ──────────────────────────────────────────────────
|
||||
# Force-disable reliance on git submodules and vcpkg. All external dependencies
|
||||
# must be fetched and managed via CPM to ensure portability and build-time
|
||||
# environment isolation.
|
||||
set(CITRON_CHECK_SUBMODULES OFF CACHE BOOL "Force disable submodule presence checks" FORCE)
|
||||
set(CITRON_USE_BUNDLED_VCPKG OFF CACHE BOOL "Force disable vcpkg usage" FORCE)
|
||||
|
||||
if (NOT COMMAND CPMAddPackage)
|
||||
message(FATAL_ERROR "CPM.cmake not loaded — include CMakeModules/CPM.cmake before this file")
|
||||
endif()
|
||||
@@ -574,6 +582,23 @@ elseif (CITRON_USE_BUNDLED_FFMPEG)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ── Dependency Versions (Qt, ICU, XCB) ─────────────────────────────────────────
|
||||
set(CITRON_QT_VERSION "6.9.3" CACHE STRING "Qt version to download via aqt")
|
||||
|
||||
set(CITRON_ICU_REPO "unicode-org/icu" CACHE STRING "ICU GitHub repository")
|
||||
set(CITRON_ICU_TAG "release-73-2" CACHE STRING "ICU git tag/version")
|
||||
|
||||
set(CITRON_XCB_MACROS_VER "1.20.2" CACHE STRING "XCB util-macros version")
|
||||
set(CITRON_XCB_PROTO_VER "1.17.0" CACHE STRING "XCB proto version")
|
||||
set(CITRON_XCB_XAU_VER "1.0.11" CACHE STRING "XCB libXau version")
|
||||
set(CITRON_XCB_LIBXCB_VER "1.16" CACHE STRING "XCB libxcb version")
|
||||
set(CITRON_XCB_UTIL_VER "0.4.1" CACHE STRING "XCB util version")
|
||||
set(CITRON_XCB_CURSOR_VER "0.1.6" CACHE STRING "XCB cursor version")
|
||||
set(CITRON_XCB_IMAGE_VER "0.4.1" CACHE STRING "XCB image version")
|
||||
set(CITRON_XCB_KEYSYMS_VER "0.4.1" CACHE STRING "XCB keysyms version")
|
||||
set(CITRON_XCB_RENDERUTIL_VER "0.3.10" CACHE STRING "XCB renderutil version")
|
||||
set(CITRON_XCB_WM_VER "0.4.2" CACHE STRING "XCB wm version")
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Qt
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
@@ -582,6 +607,10 @@ endif()
|
||||
# See CMakeModules/qt_download.cmake for details.
|
||||
if (ENABLE_QT AND NOT USE_SYSTEM_QT)
|
||||
include(${CMAKE_SOURCE_DIR}/CMakeModules/qt_download.cmake)
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
include(${CMAKE_SOURCE_DIR}/CMakeModules/icu_build.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/CMakeModules/xcb_build.cmake)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "[CPM] All dependency packages configured")
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# SPDX-FileCopyrightText: 2026 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# ICU build script for Linux portability.
|
||||
# Fetches ICU via CPM and builds it as shared libraries using Autotools.
|
||||
|
||||
if (NOT UNIX OR APPLE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CITRON_ICU_REPO)
|
||||
set(CITRON_ICU_REPO "unicode-org/icu")
|
||||
endif()
|
||||
if (NOT DEFINED CITRON_ICU_TAG)
|
||||
set(CITRON_ICU_TAG "release-73-2")
|
||||
endif()
|
||||
|
||||
CPMAddPackage(
|
||||
NAME icu_src
|
||||
GITHUB_REPOSITORY "${CITRON_ICU_REPO}"
|
||||
GIT_TAG "${CITRON_ICU_TAG}"
|
||||
DOWNLOAD_ONLY YES
|
||||
)
|
||||
|
||||
if (icu_src_ADDED)
|
||||
set(ICU_PREFIX "${icu_src_SOURCE_DIR}/icu4c")
|
||||
set(ICU_BUILD_DIR "${CMAKE_BINARY_DIR}/externals/icu-build")
|
||||
file(MAKE_DIRECTORY "${ICU_BUILD_DIR}")
|
||||
|
||||
# Identify the shared libraries we expect to produce
|
||||
set(_icu_components data i18n io test tu uc)
|
||||
set(ICU_LIBRARIES)
|
||||
foreach(_comp ${_icu_components})
|
||||
list(APPEND ICU_LIBRARIES "${ICU_BUILD_DIR}/lib/libicu${_comp}.so.73")
|
||||
endforeach()
|
||||
|
||||
execute_process(COMMAND nproc OUTPUT_VARIABLE SYSTEM_THREADS OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
set(_icu_work_dir "${ICU_BUILD_DIR}/build")
|
||||
file(MAKE_DIRECTORY "${_icu_work_dir}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${_icu_work_dir}/Makefile"
|
||||
COMMAND "${ICU_PREFIX}/source/configure"
|
||||
--prefix="${ICU_BUILD_DIR}"
|
||||
--enable-shared
|
||||
--disable-static
|
||||
--disable-samples
|
||||
--disable-tests
|
||||
WORKING_DIRECTORY "${_icu_work_dir}"
|
||||
COMMENT "Configuring ICU via Autotools"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${ICU_LIBRARIES}
|
||||
COMMAND make -j${SYSTEM_THREADS}
|
||||
COMMAND make install
|
||||
DEPENDS "${_icu_work_dir}/Makefile"
|
||||
WORKING_DIRECTORY "${_icu_work_dir}"
|
||||
COMMENT "Building and installing ICU"
|
||||
)
|
||||
|
||||
add_custom_target(icu-build ALL DEPENDS ${ICU_LIBRARIES})
|
||||
|
||||
# Export for CopyCitronQt6Deps
|
||||
set(ICU_BINARY_DIR "${ICU_BUILD_DIR}/lib" CACHE INTERNAL "Location of CPM-built ICU libs")
|
||||
endif()
|
||||
@@ -17,8 +17,20 @@
|
||||
#
|
||||
# Prerequisites: Python3 + aqt must be installed (build script's ensure_aqt() handles this).
|
||||
|
||||
set(CITRON_QT_VERSION "6.9.3" CACHE STRING "Qt version to download via aqt")
|
||||
set(CITRON_QT_BASE_DIR "${CMAKE_BINARY_DIR}/externals/qt-cpm" CACHE PATH
|
||||
# The version is defined in dependencies.cmake as a CACHE variable.
|
||||
if (NOT DEFINED CITRON_QT_VERSION)
|
||||
set(CITRON_QT_VERSION "6.9.3")
|
||||
endif()
|
||||
|
||||
if (DEFINED ENV{CPM_SOURCE_CACHE})
|
||||
set(_DEFAULT_QT_BASE_DIR "$ENV{CPM_SOURCE_CACHE}/qt-bin")
|
||||
elseif (DEFINED CPM_SOURCE_CACHE)
|
||||
set(_DEFAULT_QT_BASE_DIR "${CPM_SOURCE_CACHE}/qt-bin")
|
||||
else()
|
||||
set(_DEFAULT_QT_BASE_DIR "${CMAKE_BINARY_DIR}/externals/qt-cpm")
|
||||
endif()
|
||||
|
||||
set(CITRON_QT_BASE_DIR "${_DEFAULT_QT_BASE_DIR}" CACHE PATH
|
||||
"Base directory for aqt-managed Qt downloads")
|
||||
|
||||
# ── Find aqt ──────────────────────────────────────────────────────────────────
|
||||
@@ -44,12 +56,14 @@ if (WIN32)
|
||||
set(_QT_OS "windows")
|
||||
set(_QT_TARGET "desktop")
|
||||
set(_QT_ARCH "win64_llvm_mingw")
|
||||
set(_QT_DIR_NAME "llvm-mingw_64")
|
||||
set(_QT_CMAKE_SUB "lib/cmake/Qt6")
|
||||
else()
|
||||
# Native Linux (or macOS — extend here if needed)
|
||||
set(_QT_OS "linux")
|
||||
set(_QT_TARGET "desktop")
|
||||
set(_QT_ARCH "linux_gcc_64")
|
||||
set(_QT_DIR_NAME "gcc_64")
|
||||
set(_QT_CMAKE_SUB "lib/cmake/Qt6")
|
||||
endif()
|
||||
|
||||
@@ -57,7 +71,7 @@ endif()
|
||||
if (Qt6_DIR AND EXISTS "${Qt6_DIR}/Qt6Config.cmake")
|
||||
message(STATUS "[Qt] Using target Qt from Qt6_DIR: ${Qt6_DIR}")
|
||||
else()
|
||||
set(_QT_TARGET_DIR "${CITRON_QT_BASE_DIR}/${CITRON_QT_VERSION}/${_QT_ARCH}")
|
||||
set(_QT_TARGET_DIR "${CITRON_QT_BASE_DIR}/${CITRON_QT_VERSION}/${_QT_DIR_NAME}")
|
||||
set(_QT_TARGET_CMAKE "${_QT_TARGET_DIR}/${_QT_CMAKE_SUB}/Qt6Config.cmake")
|
||||
|
||||
if (NOT EXISTS "${_QT_TARGET_CMAKE}")
|
||||
@@ -92,7 +106,7 @@ else()
|
||||
${_QT_OS} ${_QT_TARGET}
|
||||
${CITRON_QT_VERSION} ${_QT_ARCH}
|
||||
--outputdir "${CITRON_QT_BASE_DIR}"
|
||||
--modules qtmultimedia qtimageformats qtsvg
|
||||
--modules qtmultimedia qtimageformats
|
||||
RESULT_VARIABLE _qt_mm_result
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
)
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
# SPDX-FileCopyrightText: 2026 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# XCB utility build script for Linux portability.
|
||||
# Fetches XCB components via CPM and builds them as shared libraries.
|
||||
|
||||
if (NOT UNIX OR APPLE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# We need a list of components to fetch and build.
|
||||
# 'macros' and 'proto' must come first as others depend on them.
|
||||
set(_xcb_components macros proto xau libxcb util image keysyms renderutil wm cursor)
|
||||
|
||||
set(XCB_BUILD_ROOT "${CMAKE_BINARY_DIR}/externals/xcb-build")
|
||||
file(MAKE_DIRECTORY "${XCB_BUILD_ROOT}")
|
||||
set(XCB_BINARY_DIR "${XCB_BUILD_ROOT}/lib" CACHE INTERNAL "Location of CPM-built XCB libs")
|
||||
|
||||
# Define versions for each component to fetch the correct tarball
|
||||
# These are defined in dependencies.cmake as CACHE variables.
|
||||
set(_xcb_macros_ver "${CITRON_XCB_MACROS_VER}")
|
||||
set(_xcb_proto_ver "${CITRON_XCB_PROTO_VER}")
|
||||
set(_xcb_xau_ver "${CITRON_XCB_XAU_VER}")
|
||||
set(_xcb_libxcb_ver "${CITRON_XCB_LIBXCB_VER}")
|
||||
set(_xcb_cursor_ver "${CITRON_XCB_CURSOR_VER}")
|
||||
set(_xcb_util_ver "${CITRON_XCB_UTIL_VER}")
|
||||
set(_xcb_image_ver "${CITRON_XCB_IMAGE_VER}")
|
||||
set(_xcb_keysyms_ver "${CITRON_XCB_KEYSYMS_VER}")
|
||||
set(_xcb_renderutil_ver "${CITRON_XCB_RENDERUTIL_VER}")
|
||||
set(_xcb_wm_ver "${CITRON_XCB_WM_VER}")
|
||||
|
||||
set(CITRON_XCB_TARGETS "" CACHE INTERNAL "List of XCB build targets")
|
||||
foreach(_comp ${_xcb_components})
|
||||
# (re-pasting the existing logic to avoid deletion)
|
||||
if (_comp STREQUAL "macros")
|
||||
set(_url "https://xorg.freedesktop.org/archive/individual/util/util-macros-${_xcb_macros_ver}.tar.xz")
|
||||
set(_name "util-macros")
|
||||
elseif(_comp STREQUAL "xau")
|
||||
set(_url "https://xorg.freedesktop.org/archive/individual/lib/libXau-${_xcb_xau_ver}.tar.xz")
|
||||
set(_name "libXau")
|
||||
elseif(_comp STREQUAL "libxcb")
|
||||
set(_url "https://xcb.freedesktop.org/dist/libxcb-${_xcb_libxcb_ver}.tar.xz")
|
||||
set(_name "libxcb")
|
||||
elseif(_comp STREQUAL "proto")
|
||||
set(_url "https://xcb.freedesktop.org/dist/xcb-proto-${_xcb_proto_ver}.tar.xz")
|
||||
set(_name "xcb-proto")
|
||||
else()
|
||||
set(_name "xcb-util")
|
||||
if (NOT _comp STREQUAL "util")
|
||||
set(_name "xcb-util-${_comp}")
|
||||
endif()
|
||||
set(_ver "${_xcb_${_comp}_ver}")
|
||||
set(_url "https://xcb.freedesktop.org/dist/${_name}-${_ver}.tar.xz")
|
||||
endif()
|
||||
|
||||
CPMAddPackage(
|
||||
NAME xcb_${_comp}_src
|
||||
URL "${_url}"
|
||||
DOWNLOAD_ONLY YES
|
||||
)
|
||||
|
||||
if (xcb_${_comp}_src_ADDED)
|
||||
set(_src_dir "${xcb_${_comp}_src_SOURCE_DIR}")
|
||||
set(_build_dir "${XCB_BUILD_ROOT}/${_comp}")
|
||||
file(MAKE_DIRECTORY "${_build_dir}")
|
||||
|
||||
# Check if it has a CMakeLists.txt (newer versions do) or needs Autotools
|
||||
if (EXISTS "${_src_dir}/CMakeLists.txt")
|
||||
# Build via CMake
|
||||
add_subdirectory("${_src_dir}" "${_build_dir}")
|
||||
else()
|
||||
# Build via Autotools (standard fallback)
|
||||
set(_env_vars
|
||||
"ACLOCAL_PATH=${XCB_BUILD_ROOT}/share/aclocal"
|
||||
"PKG_CONFIG_PATH=${XCB_BUILD_ROOT}/lib/pkgconfig:${XCB_BUILD_ROOT}/share/pkgconfig"
|
||||
"PYTHON=python3"
|
||||
"LD_RUN_PATH=\$\$ORIGIN"
|
||||
)
|
||||
|
||||
set(_target_name "xcb-${_comp}-build")
|
||||
list(APPEND CITRON_XCB_TARGETS ${_target_name})
|
||||
set(CITRON_XCB_TARGETS ${CITRON_XCB_TARGETS} CACHE INTERNAL "List of XCB build targets")
|
||||
|
||||
# We use autoreconf -fi to refresh libtool/aclocal files from the host system
|
||||
# to avoid mismatch errors (e.g. 'ltmain.sh is newer').
|
||||
add_custom_command(
|
||||
OUTPUT "${_build_dir}/Makefile"
|
||||
COMMAND ${CMAKE_COMMAND} -E env ${_env_vars} autoreconf -fi "${_src_dir}"
|
||||
COMMAND ${CMAKE_COMMAND} -E env ${_env_vars} "${_src_dir}/configure" --prefix="${XCB_BUILD_ROOT}" --enable-shared
|
||||
WORKING_DIRECTORY "${_build_dir}"
|
||||
COMMENT "Configuring ${_name} via Autotools"
|
||||
)
|
||||
add_custom_target(${_target_name} ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E env ${_env_vars} make install
|
||||
DEPENDS "${_build_dir}/Makefile"
|
||||
WORKING_DIRECTORY "${_build_dir}"
|
||||
COMMENT "Building ${_name}"
|
||||
)
|
||||
|
||||
# Enforce sequential build ordering to ensure all dependencies are installed
|
||||
# in XCB_BUILD_ROOT before downstream components are configured.
|
||||
if (_last_xcb_target)
|
||||
add_dependencies(${_target_name} ${_last_xcb_target})
|
||||
endif()
|
||||
set(_last_xcb_target ${_target_name})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
Regular → Executable
+23
-10
@@ -129,6 +129,7 @@
|
||||
# python3 + aqtinstall Qt binary download (invoked by cmake)
|
||||
# autoconf + automake + make FFmpeg autotools build
|
||||
# glslang (glslc) Vulkan shader compilation
|
||||
# patchelf bundle RPATH normalization
|
||||
# perf propeller stage only
|
||||
# =============================================================================
|
||||
|
||||
@@ -350,7 +351,7 @@ stage_setup() {
|
||||
*)
|
||||
warn "Unrecognised package manager. Install manually:"
|
||||
warn " clang (${CLANG_VERSION}+), lld, llvm-profdata, cmake, ninja, git,"
|
||||
warn " nasm, perl, python3, python3-pip, autoconf, automake, make, glslang-tools"
|
||||
warn " nasm, perl, python3, python3-pip, autoconf, automake, make, glslang-tools, patchelf"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -370,6 +371,7 @@ _setup_apt() {
|
||||
nasm yasm perl \
|
||||
autoconf automake make \
|
||||
glslang-tools \
|
||||
patchelf \
|
||||
lsb-release software-properties-common gnupg \
|
||||
libelf-dev libssl-dev libzstd-dev \
|
||||
linux-tools-common linux-tools-generic 2>/dev/null || true
|
||||
@@ -384,7 +386,7 @@ _setup_pacman() {
|
||||
nasm yasm perl \
|
||||
autoconf automake make \
|
||||
glslang clang lld llvm \
|
||||
perf 2>/dev/null || true
|
||||
patchelf perf 2>/dev/null || true
|
||||
# Arch ships unversioned tools — symlink to versioned names
|
||||
for tool in clang clang++ lld llvm-profdata llvm-bolt merge-fdata; do
|
||||
local versioned="/usr/local/bin/${tool}-${CLANG_VERSION}"
|
||||
@@ -402,7 +404,7 @@ _setup_dnf() {
|
||||
python3 python3-pip curl wget xz \
|
||||
nasm yasm perl \
|
||||
autoconf automake make \
|
||||
glslang clang lld \
|
||||
glslang clang lld patchelf \
|
||||
elfutils-libelf-devel openssl-devel \
|
||||
perf 2>/dev/null || true
|
||||
sudo dnf install -y "clang${CLANG_VERSION}" "llvm${CLANG_VERSION}" 2>/dev/null \
|
||||
@@ -417,7 +419,7 @@ _setup_yum() {
|
||||
python3 python3-pip curl wget xz \
|
||||
nasm yasm perl \
|
||||
autoconf automake make \
|
||||
clang lld \
|
||||
clang lld patchelf \
|
||||
elfutils-libelf-devel openssl-devel \
|
||||
perf 2>/dev/null || true
|
||||
warn "yum/CentOS: LLVM ${CLANG_VERSION} may not be in repos. Check SCL or llvm.org."
|
||||
@@ -430,7 +432,7 @@ _setup_zypper() {
|
||||
python3 python3-pip curl wget xz \
|
||||
nasm yasm perl \
|
||||
autoconf automake make \
|
||||
glslang clang lld llvm \
|
||||
glslang clang lld llvm patchelf \
|
||||
libelf-devel libopenssl-devel \
|
||||
perf 2>/dev/null || true
|
||||
}
|
||||
@@ -444,6 +446,7 @@ _setup_emerge() {
|
||||
sys-devel/clang sys-devel/lld \
|
||||
dev-build/autoconf dev-build/automake \
|
||||
media-libs/glslang \
|
||||
dev-util/patchelf \
|
||||
dev-libs/elfutils dev-libs/openssl 2>/dev/null || true
|
||||
}
|
||||
|
||||
@@ -503,7 +506,7 @@ _verify_tools() {
|
||||
info "Verifying installation..."
|
||||
local ok=1
|
||||
for tool in "${CLANG}" "${CLANGPP}" "${LLD}" "${LLVM_PROFDATA}" \
|
||||
cmake ninja git nasm perl python3; do
|
||||
cmake ninja git nasm perl python3 patchelf; do
|
||||
if command -v "${tool}" &>/dev/null; then
|
||||
success " ${tool} -> $(command -v "${tool}")"
|
||||
else
|
||||
@@ -663,7 +666,9 @@ common_cmake_args() {
|
||||
"-DUSE_SYSTEM_QT=OFF" \
|
||||
"-DENABLE_QT6=ON" \
|
||||
"-DCITRON_USE_BUNDLED_FFMPEG=ON" \
|
||||
"-DBUILD_TESTING=OFF" \
|
||||
"-DCITRON_TESTS=OFF" \
|
||||
"-DCITRON_DOWNLOAD_TIME_ZONE_DATA=ON" \
|
||||
"-DCITRON_CHECK_SUBMODULES=OFF" \
|
||||
"-DCITRON_USE_LLVM_DEMANGLE=OFF" \
|
||||
"-DCITRON_USE_QT_MULTIMEDIA=ON" \
|
||||
@@ -822,6 +827,7 @@ stage_generate() {
|
||||
"-DCMAKE_EXE_LINKER_FLAGS_${bt_upper}=${linker_flags}"
|
||||
|
||||
write_gen_sentinel
|
||||
mkdir -p "${BUILD_GENERATE}/bin/user"
|
||||
success "Instrumented build: ${BUILD_GENERATE}/bin/citron"
|
||||
print_profiling_instructions "${BUILD_GENERATE}/bin/citron"
|
||||
}
|
||||
@@ -894,6 +900,7 @@ stage_csgenerate() {
|
||||
"-DCMAKE_CXX_FLAGS_${bt_upper}=${compile_flags}" \
|
||||
"-DCMAKE_EXE_LINKER_FLAGS_${bt_upper}=${linker_flags}"
|
||||
|
||||
mkdir -p "${BUILD_CSGENERATE}/bin/user"
|
||||
success "CS-IRPGO instrumented build: ${BUILD_CSGENERATE}/bin/citron"
|
||||
echo ""
|
||||
echo -e "${YELLOW}════════════════════════════════════════════════════════════════${RESET}"
|
||||
@@ -963,6 +970,7 @@ stage_use() {
|
||||
header "Build: Baseline Release (no PGO, LTO=${LTO_MODE})"
|
||||
apply_source_patches
|
||||
_build_with_flags "${BUILD_ROOT}/use-nopgo" nopgo
|
||||
mkdir -p "${BUILD_ROOT}/use-nopgo/bin/user"
|
||||
success "Baseline build: ${BUILD_ROOT}/use-nopgo/bin/citron"
|
||||
return 0
|
||||
fi
|
||||
@@ -1004,6 +1012,7 @@ stage_use() {
|
||||
echo ""
|
||||
success "════════════════════════════════════════════════════════════════"
|
||||
success " Stage use complete"
|
||||
mkdir -p "${BUILD_USE}/bin/user"
|
||||
success " Binary: ${BUILD_USE}/bin/citron"
|
||||
success " PGO: ${pgo_label}"
|
||||
success " LTO: ${LTO_MODE}${LTO_MODE:+ ($(lto_clang_flag))}"
|
||||
@@ -1123,8 +1132,8 @@ stage_bolt() {
|
||||
fi
|
||||
|
||||
local elf_binary="${relocs_dir}/bin/citron"
|
||||
mkdir -p "${BOLT_PROFILE_DIR}" "${BUILD_BOLT}"
|
||||
local instrumented="${BUILD_BOLT}/citron-bolt-instrumented"
|
||||
mkdir -p "${BOLT_PROFILE_DIR}" "${BUILD_BOLT}/bin"
|
||||
local instrumented="${BUILD_BOLT}/bin/citron-bolt-instrumented"
|
||||
local fdata_pattern="${BOLT_PROFILE_DIR}/citron-%p.fdata"
|
||||
local merged_fdata="${BOLT_PROFILE_DIR}/citron-merged.fdata"
|
||||
|
||||
@@ -1167,15 +1176,17 @@ stage_bolt() {
|
||||
--split-all-cold \
|
||||
--split-eh \
|
||||
--dyno-stats \
|
||||
-o "${BUILD_BOLT}/citron" \
|
||||
-o "${BUILD_BOLT}/bin/citron" \
|
||||
|| error "BOLT optimization failed."
|
||||
|
||||
echo ""
|
||||
success "════════════════════════════════════════════════════════════════"
|
||||
success " Stage bolt complete"
|
||||
success " Binary: ${BUILD_BOLT}/citron"
|
||||
mkdir -p "${BUILD_BOLT}/user"
|
||||
success " Binary: ${BUILD_BOLT}/bin/citron"
|
||||
success " Optimizations: PGO + LTO + BOLT basic-block reordering"
|
||||
success "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
@@ -1341,9 +1352,11 @@ stage_propeller() {
|
||||
echo ""
|
||||
success "════════════════════════════════════════════════════════════════"
|
||||
success " Stage propeller complete"
|
||||
mkdir -p "${BUILD_PROPELLER}/bin/user"
|
||||
success " Binary: ${BUILD_PROPELLER}/bin/citron"
|
||||
success " Optimizations: PGO + LTO + Propeller BB+function layout"
|
||||
success "════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
|
||||
Vendored
+3
-1
@@ -40,6 +40,9 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
set(FFmpeg_FOUND YES)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED FFmpeg_COMPONENTS)
|
||||
set(FFmpeg_COMPONENTS avcodec avfilter avutil swscale)
|
||||
endif()
|
||||
unset(FFmpeg_LIBRARIES CACHE)
|
||||
foreach(COMPONENT ${FFmpeg_COMPONENTS})
|
||||
set(FFmpeg_${COMPONENT}_PREFIX "${FFmpeg_BUILD_DIR}/lib${COMPONENT}")
|
||||
@@ -168,7 +171,6 @@ if (NOT WIN32 AND NOT ANDROID)
|
||||
--disable-ffmpeg
|
||||
--disable-ffprobe
|
||||
--disable-network
|
||||
--disable-postproc
|
||||
--disable-swresample
|
||||
--enable-decoder=h264
|
||||
--enable-decoder=vp8
|
||||
|
||||
@@ -14,7 +14,13 @@ set(CMAKE_JOB_POOL_LINK link_pool)
|
||||
# Set the RPATH for Qt Libraries
|
||||
# This must be done before the `citron` target is created
|
||||
if (CITRON_USE_BUNDLED_QT AND (${CMAKE_SYSTEM_NAME} STREQUAL "Linux"))
|
||||
set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}/bin/lib/")
|
||||
# Use relative RPATH so the binary finds libraries in the 'lib' subfolder.
|
||||
# $ORIGIN refers to the directory containing the executable.
|
||||
# We use --disable-new-dtags to force RPATH instead of RUNPATH,
|
||||
# ensuring recursive dependency resolution for bundled libraries.
|
||||
set(CMAKE_BUILD_RPATH "$ORIGIN/lib/")
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib/")
|
||||
add_link_options("-Wl,--disable-new-dtags")
|
||||
endif()
|
||||
|
||||
add_executable(citron
|
||||
@@ -652,6 +658,12 @@ endif()
|
||||
|
||||
if (CITRON_USE_BUNDLED_QT)
|
||||
include(CopyCitronQt6Deps)
|
||||
if (TARGET icu-build)
|
||||
add_dependencies(citron icu-build)
|
||||
endif()
|
||||
if (CITRON_XCB_TARGETS)
|
||||
add_dependencies(citron ${CITRON_XCB_TARGETS})
|
||||
endif()
|
||||
copy_citron_Qt6_deps(citron)
|
||||
endif()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user