Files
kte/cmake/fix_bundle.cmake
T
kyleandClaude Opus 5.5 2125583407 Remove the Qt frontend
The Qt GUI was unused: out of make-app-release since March, not built by
the gate, and its app bundle could not start (no platform plugin). Every
renderer and input change had to be made in it separately. kge is the
ImGui frontend only.

Removes QtFrontend/QtInputHandler/QtRenderer, the KTE_USE_QT option and
its #if branches (Command.cc, GUITheme.h, main.cc), the Nix qt package
and dev shell, the commented-out Qt release steps, the Qt frontend plan,
and Qt mentions in AGENTS.md, DEVELOPER_GUIDE.md, REWRITE.md and code
comments. Git history keeps the code.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 12:32:58 -07:00

106 lines
4.4 KiB
CMake

cmake_minimum_required(VERSION 3.15)
# Fix up a macOS .app bundle by copying non-system dylibs into
# Contents/Frameworks and rewriting install names to use @rpath/@loader_path.
#
# Usage:
# cmake -DAPP_BUNDLE=/path/to/kge.app -P cmake/fix_bundle.cmake
if (NOT APP_BUNDLE)
message(FATAL_ERROR "APP_BUNDLE not set. Invoke with -DAPP_BUNDLE=/path/to/App.app")
endif ()
get_filename_component(APP_DIR "${APP_BUNDLE}" ABSOLUTE)
set(EXECUTABLE "${APP_DIR}/Contents/MacOS/kge")
if (NOT EXISTS "${EXECUTABLE}")
message(FATAL_ERROR "Executable not found at: ${EXECUTABLE}")
endif ()
include(BundleUtilities)
# Directories to search when resolving prerequisites. We include Homebrew so that
# if any deps are currently resolved from there, fixup_bundle will copy them into
# the bundle and rewrite install names to be self-contained.
set(DIRS
"/usr/local/lib"
"/opt/homebrew/lib"
"/opt/homebrew/opt"
)
# Note: We pass empty plugin list so fixup_bundle scans the executable and all
# libs it references recursively, copying every non-system dylib (e.g. Homebrew
# SDL2, freetype, pcre2) into Contents/Frameworks; SDL3 is handled below.
# fixup_bundle often fails if copied libraries are read-only.
# We also try to use the system install_name_tool and otool to avoid issues with Anaconda's version.
# Note: BundleUtilities uses find_program(gp_otool "otool") internally, so we might need to set it differently.
set(gp_otool "/usr/bin/otool")
set(CMAKE_INSTALL_NAME_TOOL "/usr/bin/install_name_tool")
set(CMAKE_OTOOL "/usr/bin/otool")
set(ENV{PATH} "/usr/bin:/bin:/usr/sbin:/sbin")
execute_process(COMMAND chmod -R u+w "${APP_DIR}/Contents/Frameworks")
fixup_bundle("${APP_DIR}" "" "${DIRS}")
# Homebrew's sdl2 is sdl2-compat, which dlopen()s SDL3 at startup instead of
# linking it, so fixup_bundle never sees it. Without SDL3 in the bundle kge
# stops at launch with "Failed loading SDL3 library". sdl2-compat looks for
# @loader_path/libSDL3.dylib first; put SDL3 there.
set(SDL2_IN_BUNDLE "${APP_DIR}/Contents/Frameworks/libSDL2-2.0.0.dylib")
if (EXISTS "${SDL2_IN_BUNDLE}")
file(STRINGS "${SDL2_IN_BUNDLE}" SDL2_COMPAT_REFS REGEX "libSDL3\\.dylib")
if (SDL2_COMPAT_REFS)
find_file(SDL3_DYLIB NAMES libSDL3.0.dylib libSDL3.dylib
PATHS "/opt/homebrew/opt/sdl3/lib" "/opt/homebrew/lib" "/usr/local/opt/sdl3/lib" "/usr/local/lib"
NO_DEFAULT_PATH)
if (NOT SDL3_DYLIB)
message(FATAL_ERROR "libSDL2 in the bundle is sdl2-compat, which needs SDL3 at run time, "
"but libSDL3 was not found (brew install sdl3)")
endif ()
file(REAL_PATH "${SDL3_DYLIB}" SDL3_REAL)
set(SDL3_IN_BUNDLE "${APP_DIR}/Contents/Frameworks/libSDL3.dylib")
message(STATUS "Bundling SDL3 for sdl2-compat: ${SDL3_REAL}")
file(COPY_FILE "${SDL3_REAL}" "${SDL3_IN_BUNDLE}")
execute_process(COMMAND chmod u+w "${SDL3_IN_BUNDLE}")
execute_process(COMMAND /usr/bin/install_name_tool -id "@loader_path/libSDL3.dylib" "${SDL3_IN_BUNDLE}"
RESULT_VARIABLE SDL3_ID_RESULT)
if (NOT SDL3_ID_RESULT EQUAL 0)
message(FATAL_ERROR "install_name_tool -id failed on ${SDL3_IN_BUNDLE}")
endif ()
endif ()
endif ()
# On Apple Silicon (and modern macOS in general), modifications by fixup_bundle
# invalidate code signatures. We must re-sign the bundle (at least ad-hoc)
# for it to be allowed to run.
# We sign deep, but sometimes explicit signing of components is more reliable.
message(STATUS "Re-signing ${APP_DIR} after fixup...")
# 1. Sign dylibs in Frameworks
file(GLOB_RECURSE DYLIBS "${APP_DIR}/Contents/Frameworks/*.dylib")
foreach (DYLIB ${DYLIBS})
message(STATUS "Signing ${DYLIB}...")
execute_process(COMMAND /usr/bin/codesign --force --sign - "${DYLIB}")
endforeach ()
# 2. Sign nested executables
message(STATUS "Signing nested kte...")
execute_process(COMMAND /usr/bin/codesign --force --sign - "${APP_DIR}/Contents/MacOS/kte")
# 3. Sign the main executable explicitly
message(STATUS "Signing main kge...")
execute_process(COMMAND /usr/bin/codesign --force --sign - "${APP_DIR}/Contents/MacOS/kge")
# 4. Sign the main bundle
execute_process(
COMMAND /usr/bin/codesign --force --deep --sign - "${APP_DIR}"
RESULT_VARIABLE CODESIGN_RESULT
)
if (NOT CODESIGN_RESULT EQUAL 0)
message(FATAL_ERROR "Codesign failed with error: ${CODESIGN_RESULT}")
endif ()
message(STATUS "fix_bundle.cmake completed for ${APP_DIR}")