diff --git a/CMakeLists.txt b/CMakeLists.txt index 391dc4d72..dac5d4a42 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,8 +36,12 @@ if(NOT DEFINED KANGAROO_ARCH) set(KANGAROO_ARCH x86_64) endif() -# Where the superbuild installs the third party libraries for this platform. -set(BUILD_DIR ${CMAKE_SOURCE_DIR}/.builddir/${KANGAROO_OS}/${KANGAROO_ARCH}) +# Where the superbuild installs the third party libraries for this platform. SINGE_TREE lets a +# second toolchain for the same platform keep its own tree (the zig Linux build beside the gcc one). +if(NOT DEFINED SINGE_TREE) + set(SINGE_TREE ${KANGAROO_OS}) +endif() +set(BUILD_DIR ${CMAKE_SOURCE_DIR}/.builddir/${SINGE_TREE}/${KANGAROO_ARCH}) set(GENERATED_DIR ${CMAKE_BINARY_DIR}/generated) file(MAKE_DIRECTORY ${GENERATED_DIR}) @@ -476,8 +480,16 @@ target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE if(KANGAROO_OS STREQUAL "linux") # ffmpeg's vdpau hardware context is always compiled in on X11 hosts. set(SYSTEM_LIBS -lX11 -lvdpau -ldl -rdynamic) # -rdynamic gives the crash backtrace function names + # Release binaries are stripped; the crash backtrace reads the dynamic symbols -rdynamic exports, + # which stripping keeps. + if(CMAKE_BUILD_TYPE STREQUAL "Release") + list(APPEND SYSTEM_LIBS -s) + endif() elseif(KANGAROO_OS STREQUAL "pi") set(SYSTEM_LIBS -ldl) + if(CMAKE_BUILD_TYPE STREQUAL "Release") + list(APPEND SYSTEM_LIBS -s) + endif() elseif(KANGAROO_OS STREQUAL "macos") set(SYSTEM_LIBS -Wl,-framework,CoreVideo @@ -495,10 +507,13 @@ elseif(KANGAROO_OS STREQUAL "macos") -Wl,-weak_framework,CoreHaptics -liconv -lc++ - ${OSXCROSS_TARGET_DIR}/darwin/libclang_rt.osx.a ) - if(NOT DEFINED OSXCROSS_TARGET_DIR) - message(FATAL_ERROR "OSXCROSS_TARGET_DIR must be set for macOS builds.") + if(NOT SINGE_ZIG_TARGET) + # osxcross builds need clang's runtime library named; zig carries its own. + if(NOT DEFINED OSXCROSS_TARGET_DIR) + message(FATAL_ERROR "OSXCROSS_TARGET_DIR must be set for macOS builds without zig.") + endif() + list(APPEND SYSTEM_LIBS ${OSXCROSS_TARGET_DIR}/darwin/libclang_rt.osx.a) endif() elseif(KANGAROO_OS STREQUAL "windows") # A GUI-subsystem executable, so no console window opens; zig's linker wants the flag spelled out. diff --git a/CMakePresets.json b/CMakePresets.json index 0c30f1ecc..b5f29a6a9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -17,38 +17,28 @@ }, { "name": "linux-x86_64", - "displayName": "Linux x86_64", + "displayName": "Linux x86_64 (zig, glibc 2.28, release)", "inherits": "base", "binaryDir": "${sourceDir}/.builddir/linux/x86_64/superbuild", + "toolchainFile": "${sourceDir}/cmake/zig/x86_64-linux-gnu.cmake", + "cacheVariables": { + "SINGE_TRIPLE": "x86_64-linux-gnu", + "SINGE_CROSS_OS": "linux", + "SINGE_SUFFIX": "", + "SINGE_TREE": "linux" + } + }, + { + "name": "linux-x86_64-gcc", + "displayName": "Linux x86_64 (host gcc, developer build)", + "inherits": "base", + "binaryDir": "${sourceDir}/.builddir/linux-gcc/x86_64/superbuild", "toolchainFile": "${sourceDir}/cmake/linux-x86_64.cmake", "cacheVariables": { "SINGE_TRIPLE": "x86_64-linux-gnu", "SINGE_CROSS_OS": "linux", - "SINGE_SUFFIX": "" - } - }, - { - "name": "pi-aarch64", - "displayName": "Raspberry Pi 64-bit", - "inherits": "base", - "binaryDir": "${sourceDir}/.builddir/pi/aarch64/superbuild", - "toolchainFile": "${sourceDir}/../toolchains/cmake/aarch64-rpi3-linux-gnu.cmake", - "cacheVariables": { - "SINGE_TRIPLE": "aarch64-rpi3-linux-gnu", - "SINGE_CROSS_OS": "linux", - "SINGE_SUFFIX": "" - } - }, - { - "name": "macos-aarch64", - "displayName": "macOS Apple silicon", - "inherits": "base", - "binaryDir": "${sourceDir}/.builddir/macos/aarch64/superbuild", - "toolchainFile": "${sourceDir}/../toolchains/cmake/aarch64-apple-darwin22.4.cmake", - "cacheVariables": { - "SINGE_TRIPLE": "aarch64-apple-darwin22.4", - "SINGE_CROSS_OS": "darwin", - "SINGE_SUFFIX": "" + "SINGE_SUFFIX": "-gcc", + "SINGE_TREE": "linux-gcc" } }, { @@ -62,6 +52,30 @@ "SINGE_CROSS_OS": "mingw32", "SINGE_SUFFIX": ".exe" } + }, + { + "name": "pi-aarch64", + "displayName": "Raspberry Pi 64-bit (zig)", + "inherits": "base", + "binaryDir": "${sourceDir}/.builddir/pi/aarch64/superbuild", + "toolchainFile": "${sourceDir}/cmake/zig/aarch64-linux-gnu.cmake", + "cacheVariables": { + "SINGE_TRIPLE": "aarch64-linux-gnu", + "SINGE_CROSS_OS": "linux", + "SINGE_SUFFIX": "" + } + }, + { + "name": "macos-aarch64", + "displayName": "macOS Apple silicon (zig)", + "inherits": "base", + "binaryDir": "${sourceDir}/.builddir/macos/aarch64/superbuild", + "toolchainFile": "${sourceDir}/cmake/zig/aarch64-macos.cmake", + "cacheVariables": { + "SINGE_TRIPLE": "aarch64-apple-darwin22.4", + "SINGE_CROSS_OS": "darwin", + "SINGE_SUFFIX": "" + } } ], "buildPresets": [ @@ -69,6 +83,14 @@ "name": "linux-x86_64", "configurePreset": "linux-x86_64" }, + { + "name": "linux-x86_64-gcc", + "configurePreset": "linux-x86_64-gcc" + }, + { + "name": "windows-x86_64", + "configurePreset": "windows-x86_64" + }, { "name": "pi-aarch64", "configurePreset": "pi-aarch64" @@ -76,10 +98,6 @@ { "name": "macos-aarch64", "configurePreset": "macos-aarch64" - }, - { - "name": "windows-x86_64", - "configurePreset": "windows-x86_64" } ] } diff --git a/INSTALL b/INSTALL index af3eeea35..7003d25d2 100644 --- a/INSTALL +++ b/INSTALL @@ -63,16 +63,41 @@ pkg-config perl nasm imagemagick lua5.4 ffmpeg asciidoctor ruby-asciidoctor-pdf autoconf automake libtool libasound-dev libxi-dev libvdpau-dev libva-dev libdrm-dev libgl-dev libx11-dev. -Cross builds need nothing else installed: +The Linux release build and the Windows build use zig as the compiler: +the build fetches a pinned zig release (version and SHA-256 in +cmake/zig/zig.cmake) into .builddir/toolchains on first use. For Linux it +targets glibc 2.28, so the binary runs on distributions back to Debian 10 +and Ubuntu 18.04 while linking the host's platform libraries (X11, ALSA, +VA-API, VDPAU, DRM); for Windows zig carries the headers and import +libraries itself, so nothing else is installed: ./build-all.sh windows x86_64 -fetches a pinned zig release (version and SHA-256 in cmake/zig/zig.cmake) -into .builddir/toolchains on first use and uses it as the cross compiler; -zig carries the Windows headers and import libraries itself. The Pi and -macOS presets are not yet self-contained; they still expect the toolchains -repository beside this one (see PLAN.md section 17 for the plan to move -them to zig too). +A developer build with the host's own gcc, glibc and symbols is the +linux-x86_64-gcc preset (binary Singe-v3.00-Linux-x86_64-gcc). + +macOS builds with zig too, but needs an Apple SDK for the frameworks, +which Apple's licence does not allow a build script to fetch. Provide it +once as a tarball holding a single MacOSX*.sdk directory: + + .builddir/toolchains/MacOSX.sdk.tar.xz + +On a Mac with Xcode installed, osxcross's tools/gen_sdk_package.sh makes +exactly that tarball from the installed SDK. The build unpacks it to +.builddir/toolchains/MacOSX.sdk on first use. Alternatively point +SINGE_MACOS_SDK at an unpacked SDK, or set SINGE_MACOS_SDK_URL (and +SINGE_MACOS_SDK_SHA256) to have the build fetch the tarball from a +location of your choosing. Then: + + ./build-all.sh macos aarch64 + +The Raspberry Pi build (64-bit Raspberry Pi OS, glibc 2.31 or newer) +also uses zig. The platform headers and libraries it links against are +Debian bookworm arm64 packages listed in cmake/zig/piPackages.cmake, +fetched from snapshot.debian.org and unpacked with dpkg-deb into +.builddir/toolchains/sysroot-aarch64-linux-gnu on first use: + + ./build-all.sh pi aarch64 Useful forms (anything after the platform goes to cmake --build): @@ -83,5 +108,5 @@ Without the wrapper: cmake --preset linux-x86_64 && cmake --build --preset linux-x86_64 -Presets: linux-x86_64, windows-x86_64, pi-aarch64, macos-aarch64 -(CMakePresets.json). +Presets: linux-x86_64, linux-x86_64-gcc, windows-x86_64, pi-aarch64, +macos-aarch64 (CMakePresets.json). diff --git a/build-all.sh b/build-all.sh index a29120ed9..7a9c6cbea 100755 --- a/build-all.sh +++ b/build-all.sh @@ -39,20 +39,8 @@ function buildAll() { local ARCH=$2 shift 2 - # Linux builds with the host compiler and Windows with the zig the build fetches itself. The Pi - # and macOS presets still lean on the toolchains repository beside this one until they move to - # zig as well (PLAN.md section 17). - if [[ "${OS}" == "pi" || "${OS}" == "macos" ]]; then - if [[ ! -x ../toolchains/toolchains.sh ]]; then - echo "error: ${OS} still needs ../toolchains/toolchains.sh" >&2 - exit 1 - fi - source <(../toolchains/toolchains.sh use ${ARCH} ${OS}) - if [[ "${OS}" == "pi" ]]; then - sudo chroot ${SYSROOT} apt-get -y install libasound-dev libxi-dev libvdpau-dev libdrm-dev - fi - fi - + # Every platform builds with the zig the build fetches itself; the Pi preset also fetches its + # platform packages and macOS needs the Apple SDK tarball (see INSTALL). cmake --preset ${OS}-${ARCH} cmake --build --preset ${OS}-${ARCH} "$@" } diff --git a/cmake/Superbuild.cmake b/cmake/Superbuild.cmake index 4889cdd72..4b9325e81 100644 --- a/cmake/Superbuild.cmake +++ b/cmake/Superbuild.cmake @@ -81,7 +81,7 @@ set(SB_PKG_CONFIG_LIBDIR "${SB_PREFIX}/lib/pkgconfig") if(KANGAROO_OS STREQUAL "linux") set(SB_PKG_CONFIG_LIBDIR "${SB_PKG_CONFIG_LIBDIR}:/usr/lib/${SINGE_TRIPLE}/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig") elseif(KANGAROO_OS STREQUAL "pi") - set(SB_PKG_CONFIG_LIBDIR "${SB_PKG_CONFIG_LIBDIR}:${CMAKE_SYSROOT}/usr/lib/${SINGE_TRIPLE}/pkgconfig:${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig") + set(SB_PKG_CONFIG_LIBDIR "${SB_PKG_CONFIG_LIBDIR}:${SINGE_SYSROOT}/usr/lib/${SINGE_TRIPLE}/pkgconfig:${SINGE_SYSROOT}/usr/lib/pkgconfig:${SINGE_SYSROOT}/usr/share/pkgconfig") elseif(DEFINED ENV{PKG_CONFIG_LIBDIR}) set(SB_PKG_CONFIG_LIBDIR "${SB_PKG_CONFIG_LIBDIR}:$ENV{PKG_CONFIG_LIBDIR}") endif() @@ -104,7 +104,7 @@ function(singeStepEnv outVar cflags) list(APPEND env "AR=${CMAKE_AR}") endif() if(KANGAROO_OS STREQUAL "pi") - list(APPEND env "PKG_CONFIG_SYSROOT_DIR=${CMAKE_SYSROOT}") + list(APPEND env "PKG_CONFIG_SYSROOT_DIR=${SINGE_SYSROOT}") endif() set(${outVar} ${env} PARENT_SCOPE) endfunction() @@ -210,6 +210,8 @@ elseif(KANGAROO_OS STREQUAL "macos") else() set(opensslTarget darwin64-x86_64) endif() +elseif(SINGE_ZIG_TARGET) + set(opensslTarget linux-x86_64) else() set(opensslTarget "") endif() @@ -221,13 +223,14 @@ else() set(opensslAsm "") endif() # OpenSSL's Configure derives the source tree from the build directory's position and only -# copes with a build directory nested inside its own tree, so this one lives there. -set(opensslBinary ${SB_THIRDPARTY}/openssl/.builddir) +# copes with a build directory nested inside its own tree, so this one lives there, one per target +# so that switching presets never links another architecture's objects. +set(opensslBinary ${SB_THIRDPARTY}/openssl/.builddir/${KANGAROO_OS}-${KANGAROO_ARCH}) ExternalProject_Add(openssl SOURCE_DIR ${SB_THIRDPARTY}/openssl BINARY_DIR ${opensslBinary} DEPENDS zlib zstd - CONFIGURE_COMMAND ${SB_ENV} perl ../Configure ${opensslTarget} --prefix=${SB_PREFIX} --libdir=lib --with-zlib-include=${SB_PREFIX}/include --with-zlib-lib=${SB_PREFIX}/lib --with-zstd-include=${SB_PREFIX}/include --with-zstd-lib=${SB_PREFIX}/lib ${opensslAsm} no-apps no-docs no-dso no-dynamic-engine no-module no-shared no-tests zlib enable-zstd + CONFIGURE_COMMAND ${SB_ENV} perl ../../Configure ${opensslTarget} --prefix=${SB_PREFIX} --libdir=lib --with-zlib-include=${SB_PREFIX}/include --with-zlib-lib=${SB_PREFIX}/lib --with-zstd-include=${SB_PREFIX}/include --with-zstd-lib=${SB_PREFIX}/lib ${opensslAsm} no-apps no-docs no-dso no-dynamic-engine no-module no-shared no-tests zlib enable-zstd BUILD_COMMAND ${SB_ENV} make build_sw INSTALL_COMMAND ${SB_ENV} make install_sw LOG_CONFIGURE ON LOG_BUILD ON LOG_INSTALL ON LOG_OUTPUT_ON_FAILURE ON @@ -241,8 +244,6 @@ if(KANGAROO_OS STREQUAL "linux") set(hwaccel --enable-vaapi --enable-vdpau --enable-libdrm) elseif(KANGAROO_OS STREQUAL "pi") set(hwaccel --enable-v4l2-m2m --enable-libdrm) - # FFmpeg still includes a header the Pi's libc dropped. - file(WRITE ${SB_PREFIX}/include/sys/sysctl.h "/* File no longer used */\n") elseif(KANGAROO_OS STREQUAL "macos") set(hwaccel --enable-videotoolbox) elseif(KANGAROO_OS STREQUAL "windows") @@ -250,13 +251,22 @@ elseif(KANGAROO_OS STREQUAL "windows") else() set(hwaccel "") endif() -# With a classic cross toolchain every tool is -; with zig each is named outright and -# the host's nm reads the target's objects (binutils understands PE and Mach-O). +# With a classic cross toolchain every tool is -; with zig each is named outright. if(SINGE_ZIG_TARGET) - set(ffmpegTools --enable-cross-compile --cc=${SB_CC} --cxx=${SB_CXX} --ar=${CMAKE_AR} --ranlib=${SB_RANLIB} --nm=nm --windres=${CMAKE_RC_COMPILER}) + set(ffmpegTools --enable-cross-compile --cc=${SB_CC} --cxx=${SB_CXX} --ar=${CMAKE_AR} --ranlib=${SB_RANLIB} --windres=${CMAKE_RC_COMPILER}) + # The host's binutils nm reads x86 ELF and PE objects but not aarch64 or Mach-O ones; FFmpeg only + # uses nm to learn the symbol prefix, which is empty everywhere but macOS, so the others go without. + if(KANGAROO_ARCH STREQUAL "x86_64") + list(APPEND ffmpegTools --nm=nm) + endif() else() set(ffmpegTools --cross-prefix=${SINGE_TRIPLE}- --cc=${SB_CC} --cxx=${SB_CXX} --ranlib=${SB_RANLIB}) endif() +# FFmpeg's configure sees sys/sysctl.h in the Pi sysroot and in zig's glibc header set, then its +# build cannot include it; an empty stand-in satisfies both (Linux uses sysconf, not sysctl). +if((KANGAROO_OS STREQUAL "pi") OR ((KANGAROO_OS STREQUAL "linux") AND SINGE_ZIG_TARGET)) + file(WRITE ${SB_PREFIX}/include/sys/sysctl.h "/* File no longer used */\n") +endif() set(ffmpegBinary ${SB_PREFIX}/build/ffmpeg) ExternalProject_Add(ffmpeg SOURCE_DIR ${SB_THIRDPARTY}/ffmpeg @@ -274,15 +284,18 @@ singeRebuildTarget(ffmpeg) string(SUBSTRING ${KANGAROO_OS} 0 1 osInitial) string(SUBSTRING ${KANGAROO_OS} 1 -1 osRest) string(TOUPPER ${osInitial} osInitial) -set(singeBinaryName "Singe-v${PROJECT_VERSION}-${osInitial}${osRest}-${KANGAROO_ARCH}${SINGE_SUFFIX}") +# The built file carries the platform's executable suffix; the copy in .builddir/ carries the +# preset's, which is the same thing for Windows and lets an experimental build live beside another. +set(singeBinaryBase "Singe-v${PROJECT_VERSION}-${osInitial}${osRest}-${KANGAROO_ARCH}") +set(singeBinaryName "${singeBinaryBase}${SINGE_SUFFIX}") set(singeBinary ${SB_PREFIX}/singe) ExternalProject_Add(singe SOURCE_DIR ${CMAKE_SOURCE_DIR} BINARY_DIR ${singeBinary} DEPENDS zlib zstd SDL3 SDL3_image SDL3_mixer SDL3_ttf openssl ffmpeg - CONFIGURE_COMMAND ${SB_ENV} ${CMAKE_COMMAND} -S ${CMAKE_SOURCE_DIR} -B ${singeBinary} ${SB_CMAKE_ARGS} -DSINGE_SUPERBUILD=OFF -DKANGAROO_OS=${KANGAROO_OS} -DKANGAROO_ARCH=${KANGAROO_ARCH} + CONFIGURE_COMMAND ${SB_ENV} ${CMAKE_COMMAND} -S ${CMAKE_SOURCE_DIR} -B ${singeBinary} ${SB_CMAKE_ARGS} -DSINGE_SUPERBUILD=OFF -DKANGAROO_OS=${KANGAROO_OS} -DKANGAROO_ARCH=${KANGAROO_ARCH} -DSINGE_TREE=${SINGE_TREE} BUILD_COMMAND ${SB_ENV} ${CMAKE_COMMAND} --build ${singeBinary} --parallel ${SB_JOBS} - INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${singeBinary}/${singeBinaryName} ${CMAKE_SOURCE_DIR}/.builddir/${singeBinaryName} + INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${singeBinary}/${singeBinaryBase}${CMAKE_EXECUTABLE_SUFFIX} ${CMAKE_SOURCE_DIR}/.builddir/${singeBinaryName} BUILD_ALWAYS ON ) diff --git a/cmake/zig/aarch64-linux-gnu.cmake b/cmake/zig/aarch64-linux-gnu.cmake new file mode 100644 index 000000000..4c9a5f858 --- /dev/null +++ b/cmake/zig/aarch64-linux-gnu.cmake @@ -0,0 +1,93 @@ +# +# Singe 3 +# Copyright (C) 2006-2026 Scott Duensing +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public Licens +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# Raspberry Pi (64-bit Raspberry Pi OS) with zig as the compiler. zig supplies glibc pinned to the +# version below plus the kernel headers; the platform libraries Singe, SDL3 and FFmpeg build against +# (libdrm, ALSA, X11, GBM/EGL/GLES, udev, ...) come from the Debian packages listed in +# piPackages.cmake, downloaded and unpacked into a sysroot under .builddir/toolchains on first use. +# Nothing outside the source tree is touched; dpkg-deb from the host does the unpacking. + +include(${CMAKE_CURRENT_LIST_DIR}/zig.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/piPackages.cmake) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +# Raspberry Pi OS bullseye shipped glibc 2.31; a binary built against it runs there and on everything since. +set(SINGE_GLIBC_VERSION 2.31) + +get_filename_component(piToolchains ${CMAKE_CURRENT_LIST_DIR}/../../.builddir/toolchains ABSOLUTE) +set(SINGE_SYSROOT ${piToolchains}/sysroot-aarch64-linux-gnu CACHE PATH "Pi platform headers and libraries" FORCE) +set(piDebs ${piToolchains}/debs-aarch64-linux-gnu) +set(piStamp ${SINGE_SYSROOT}/.complete) + +# The stamp holds the manifest that built the sysroot; a changed manifest rebuilds it. +string(SHA256 piManifest "${piPackages}") +set(piHave "") +if(EXISTS ${piStamp}) + file(READ ${piStamp} piHave) + string(STRIP "${piHave}" piHave) +endif() +if(NOT piHave STREQUAL piManifest) + find_program(SINGE_DPKG_DEB dpkg-deb) + if(NOT SINGE_DPKG_DEB) + message(FATAL_ERROR "dpkg-deb is needed to unpack the Pi sysroot packages (apt-get install dpkg).") + endif() + message(STATUS "Building the Pi sysroot in ${SINGE_SYSROOT}") + file(REMOVE_RECURSE ${SINGE_SYSROOT}) + file(MAKE_DIRECTORY ${SINGE_SYSROOT} ${piDebs}) + foreach(entry IN LISTS piPackages) + string(REGEX MATCH "^([^|]*)\\|(.*)$" unused "${entry}") + set(url ${CMAKE_MATCH_1}) + set(sha ${CMAKE_MATCH_2}) + get_filename_component(deb ${url} NAME) + set(debPath ${piDebs}/${deb}) + if(NOT EXISTS ${debPath}) + message(STATUS "Downloading ${deb}") + file(DOWNLOAD ${url} ${debPath} EXPECTED_HASH SHA256=${sha} STATUS status) + list(GET status 0 code) + if(NOT code EQUAL 0) + file(REMOVE ${debPath}) + message(FATAL_ERROR "Download of ${url} failed: ${status}") + endif() + endif() + execute_process(COMMAND ${SINGE_DPKG_DEB} -x ${debPath} ${SINGE_SYSROOT} RESULT_VARIABLE code) + if(NOT code EQUAL 0) + message(FATAL_ERROR "Unpacking ${deb} failed.") + endif() + endforeach() + file(WRITE ${piStamp} "${piManifest}\n") +endif() + +# The sysroot's headers come after zig's own; its libraries are linked by name and left unresolved +# at link time (they are only stubs for what the Pi provides at run time). +set(piLibs ${SINGE_SYSROOT}/usr/lib/aarch64-linux-gnu) +singeZigToolchain(aarch64-linux-gnu.${SINGE_GLIBC_VERSION} "-idirafter ${SINGE_SYSROOT}/usr/include/aarch64-linux-gnu -idirafter ${SINGE_SYSROOT}/usr/include -L${piLibs} -L${SINGE_SYSROOT}/lib/aarch64-linux-gnu -Wl,--allow-shlib-undefined") + +# find_package and pkg-config look only in the sysroot; programs come from the host. +set(CMAKE_FIND_ROOT_PATH ${SINGE_SYSROOT}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu CACHE STRING "" FORCE) +set(CMAKE_C_LIBRARY_ARCHITECTURE aarch64-linux-gnu CACHE STRING "" FORCE) +set(CMAKE_LIBRARY_PATH ${piLibs} CACHE PATH "" FORCE) +set(KANGAROO_OS pi) +set(KANGAROO_ARCH aarch64) diff --git a/cmake/zig/aarch64-macos.cmake b/cmake/zig/aarch64-macos.cmake new file mode 100644 index 000000000..57eeab5f1 --- /dev/null +++ b/cmake/zig/aarch64-macos.cmake @@ -0,0 +1,81 @@ +# +# Singe 3 +# Copyright (C) 2006-2026 Scott Duensing +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public Licens +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# macOS on Apple silicon with zig as the compiler. zig carries the macOS libc headers and the +# libSystem stub itself; everything else (Cocoa, CoreAudio, VideoToolbox, Metal and the rest of +# the frameworks, libc++, libiconv) comes from an Apple SDK, which Apple does not let a build +# script fetch. The SDK is expected, in this order: +# 1. an unpacked SDK at SINGE_MACOS_SDK (default .builddir/toolchains/MacOSX.sdk); +# 2. a tarball at .builddir/toolchains/MacOSX.sdk.tar.xz, unpacked on first use; +# 3. SINGE_MACOS_SDK_URL (with SINGE_MACOS_SDK_SHA256), downloaded and unpacked on first use. +# See INSTALL for how to make the tarball from Xcode. + +include(${CMAKE_CURRENT_LIST_DIR}/zig.cmake) + +set(CMAKE_SYSTEM_NAME Darwin) +set(CMAKE_SYSTEM_PROCESSOR arm64) + +get_filename_component(sdkToolchains ${CMAKE_CURRENT_LIST_DIR}/../../.builddir/toolchains ABSOLUTE) +set(SINGE_MACOS_SDK ${sdkToolchains}/MacOSX.sdk CACHE PATH "Unpacked Apple SDK for the macOS build") +set(SINGE_MACOS_SDK_URL "" CACHE STRING "Where to fetch the Apple SDK tarball from, if anywhere") +set(SINGE_MACOS_SDK_SHA256 "" CACHE STRING "SHA-256 of that tarball") +set(sdkTarball ${sdkToolchains}/MacOSX.sdk.tar.xz) +if(NOT EXISTS ${SINGE_MACOS_SDK}/System/Library/Frameworks/Cocoa.framework) + if((NOT EXISTS ${sdkTarball}) AND SINGE_MACOS_SDK_URL) + message(STATUS "Downloading the Apple SDK from ${SINGE_MACOS_SDK_URL}") + file(MAKE_DIRECTORY ${sdkToolchains}) + if(SINGE_MACOS_SDK_SHA256) + file(DOWNLOAD ${SINGE_MACOS_SDK_URL} ${sdkTarball} EXPECTED_HASH SHA256=${SINGE_MACOS_SDK_SHA256} STATUS status) + else() + file(DOWNLOAD ${SINGE_MACOS_SDK_URL} ${sdkTarball} STATUS status) + endif() + list(GET status 0 code) + if(NOT code EQUAL 0) + message(FATAL_ERROR "Apple SDK download failed: ${status}") + endif() + endif() + if(EXISTS ${sdkTarball}) + message(STATUS "Unpacking ${sdkTarball}") + set(sdkUnpack ${sdkToolchains}/MacOSX.sdk.unpack) + file(REMOVE_RECURSE ${sdkUnpack}) + file(ARCHIVE_EXTRACT INPUT ${sdkTarball} DESTINATION ${sdkUnpack}) + file(GLOB sdkFound LIST_DIRECTORIES true ${sdkUnpack}/*.sdk ${sdkUnpack}/*/*.sdk) + list(LENGTH sdkFound sdkCount) + if(NOT sdkCount EQUAL 1) + message(FATAL_ERROR "${sdkTarball} should hold exactly one MacOSX*.sdk directory; found ${sdkCount}.") + endif() + file(RENAME ${sdkFound} ${SINGE_MACOS_SDK}) + file(REMOVE_RECURSE ${sdkUnpack}) + endif() +endif() +if(NOT EXISTS ${SINGE_MACOS_SDK}/System/Library/Frameworks/Cocoa.framework) + message(FATAL_ERROR "No Apple SDK at ${SINGE_MACOS_SDK}. Put an SDK tarball at ${sdkTarball} (see INSTALL), or set SINGE_MACOS_SDK to an unpacked SDK, or SINGE_MACOS_SDK_URL to fetch one.") +endif() + +# The SDK's headers come after zig's own libc headers; frameworks and stub libraries from the SDK. +singeZigToolchain(aarch64-macos "--sysroot=${SINGE_MACOS_SDK} -idirafter ${SINGE_MACOS_SDK}/usr/include -F${SINGE_MACOS_SDK}/System/Library/Frameworks -L${SINGE_MACOS_SDK}/usr/lib") +set(CMAKE_OSX_SYSROOT ${SINGE_MACOS_SDK} CACHE PATH "Apple SDK" FORCE) +set(CMAKE_OSX_ARCHITECTURES "" CACHE STRING "Left empty; the zig target names the architecture" FORCE) +set(CMAKE_FIND_ROOT_PATH ${SINGE_MACOS_SDK}) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) +set(KANGAROO_OS macos) +set(KANGAROO_ARCH aarch64) diff --git a/cmake/zig/piPackages.cmake b/cmake/zig/piPackages.cmake new file mode 100644 index 000000000..44be12974 --- /dev/null +++ b/cmake/zig/piPackages.cmake @@ -0,0 +1,78 @@ +# Debian bookworm arm64 packages that give the Pi build its platform headers and stub libraries +# (libdrm, ALSA, X11, GBM/EGL/GLES, udev, dbus, Wayland, PulseAudio). zig supplies libc and the +# kernel headers itself, so no libc6 package is here. Every line is a permanent snapshot.debian.org +# URL and the SHA-256 Debian publishes for it; regenerate against a newer snapshot when needed. +# Format: one "url|sha256" pair per list element. + +set(piPackagesSnapshot "https://snapshot.debian.org/archive/debian/20250901T000000Z") +set(piPackages + "${piPackagesSnapshot}/pool/main/libd/libdrm/libdrm-dev_2.4.114-1+b1_arm64.deb|26d7d0dcbbda8ed023b57989e0fca7f0ff8372daaf654daf8b3a362557be5e21" + "${piPackagesSnapshot}/pool/main/libd/libdrm/libdrm2_2.4.114-1+b1_arm64.deb|f5f15a46d02cf5d9fa52d4f1c54b8cf80c398711ad771a9938b12399b8d8090c" + "${piPackagesSnapshot}/pool/main/libd/libdrm/libdrm-amdgpu1_2.4.114-1+b1_arm64.deb|24692e933b98b2b8b80d87c45728efa2bc7176120ce9efcb8793407e508b5a32" + "${piPackagesSnapshot}/pool/main/libd/libdrm/libdrm-nouveau2_2.4.114-1+b1_arm64.deb|2acf0db609e8569dd89eea5f3e6f27968de50474d31213665901ad1c6d1133de" + "${piPackagesSnapshot}/pool/main/libd/libdrm/libdrm-radeon1_2.4.114-1+b1_arm64.deb|e53c2b4be53b4a8e6413887525c9172bdc95ed3a140a52ce23d6e1a68789aaa0" + "${piPackagesSnapshot}/pool/main/a/alsa-lib/libasound2-dev_1.2.8-1+b1_arm64.deb|263668e5ce831d3a8426bd342beba7e94925e893a4a5a285252b8f3ed6b3f5ee" + "${piPackagesSnapshot}/pool/main/a/alsa-lib/libasound2_1.2.8-1+b1_arm64.deb|9fa889400fcee4b92c8f4a2fafbb7f2cd33444d9ec1665a71002ab67c06114bb" + "${piPackagesSnapshot}/pool/main/a/alsa-lib/libasound2-data_1.2.8-1_all.deb|fe0780d2d3674b2977e0acb0d48b448ad72ba1642564b7dc537f55e839984c2d" + "${piPackagesSnapshot}/pool/main/libx/libx11/libx11-dev_1.8.4-2+deb12u2_arm64.deb|34bfc833561de983cfb4475523fedc13abb4faee14a876300de659591779add8" + "${piPackagesSnapshot}/pool/main/libx/libx11/libx11-6_1.8.4-2+deb12u2_arm64.deb|d1d533e983582282a9ea82c87ac5ce715a9b67bd6d1acbd2439a11c63c36549b" + "${piPackagesSnapshot}/pool/main/libx/libxcb/libxcb1-dev_1.15-1_arm64.deb|87b5c3f1bb130727df68295ecfaadc305ee10c150afeb1a183e95b9150e18db5" + "${piPackagesSnapshot}/pool/main/libx/libxcb/libxcb1_1.15-1_arm64.deb|041d9a68415c3ccf3ce8f4f8b88e4bbfb5dc1f0d97013c6ef8423e620ea50f84" + "${piPackagesSnapshot}/pool/main/libx/libxau/libxau-dev_1.0.9-1_arm64.deb|21db3761a8f388fc83707c00fac645d4332737a859dd727571e1e6ede003b048" + "${piPackagesSnapshot}/pool/main/libx/libxau/libxau6_1.0.9-1_arm64.deb|36c2bf400641a80521093771dc2562c903df4065f9eb03add50d90564337ea6c" + "${piPackagesSnapshot}/pool/main/libx/libxdmcp/libxdmcp-dev_1.1.2-3_arm64.deb|6fd0bc51f3a4e6b7f944f24f15524a4c4ba68a4b0aa136c18bdb96a2d36988f2" + "${piPackagesSnapshot}/pool/main/libx/libxdmcp/libxdmcp6_1.1.2-3_arm64.deb|e92569ac33247261aa09adfadc34ced3994ac301cf8b58de415a2d5dbf15ccfc" + "${piPackagesSnapshot}/pool/main/x/xorgproto/x11proto-dev_2022.1-1_all.deb|3cab66a6591774188a568f9b54c4e7956f18da76e0e0fc4a779db5f6bcc3f148" + "${piPackagesSnapshot}/pool/main/x/xorg-sgml-doctools/xorg-sgml-doctools_1.11-1.1_all.deb|168345058319094e475a87ace66f5fb6ae802109650ea8434d672117982b5d0a" + "${piPackagesSnapshot}/pool/main/libx/libxext/libxext-dev_1.3.4-1+b1_arm64.deb|07f5e3efeba9564071885b2d0d2ba277692fa309a9f05ef862688af0022b1fcf" + "${piPackagesSnapshot}/pool/main/libx/libxext/libxext6_1.3.4-1+b1_arm64.deb|5e9c0ad606eb4674c645fe8e0e64330c47d2729f7a59ed569848610efd5d5b62" + "${piPackagesSnapshot}/pool/main/libx/libxi/libxi-dev_1.8-1+b1_arm64.deb|4a5e7bc3b4e55c23281b2e500b572a61ae8869b1bc03fe14b4ae5a4c9e3c295c" + "${piPackagesSnapshot}/pool/main/libx/libxi/libxi6_1.8-1+b1_arm64.deb|b26383c9929d8bfba051eee22301e064d17039ed022bbf31990feb0d7a03b36c" + "${piPackagesSnapshot}/pool/main/libx/libxfixes/libxfixes-dev_6.0.0-2_arm64.deb|25266e1bd10c7624210abf3aa3eb85e3886b6c8c08b2ecc396b8a04f24c10082" + "${piPackagesSnapshot}/pool/main/libx/libxfixes/libxfixes3_6.0.0-2_arm64.deb|d47bda8fed01b19b41d503e2df05d9166c58e30e2376f2f8784ceb7a834befe6" + "${piPackagesSnapshot}/pool/main/libx/libxrandr/libxrandr-dev_1.5.2-2+b1_arm64.deb|f951a3813c525bc950e21e801837dfe447bdbef4d2610eddbd833d7d41f92c7c" + "${piPackagesSnapshot}/pool/main/libx/libxrandr/libxrandr2_1.5.2-2+b1_arm64.deb|f0bc7f79fee182caae176652fdb1bf349d13b9591b10ad4dc1c896521da8e49f" + "${piPackagesSnapshot}/pool/main/libx/libxrender/libxrender-dev_0.9.10-1.1_arm64.deb|26a3ef50910cae3422c20af90a4a4deb85e7da3680c9192e50efc01b7e1b2f8f" + "${piPackagesSnapshot}/pool/main/libx/libxrender/libxrender1_0.9.10-1.1_arm64.deb|f260193deb4eaf0b410a1c61e1f84804366ee3372b8bad9f38005f7dbcd89aae" + "${piPackagesSnapshot}/pool/main/libx/libxcursor/libxcursor-dev_1.2.1-1_arm64.deb|5d0a0e62fcb202d9afc08c95d6b44e28211e63a6f0763e05741561ac2580aaa1" + "${piPackagesSnapshot}/pool/main/libx/libxcursor/libxcursor1_1.2.1-1_arm64.deb|a93dd172bdd940de4ac6fd2b7a3f0213604c975f9f2f51eb3013f50886aaa87c" + "${piPackagesSnapshot}/pool/main/libx/libxtst/libxtst-dev_1.2.3-1.1_arm64.deb|4e205710dd04f9e9ee360da0161c155be01086e36462fead392b707b3857b4f2" + "${piPackagesSnapshot}/pool/main/libx/libxtst/libxtst6_1.2.3-1.1_arm64.deb|ef2a1b9ac3f2620d96e17744e41c4eefb7f491eee3bcc5bc1e592180b2d94128" + "${piPackagesSnapshot}/pool/main/libx/libxss/libxss-dev_1.2.3-1_arm64.deb|970b39c57df5c1307f905c6dd89967d548e9e2711a2099241de7b8e8831e40ca" + "${piPackagesSnapshot}/pool/main/libx/libxss/libxss1_1.2.3-1_arm64.deb|e0ff80e309eacda5face68b9a3bd56718fed2750af429324c35d7c9491c335f4" + "${piPackagesSnapshot}/pool/main/libx/libxinerama/libxinerama-dev_1.1.4-3_arm64.deb|64c758aef152615d99bceead07c86b03f3737dca190230b5dde1d79403288341" + "${piPackagesSnapshot}/pool/main/libx/libxinerama/libxinerama1_1.1.4-3_arm64.deb|1dc5f458f6b3245b1b128897f905717d3cf7777a5697577b246042e25311d0df" + "${piPackagesSnapshot}/pool/main/libx/libxkbcommon/libxkbcommon-dev_1.5.0-1_arm64.deb|7d39b34b202fe58e18992b439c79c149ebb1b821b58dfb863ff4898e06420699" + "${piPackagesSnapshot}/pool/main/libx/libxkbcommon/libxkbcommon0_1.5.0-1_arm64.deb|ec518d8a19796a399ab95e7bc4dfbb6bd2ed8e151f77b222df26208db412d852" + "${piPackagesSnapshot}/pool/main/m/mesa/libgbm-dev_22.3.6-1+deb12u1_arm64.deb|ba3f413f6f428b45e21d93fc5eb213bbc31ca1c15a7b265da3700100fd2475c8" + "${piPackagesSnapshot}/pool/main/m/mesa/libgbm1_22.3.6-1+deb12u1_arm64.deb|c76790e11aac46e328b6a13b34cccd3ef01fad79cfe80d2c4aa2384ac9ddb1f8" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libegl-dev_1.6.0-1_arm64.deb|8a3004f892785a5fa4c9f969c116f567a36d1c8e9b3d5fd0403055151e36c7d3" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libegl1_1.6.0-1_arm64.deb|707097a275155c600e2e9251c4ee7cdfdb2d8f50a678a850a2526a7bc9664166" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libgles-dev_1.6.0-1_arm64.deb|941e9963d64479544691f7183fe0eeae32b53b633df71c4c51263517ab2ea8f3" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libgles2_1.6.0-1_arm64.deb|efeb2717380f8411d66b3f669bb99bbd83ff09db3d4a1661533aa31af659608c" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libgl-dev_1.6.0-1_arm64.deb|56add9e710c072cf56504beed50a639f9f7c64f4e31e66958fa65a566084888c" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libgl1_1.6.0-1_arm64.deb|f4043ab47f52325973d2b608514b3469b055b65c744861c7f378755a32e799d6" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libglvnd-dev_1.6.0-1_arm64.deb|86cba4e243d10ae07cc6e769f23ecd097b2f87b722dc5ac48a48a3794cd29513" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libglvnd0_1.6.0-1_arm64.deb|d5063205fab5322ee686f33f87c6315b3fcd1335ea4e7bc8202b48ed4f9c9e83" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libglx-dev_1.6.0-1_arm64.deb|f3d6fca16c259743208df6f845aee3189eb54fed00e159811135089c16d0ad9c" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libglx0_1.6.0-1_arm64.deb|523f9b71f75e48ae605d8ef298a4b03ade26ade9a808a85329a3bd82a54b9b0d" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libopengl0_1.6.0-1_arm64.deb|4b3c6b3bc25530290cf231acac4c85b8806dda53ab6376ab22b3ec511b4fb7a0" + "${piPackagesSnapshot}/pool/main/libg/libglvnd/libopengl-dev_1.6.0-1_arm64.deb|b4ddc2d38103e9f0c3637d46334ccbf40c30e851c85f5348abc0aa37e3926822" + "${piPackagesSnapshot}/pool/main/s/systemd/libudev-dev_252.36-1~deb12u1_arm64.deb|62760a9e8fb87c2827333163efadc36c5ae66be59af18e7286d19813b8a72e03" + "${piPackagesSnapshot}/pool/main/s/systemd/libudev1_252.36-1~deb12u1_arm64.deb|5abfa6d6960f1b6a19c3d35373958d47a3a2f1221a5fe4652143fea0e0adc2ab" + "${piPackagesSnapshot}/pool/main/d/dbus/libdbus-1-dev_1.14.10-1~deb12u1_arm64.deb|817caa440feee88d53dd74432ce633af8d351552cd71014bcc8c98380c9ed88c" + "${piPackagesSnapshot}/pool/main/d/dbus/libdbus-1-3_1.14.10-1~deb12u1_arm64.deb|2a423794f44ee756f70fda67c6e47b15afe3dd22cd69e51f5d14d2ec9538f806" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-dev_1.21.0-1_arm64.deb|932405c58195d299495230792e374ad304adadf3d3ffdc07eda3466b756adc33" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-client0_1.21.0-1_arm64.deb|ae390cc04c2eb1de90b9a6373505b22c730ada5e72daa50c507b7f99c12faf06" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-egl1_1.21.0-1_arm64.deb|c08124a4d9af24f058b45c88867a84697882e755ea94965795d152fe26fe57c9" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-cursor0_1.21.0-1_arm64.deb|8c8d1a3942bc3fc9dd3ea7c679c1a314e59cdaaa700883d54d1bb3ec89db256b" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-server0_1.21.0-1_arm64.deb|4d99e7e0503fdaa999e67d47d8612c0465e775eafa47819573da50bdb09064f2" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-bin_1.21.0-1_arm64.deb|02e9361617b43b130ff032873a910258884160c169e89a1ca45d34d1150a2615" + "${piPackagesSnapshot}/pool/main/libd/libdecor-0/libdecor-0-dev_0.1.1-2_arm64.deb|e52fbcbbf6e755be2c642fcecc6154d9d071978d0797e7cf9ccf93d131bf4fc6" + "${piPackagesSnapshot}/pool/main/libd/libdecor-0/libdecor-0-0_0.1.1-2_arm64.deb|e88d3c2dd3336a97b8cf10ef270a264388fce81cedf8032b18f2a36b021bc6a3" + "${piPackagesSnapshot}/pool/main/p/pulseaudio/libpulse-dev_16.1+dfsg1-2+b1_arm64.deb|dac8f94dc214a77654cc62d0f1611cd4dee9cdefdc816e3056dd9fae5aa5d4a8" + "${piPackagesSnapshot}/pool/main/p/pulseaudio/libpulse0_16.1+dfsg1-2+b1_arm64.deb|26f17e3457c5fce0104a6b2f0efb75a3256b24b32ca7cfda6266373758a930cb" + "${piPackagesSnapshot}/pool/main/w/wayland/libwayland-egl-backend-dev_1.21.0-1_arm64.deb|0974da94059371e67e93d61398853c9967d0cc34cd7745b6d47d3aa47b88815d" + "${piPackagesSnapshot}/pool/main/libf/libffi/libffi-dev_3.4.4-1_arm64.deb|8ff6335f76752ef8659762435d0d88129ef0090a587520853238809bd10ef392" + "${piPackagesSnapshot}/pool/main/libf/libffi/libffi8_3.4.4-1_arm64.deb|80b5c36177dc0e29d531c7eddbed3cc7355cb490e49f8cfa5959572d161f27b3" +) diff --git a/cmake/zig/x86_64-linux-gnu.cmake b/cmake/zig/x86_64-linux-gnu.cmake new file mode 100644 index 000000000..3cebfa7c4 --- /dev/null +++ b/cmake/zig/x86_64-linux-gnu.cmake @@ -0,0 +1,59 @@ +# +# Singe 3 +# Copyright (C) 2006-2026 Scott Duensing +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public Licens +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. +# + +# Linux x86_64 with zig as the compiler, targeting glibc 2.28 (Debian 10, Ubuntu 18.04) so one +# release binary runs on more distributions than the build host's own glibc allows. zig supplies +# libc and its headers; the platform libraries (ALSA, X11, DRM, VA-API, VDPAU, GL) and their +# headers come from the host's development packages, searched after zig's own so the host's +# newer glibc headers never shadow the pinned ones. + +include(${CMAKE_CURRENT_LIST_DIR}/zig.cmake) + +set(SINGE_GLIBC_VERSION 2.28) +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +# The linker may see the host's platform libraries but never its libc, libm, libpthread or gcc +# runtime, or symbols get bound to the host's newer glibc versions. A directory of links to +# everything else under the host's library directory keeps the two apart. +set(hostLibs ${CMAKE_BINARY_DIR}/hostlibs) +file(MAKE_DIRECTORY ${hostLibs}) +file(GLOB hostSharedLibs /usr/lib/x86_64-linux-gnu/lib*.so) +foreach(lib ${hostSharedLibs}) + get_filename_component(name ${lib} NAME) + if(NOT name MATCHES "^lib(c|m|dl|pthread|rt|resolv|util|anl|nsl|crypt|gcc_s|stdc\\+\\+|BrokenLocale|mvec|memusage|pcprofile|SegFault|thread_db|c_malloc_debug|asan|ubsan|tsan|lsan|atomic|gomp|itm|quadmath)\\.so$") + if(NOT EXISTS ${hostLibs}/${name}) + file(CREATE_LINK ${lib} ${hostLibs}/${name} SYMBOLIC) + endif() + endif() +endforeach() + +# --allow-shlib-undefined: the host's platform libraries reference its newer glibc; at link time only +# their symbols matter, and the machine that runs the binary brings its own copies. +singeZigToolchain(x86_64-linux-gnu.${SINGE_GLIBC_VERSION} "-idirafter /usr/include/x86_64-linux-gnu -idirafter /usr/include -L${hostLibs} -Wl,--allow-shlib-undefined") +# No find-root restrictions: the host's development packages are the platform packages here, so +# SDL3 must find X11, Wayland, ALSA and the rest where they are. CMake learns the Debian multiarch +# library directory from gcc, not from a clang-style compiler, and its compiler detection overwrites +# a plain variable, so the settings are forced into the cache or FindX11 never sees libX11. +set(CMAKE_LIBRARY_ARCHITECTURE x86_64-linux-gnu CACHE STRING "Debian multiarch library directory name" FORCE) +set(CMAKE_C_LIBRARY_ARCHITECTURE x86_64-linux-gnu CACHE STRING "Debian multiarch library directory name" FORCE) +set(CMAKE_LIBRARY_PATH /usr/lib/x86_64-linux-gnu CACHE PATH "Where the host platform libraries live" FORCE) +set(KANGAROO_OS linux) +set(KANGAROO_ARCH x86_64) diff --git a/cmake/zig/x86_64-windows-gnu.cmake b/cmake/zig/x86_64-windows-gnu.cmake index 85ebe869e..e394241b8 100644 --- a/cmake/zig/x86_64-windows-gnu.cmake +++ b/cmake/zig/x86_64-windows-gnu.cmake @@ -25,7 +25,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/zig.cmake) set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_PROCESSOR x86_64) -singeZigToolchain(x86_64-windows-gnu) +singeZigToolchain(x86_64-windows-gnu "") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/cmake/zig/zig.cmake b/cmake/zig/zig.cmake index acb879356..10d9202d9 100644 --- a/cmake/zig/zig.cmake +++ b/cmake/zig/zig.cmake @@ -45,8 +45,9 @@ if(NOT EXISTS ${ZIG_EXECUTABLE}) endif() endif() -# Writes the wrapper scripts for a target into the build tree and points CMake at them. -function(singeZigToolchain target) +# Writes the wrapper scripts for a target into the build tree and points CMake at them. extra is +# appended to every compiler invocation (a target's include and library directories). +function(singeZigToolchain target extra) set(dir ${CMAKE_BINARY_DIR}/zig-${target}) file(MAKE_DIRECTORY ${dir}) # The compiler wrappers drop one flag: FFmpeg's configure adds binutils' --pic-executable ASLR @@ -54,10 +55,12 @@ function(singeZigToolchain target) set(filter "for a in \"$@\"; do [[ $a == -Wl,--pic-executable* ]] || args+=(\"$a\"); done") # -fno-sanitize=undefined: zig cc instruments for UBSan by default and expects its runtime at # link time; a release build wants neither. - foreach(tool "cc;-target ${target} -fno-sanitize=undefined" "c++;-target ${target} -fno-sanitize=undefined" "ar;" "ranlib;" "rc;") + # extra goes after the caller's arguments so the caller's -L directories are searched first. + foreach(tool "cc;-target ${target} -fno-sanitize=undefined;${extra}" "c++;-target ${target} -fno-sanitize=undefined;${extra}" "ar;;" "ranlib;;" "rc;;") list(GET tool 0 name) list(GET tool 1 args) - file(WRITE ${dir}/zig-${name} "#!/bin/bash\nargs=()\n${filter}\nexec \"${ZIG_EXECUTABLE}\" ${name} ${args} \"$\{args[@]}\"\n") + list(GET tool 2 after) + file(WRITE ${dir}/zig-${name} "#!/bin/bash\nargs=()\n${filter}\nexec \"${ZIG_EXECUTABLE}\" ${name} ${args} \"$\{args[@]}\" ${after}\n") file(CHMOD ${dir}/zig-${name} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) endforeach() set(CMAKE_C_COMPILER ${dir}/zig-cc CACHE FILEPATH "C compiler" FORCE)