diff --git a/Dockerfile.appleembedded b/Dockerfile.appleembedded new file mode 100644 index 0000000..8befeb1 --- /dev/null +++ b/Dockerfile.appleembedded @@ -0,0 +1,54 @@ +ARG img_version +FROM godot-osx:${img_version} + +RUN dnf -y install --setopt=install_weak_deps=False \ + automake autoconf gcc gcc-c++ gcc-objc gcc-objc++ cmake libicu-devel libtool libxml2-devel openssl-devel perl python yasm + +ENV IOS_SDK=18.5 +ENV TVOS_SDK=18.5 +ENV XROS_SDK=2.5 + +# Extract the SDKs for iOS, tvOS and XROS, including the simulator SDKs +# into separate layers, so this work is not repeated each time the image is built. +RUN mkdir -p /root/SDKs +RUN cd /root/SDKs && tar xf /root/files/iPhoneOS${IOS_SDK}.sdk.tar.xz +RUN cd /root/SDKs && tar xf /root/files/iPhoneSimulator${IOS_SDK}.sdk.tar.xz +RUN cd /root/SDKs && tar xf /root/files/AppleTVOS${TVOS_SDK}.sdk.tar.xz +RUN cd /root/SDKs && tar xf /root/files/AppleTVSimulator${TVOS_SDK}.sdk.tar.xz +RUN cd /root/SDKs && tar xf /root/files/XROS${XROS_SDK}.sdk.tar.xz +RUN cd /root/SDKs && tar xf /root/files/XRSimulator${XROS_SDK}.sdk.tar.xz + +RUN git clone --depth 1 --no-checkout https://github.com/tpoechtrager/cctools-port.git && \ + cd /root/cctools-port && \ + git fetch --depth 1 origin 7224fd5c9390ea15cff6ee69ff92ea677b40014b && \ + git checkout 7224fd5c9390ea15cff6ee69ff92ea677b40014b + +COPY files/appleembedded/build.sh /root/cctools-port/usage_examples/ios_toolchain/build.sh +COPY files/appleembedded/wrapper.c /root/cctools-port/usage_examples/ios_toolchain/wrapper.c + +RUN chmod +x /root/cctools-port/usage_examples/ios_toolchain/build.sh + +RUN cd /root/cctools-port && \ + usage_examples/ios_toolchain/build.sh arm64 && \ + mkdir -p /root/ioscross/arm64 && \ + mv usage_examples/ios_toolchain/target/* /root/ioscross/arm64 && \ + mkdir /root/ioscross/arm64/usr && \ + ln -s /root/ioscross/arm64/bin /root/ioscross/arm64/usr/bin + +RUN cd /root/cctools-port && \ + usage_examples/ios_toolchain/build.sh x86_64 && \ + mkdir -p /root/ioscross/x86_64 && \ + mv usage_examples/ios_toolchain/target/* /root/ioscross/x86_64 && \ + mkdir /root/ioscross/x86_64/usr && \ + ln -s /root/ioscross/x86_64/bin /root/ioscross/x86_64/usr/bin + +RUN PATH=/root/ioscross/arm64/bin:$PATH /root/files/appleembedded/check-arm.sh + +ENV OSXCROSS_IOS=not_nothing +ENV OSXCROSS_TVOS=not_nothing +ENV OSXCROSS_VISIONOS=not_nothing +ENV OSXCROSS_APPLEEMBEDDED=not_nothing + +ENV PATH="/root/ioscross/arm64/bin:/root/ioscross/x86_64/bin:${PATH}" + +CMD /bin/bash diff --git a/Dockerfile.ios b/Dockerfile.ios deleted file mode 100644 index 6b3dcd9..0000000 --- a/Dockerfile.ios +++ /dev/null @@ -1,39 +0,0 @@ -ARG img_version -FROM godot-osx:${img_version} - -ENV IOS_SDK=18.5 - -RUN dnf -y install --setopt=install_weak_deps=False \ - automake autoconf gcc gcc-c++ gcc-objc gcc-objc++ cmake libicu-devel libtool libxml2-devel openssl-devel perl python yasm && \ - git clone --progress https://github.com/tpoechtrager/cctools-port && \ - cd /root/cctools-port && \ - git checkout 7224fd5c9390ea15cff6ee69ff92ea677b40014b && \ - # arm64 device - usage_examples/ios_toolchain/build.sh /root/files/iPhoneOS${IOS_SDK}.sdk.tar.xz arm64 && \ - mkdir -p /root/ioscross/arm64 && \ - mv usage_examples/ios_toolchain/target/* /root/ioscross/arm64 && \ - mkdir /root/ioscross/arm64/usr && \ - ln -s /root/ioscross/arm64/bin /root/ioscross/arm64/usr/bin && \ - # Prepare for simulator builds - sed -i '/WRAPPER_SDKDIR/s/iPhoneOS/iPhoneSimulator/' usage_examples/ios_toolchain/build.sh && \ - # arm64 simulator - usage_examples/ios_toolchain/build.sh /root/files/iPhoneSimulator${IOS_SDK}.sdk.tar.xz arm64 && \ - mkdir -p /root/ioscross/arm64_sim && \ - mv usage_examples/ios_toolchain/target/* /root/ioscross/arm64_sim && \ - mkdir /root/ioscross/arm64_sim/usr && \ - ln -s /root/ioscross/arm64_sim/bin /root/ioscross/arm64_sim/usr/bin && \ - # x86_64 simulator - sed -i 's/^TRIPLE=.*/TRIPLE="x86_64-apple-darwin11"/' usage_examples/ios_toolchain/build.sh && \ - usage_examples/ios_toolchain/build.sh /root/files/iPhoneSimulator${IOS_SDK}.sdk.tar.xz x86_64 && \ - mkdir -p /root/ioscross/x86_64_sim && \ - mv usage_examples/ios_toolchain/target/* /root/ioscross/x86_64_sim && \ - mkdir /root/ioscross/x86_64_sim/usr && \ - ln -s /root/ioscross/x86_64_sim/bin /root/ioscross/x86_64_sim/usr/bin && \ - cd /root && \ - rm -rf /root/cctools-port - -ENV OSXCROSS_IOS=not_nothing -ENV IOSCROSS_ROOT=/root/ioscross -ENV PATH="/root/ioscross/arm64/bin:/root/ioscross/arm64_sim/bin:/root/ioscross/x86_64_sim/bin:${PATH}" - -CMD /bin/bash diff --git a/Dockerfile.osx b/Dockerfile.osx index ea13148..fc8e1a3 100644 --- a/Dockerfile.osx +++ b/Dockerfile.osx @@ -9,6 +9,9 @@ RUN dnf -y install --setopt=install_weak_deps=False \ git clone --progress https://github.com/tpoechtrager/osxcross && \ cd /root/osxcross && \ git checkout 310196974007fc916f9be1877731b716a4854f72 && \ + # Patch to fix visionOS support. + # See: https://github.com/llvm/llvm-project/issues/142502 + patch -p1 < /root/files/patches/osxcross-fix-visionos.patch && \ ln -s /root/files/MacOSX${OSX_SDK}.sdk.tar.xz /root/osxcross/tarballs && \ export UNATTENDED=1 && \ export SDK_VERSION=${OSX_SDK} && \ diff --git a/Dockerfile.xcode b/Dockerfile.xcode index 322c465..8604f82 100644 --- a/Dockerfile.xcode +++ b/Dockerfile.xcode @@ -11,25 +11,10 @@ RUN dnf -y install --setopt=install_weak_deps=False \ ENV XCODE_SDKV= ENV OSX_SDKV= ENV IOS_SDKV= +ENV TVOS_SDKV= +ENV VISIONOS_SDKV= -CMD mkdir -p /root/xcode && \ - cd /root/xcode && \ - xar -xf /root/files/Xcode_${XCODE_SDKV}.xip && \ - /root/pbzx/pbzx -n Content | cpio -i && \ - export OSX_SDK=MacOSX${OSX_SDKV}.sdk && \ - cp -r Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk /tmp/${OSX_SDK} && \ - cd /tmp && \ - tar -cJf /root/files/${OSX_SDK}.tar.xz ${OSX_SDK} && \ - rm -rf ${OSX_SDK} && \ - cd /root/xcode && \ - export IOS_SDK=iPhoneOS${IOS_SDKV}.sdk && \ - export IOS_SIMULATOR_SDK=iPhoneSimulator${IOS_SDKV}.sdk && \ - cp -r Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk /tmp/${IOS_SDK} && \ - cd /tmp && \ - tar -cJf /root/files/${IOS_SDK}.tar.xz ${IOS_SDK} && \ - rm -rf ${IOS_SDK} && \ - cd /root/xcode && \ - cp -r Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk /tmp/${IOS_SIMULATOR_SDK} && \ - cd /tmp && \ - tar -cJf /root/files/${IOS_SIMULATOR_SDK}.tar.xz ${IOS_SIMULATOR_SDK} && \ - rm -rf ${IOS_SIMULATOR_SDK} +COPY extract_xcode_sdks.sh /root/extract_xcode_sdks.sh +RUN chmod +x /root/extract_xcode_sdks.sh + +CMD /root/extract_xcode_sdks.sh diff --git a/README.md b/README.md index ae7ad30..1093934 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ These are the expected container image sizes, so you can plan your disk usage in localhost/godot-web 4.5-f42 2.35 GB localhost/godot-android 4.5-f42 4.19 GB localhost/godot-osx 4.5-f42 5.30 GB - localhost/godot-ios 4.5-f42 6.11 GB + localhost/godot-appleembedded 4.5-f42 14.1 GB In addition to this, generating containers will also require some host disk space (up to 10 GB) for the dependencies (Xcode). @@ -93,4 +93,4 @@ These are the toolchains currently in use for Godot 4.3 and later: - Android: Android NDK 28.1.13356709, build-tools 35.0.0, platform android-35, CMake 3.31.6, JDK 21 - Apple: Xcode 16.4 with Apple Clang (LLVM 19.1.4), cctools 1024.3, ld64 955.13 * macOS: MacOSX SDK 15.5 - * iOS: iPhoneOS SDK 18.5 + * Apple Embedded: iPhoneOS and iPhoneSimulator SDKs 18.5, AppleTVOS and AppleTVSimulator SDKs 18.5, XROS and XRSimulator SDKs 2.5 diff --git a/build.sh b/build.sh index 602f97f..4a5bc9a 100755 --- a/build.sh +++ b/build.sh @@ -61,7 +61,11 @@ podman_build android XCODE_SDK=16.4 OSX_SDK=15.5 IOS_SDK=18.5 -if [ ! -e "${files_root}"/MacOSX${OSX_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/iPhoneOS${IOS_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/iPhoneSimulator${IOS_SDK}.sdk.tar.xz ]; then +TVOS_SDK=18.5 +VISIONOS_SDK=2.5 +if [ ! -e "${files_root}"/MacOSX${OSX_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/iPhoneOS${IOS_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/iPhoneSimulator${IOS_SDK}.sdk.tar.xz ] \ +|| [ ! -e "${files_root}"/AppleTVOS${TVOS_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/AppleTVSimulator${TVOS_SDK}.sdk.tar.xz ] \ +|| [ ! -e "${files_root}"/XROS${VISIONOS_SDK}.sdk.tar.xz ] || [ ! -e "${files_root}"/XRSimulator${VISIONOS_SDK}.sdk.tar.xz ]; then if [ ! -r "${files_root}"/Xcode_${XCODE_SDK}.xip ]; then echo echo "Error: 'files/Xcode_${XCODE_SDK}.xip' is required for Apple platforms, but was not found or couldn't be read." @@ -69,16 +73,18 @@ if [ ! -e "${files_root}"/MacOSX${OSX_SDK}.sdk.tar.xz ] || [ ! -e "${files_root} exit 1 fi - echo "Building OSX and iOS SDK packages. This will take a while" + echo "Extracting Apple SDK packages. This will take a while." podman_build xcode "$podman" run -it --rm \ -v "${files_root}":/root/files:z \ -e XCODE_SDKV="${XCODE_SDK}" \ -e OSX_SDKV="${OSX_SDK}" \ -e IOS_SDKV="${IOS_SDK}" \ + -e TVOS_SDKV="${TVOS_SDK}" \ + -e VISIONOS_SDKV="${VISIONOS_SDK}" \ godot-xcode:${img_version} \ 2>&1 | tee logs/xcode_packer.log fi podman_build osx -podman_build ios +podman_build appleembedded diff --git a/extract_xcode_sdks.sh b/extract_xcode_sdks.sh new file mode 100644 index 0000000..6adc4bf --- /dev/null +++ b/extract_xcode_sdks.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Configurable variables (can be set via env) +XCODE_APP_PATH="${XCODE_APP_PATH:-/root/xcode/Xcode.app}" +XCODE_XIP_PATH="${XCODE_XIP_PATH:-/root/files/Xcode_${XCODE_SDKV}.xip}" +EXTRACT_FROM_XIP="${EXTRACT_FROM_XIP:-1}" + +OUT_DIR="${OUT_DIR:-/root/files}" + +# SDK versions (should be set via env or Dockerfile) +OSX_SDKV="${OSX_SDKV:-}" +IOS_SDKV="${IOS_SDKV:-}" +TVOS_SDKV="${TVOS_SDKV:-}" +VISIONOS_SDKV="${VISIONOS_SDKV:-}" + +# Which SDKs to extract (set to 1 to enable) +# Note: These defaults are overridden below based on execution context + +# Optionally extract Xcode.app from .xip if needed +if [[ "$EXTRACT_FROM_XIP" == "1" ]]; then + mkdir -p /root/xcode + cd /root/xcode + xar -xf "$XCODE_XIP_PATH" + /root/pbzx/pbzx -n Content | cpio -i + XCODE_APP_PATH="/root/xcode/Xcode.app" +fi + +if [[ "${EXTRACT_FROM_XIP:-1}" == "1" ]]; then + EXTRACT_MACOS="${EXTRACT_MACOS:-1}" + EXTRACT_IOS="${EXTRACT_IOS:-1}" + EXTRACT_IOS_SIM="${EXTRACT_IOS_SIM:-1}" + EXTRACT_TVOS="${EXTRACT_TVOS:-1}" + EXTRACT_TVOS_SIM="${EXTRACT_TVOS_SIM:-1}" + EXTRACT_VISIONOS="${EXTRACT_VISIONOS:-1}" + EXTRACT_VISIONOS_SIM="${EXTRACT_VISIONOS_SIM:-1}" +else + # When called manually, require explicit SDK selection + EXTRACT_MACOS="${EXTRACT_MACOS:-0}" + EXTRACT_IOS="${EXTRACT_IOS:-0}" + EXTRACT_IOS_SIM="${EXTRACT_IOS_SIM:-0}" + EXTRACT_TVOS="${EXTRACT_TVOS:-0}" + EXTRACT_TVOS_SIM="${EXTRACT_TVOS_SIM:-0}" + EXTRACT_VISIONOS="${EXTRACT_VISIONOS:-0}" + EXTRACT_VISIONOS_SIM="${EXTRACT_VISIONOS_SIM:-0}" +fi + +extract_and_pack() { + local sdk_dir="$1" + local sdk_name="$2" + local versioned_name="$3" + local tar_name="$4" + + if [[ -d "$sdk_dir/$sdk_name" ]]; then + + # Use tar to copy and preserve everything, then repackage + echo "=== Copying SDK using tar to preserve special files ===" + cd "$sdk_dir" + tar -cf - "$sdk_name" | (cd "/tmp" && tar -xf -) + + # Rename to versioned name + mv "/tmp/$sdk_name" "/tmp/$versioned_name" + + # Verify SDKSettings.json exists and has content + if [[ -f "/tmp/$versioned_name/SDKSettings.json" ]]; then + echo "=== SDKSettings.json found, size: $(wc -c < "/tmp/$versioned_name/SDKSettings.json") bytes ===" + echo "=== MD5 check ===" + echo "Source file MD5: $(md5sum "$sdk_dir/$sdk_name/SDKSettings.json" | cut -d' ' -f1)" + echo "Copied file MD5: $(md5sum "/tmp/$versioned_name/SDKSettings.json" | cut -d' ' -f1)" + else + echo "⚠️ Warning: SDKSettings.json not found in extracted SDK" + fi + + # Create tar with versioned directory name + tar -cJf "$OUT_DIR/$tar_name" -C "/tmp" "$versioned_name" + + # Clean up temporary directory + rm -rf "/tmp/$versioned_name" + + echo "✓ Packed $tar_name" + else + echo "✗ SDK not found: $sdk_dir/$sdk_name" + exit 1 + fi +} + +# macOS SDK +if [[ "$EXTRACT_MACOS" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" \ + "MacOSX.sdk" \ + "MacOSX${OSX_SDKV}.sdk" \ + "MacOSX${OSX_SDKV}.sdk.tar.xz" +fi + +# iOS SDK +if [[ "$EXTRACT_IOS" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs" \ + "iPhoneOS.sdk" \ + "iPhoneOS${IOS_SDKV}.sdk" \ + "iPhoneOS${IOS_SDKV}.sdk.tar.xz" +fi + +# iOS Simulator SDK +if [[ "$EXTRACT_IOS_SIM" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs" \ + "iPhoneSimulator.sdk" \ + "iPhoneSimulator${IOS_SDKV}.sdk" \ + "iPhoneSimulator${IOS_SDKV}.sdk.tar.xz" +fi + +# tvOS SDK +if [[ "$EXTRACT_TVOS" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs" \ + "AppleTVOS.sdk" \ + "AppleTVOS${TVOS_SDKV}.sdk" \ + "AppleTVOS${TVOS_SDKV}.sdk.tar.xz" +fi + +# tvOS Simulator SDK +if [[ "$EXTRACT_TVOS_SIM" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/SDKs" \ + "AppleTVSimulator.sdk" \ + "AppleTVSimulator${TVOS_SDKV}.sdk" \ + "AppleTVSimulator${TVOS_SDKV}.sdk.tar.xz" +fi + +# visionOS SDK +if [[ "$EXTRACT_VISIONOS" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/XROS.platform/Developer/SDKs" \ + "XROS.sdk" \ + "XROS${VISIONOS_SDKV}.sdk" \ + "XROS${VISIONOS_SDKV}.sdk.tar.xz" +fi + +# visionOS Simulator SDK +if [[ "$EXTRACT_VISIONOS_SIM" == "1" ]]; then + extract_and_pack \ + "$XCODE_APP_PATH/Contents/Developer/Platforms/XRSimulator.platform/Developer/SDKs" \ + "XRSimulator.sdk" \ + "XRSimulator${VISIONOS_SDKV}.sdk" \ + "XRSimulator${VISIONOS_SDKV}.sdk.tar.xz" +fi + +echo "Done extracting selected SDKs." diff --git a/files/appleembedded/build.sh b/files/appleembedded/build.sh new file mode 100755 index 0000000..cf988ef --- /dev/null +++ b/files/appleembedded/build.sh @@ -0,0 +1,197 @@ +#!/usr/bin/env bash + +export LC_ALL=C +pushd "${0%/*}" &>/dev/null + +PLATFORM=$(uname -s) +OPERATING_SYSTEM=$(uname -o || echo "-") + +if [ $OPERATING_SYSTEM == "Android" ]; then + export CC="clang -D__ANDROID_API__=26" + export CXX="clang++ -D__ANDROID_API__=26" +fi + +if [ -z "$LLVM_DSYMUTIL" ]; then + if command -v llvm-dsymutil &>/dev/null; then + LLVM_DSYMUTIL=llvm-dsymutil + else + LLVM_DSYMUTIL=dsymutil + fi +fi + +if [ -z "$JOBS" ]; then + JOBS=$(nproc 2>/dev/null || ncpus 2>/dev/null || echo 1) +fi + +set -e + +function verbose_cmd +{ + echo "$@" + eval "$@" +} + +function git_clone_repository +{ + local url=$1 + local branch=$2 + local directory + + directory=$(basename $url) + directory=${directory/\.git/} + + if [ -n "$CCTOOLS_IOS_DEV" ]; then + rm -rf $directory + cp -r $CCTOOLS_IOS_DEV/$directory . + return + fi + + if [ ! -d $directory ]; then + local args="" + test "$branch" = "master" && args="--depth 1" + git clone $url $args + fi + + pushd $directory &>/dev/null + + git reset --hard + git clean -fdx + git checkout $branch + git pull origin $branch + + popd &>/dev/null +} + + +if [ $# -lt 1 ]; then + echo "usage: $0 " 1>&2 + echo "i.e. $0 arm64" 1>&2 + exit 1 +fi + +TARGET_CPU="$1" +if [ "$TARGET_CPU" != "arm64" ] && [ "$TARGET_CPU" != "x86_64" ]; then + echo "target cpu must be either 'arm64' or 'x86_64'" 1>&2 + exit 1 +fi + +if [ "$TARGET_CPU" == "arm64" ]; then + TRIPLE="arm-apple-darwin11" +else + TRIPLE="x86_64-apple-darwin11" +fi + +TARGETDIR="$PWD/target" + +if [ -d $TARGETDIR ]; then + echo "cleaning up ..." + rm -rf $TARGETDIR +fi + +mkdir -p $TARGETDIR +mkdir -p $TARGETDIR/bin + +echo "" +echo "*** building wrapper ***" +echo "" + +OK=0 + +set +e +version=$(echo "$($LLVM_DSYMUTIL --version 2>&1)" | grep -oP 'LLVM version \K[^\s]+') + +if [ $? -eq 0 ]; then + major_version=$(echo "$version" | awk -F'\\.' '{print $1}') + minor_version=$(echo "$version" | awk -F'\\.' '{print $2}') + if ((major_version > 3 || (major_version == 3 && minor_version >= 8))); then + OK=1 + + if [ "$LLVM_DSYMUTIL" == "llvm-dsymutil" ]; then + ln -sf "$(command -v $LLVM_DSYMUTIL)" "$TARGETDIR/bin/dsymutil" + fi + fi +fi +set -e + +if [ $OK -ne 1 ]; then + echo "int main(){return 0;}" | cc -xc -O2 -o $TARGETDIR/bin/dsymutil - +fi + +pushd $TARGETDIR/bin &>/dev/null +ln -sf $TRIPLE-lipo lipo +popd &>/dev/null + +verbose_cmd cc -O2 -Wall -Wextra -pedantic wrapper.c \ + -DTARGET_CPU=\"\\\"${TARGET_CPU}\\\"\" \ + -o $TARGETDIR/bin/$TRIPLE-clang + +pushd $TARGETDIR/bin &>/dev/null +verbose_cmd ln -sf $TRIPLE-clang $TRIPLE-clang++ +popd &>/dev/null + +rm -rf tmp +mkdir -p tmp + +echo "" +echo "*** building ldid ***" +echo "" + +pushd tmp &>/dev/null +git_clone_repository https://github.com/tpoechtrager/ldid.git master +pushd ldid &>/dev/null +make INSTALLPREFIX=$TARGETDIR -j$JOBS install +popd &>/dev/null +popd &>/dev/null + +echo "" +echo "*** building apple-libdispatch ***" +echo "" + +pushd tmp &>/dev/null +git_clone_repository https://github.com/tpoechtrager/apple-libdispatch.git main +pushd apple-libdispatch &>/dev/null +mkdir -p build +pushd build &>/dev/null +CC=clang CXX=clang++ \ + cmake .. -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=$TARGETDIR +make install -j$JOBS +popd &>/dev/null +popd &>/dev/null +popd &>/dev/null + +echo "" +echo "*** building apple-libtapi ***" +echo "" + +pushd tmp &>/dev/null +git_clone_repository https://github.com/tpoechtrager/apple-libtapi.git 1300.6.5 +pushd apple-libtapi &>/dev/null +INSTALLPREFIX=$TARGETDIR ./build.sh +./install.sh +popd &>/dev/null +popd &>/dev/null + +echo "" +echo "*** building cctools / ld64 ***" +echo "" + +pushd ../../cctools &>/dev/null +git clean -fdx &>/dev/null || true +popd &>/dev/null + +pushd tmp &>/dev/null +mkdir -p cctools +pushd cctools &>/dev/null +../../../../cctools/configure \ + --target=$TRIPLE \ + --prefix=$TARGETDIR \ + --with-libtapi=$TARGETDIR \ + --with-libdispatch=$TARGETDIR \ + --with-libblocksruntime=$TARGETDIR +make -j$JOBS && make install +popd &>/dev/null +popd &>/dev/null + + +echo "" +echo "*** all done ***" diff --git a/files/appleembedded/check-arm.sh b/files/appleembedded/check-arm.sh new file mode 100755 index 0000000..0d67c11 --- /dev/null +++ b/files/appleembedded/check-arm.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +function check_toolchain +{ + local platform=$1 + local sdk_prefix=$2 + local sdk_version=$3 + # if $4 is true, use the simulator SDK + if [ "$4" == "true" ]; then + SDK_DIR="/root/SDKs/${sdk_prefix}Simulator${sdk_version}.sdk" + TARGET_OS="${platform}${sdk_version}-simulator" + NAME="${platform} (Simulator)" + else + SDK_DIR="/root/SDKs/${sdk_prefix}OS${sdk_version}.sdk" + TARGET_OS="${platform}${sdk_version}" + NAME="${platform} (Device)" + fi + + echo "" + echo "*** checking ${NAME} toolchain ***" + echo "" + echo "" + + echo "int main(){return 0;}" | arm-apple-darwin11-clang -isysroot "$SDK_DIR" -mtargetos=${TARGET_OS} -xc -O2 -c -o test.o - || exit 1 + arm-apple-darwin11-ar rcs libtest.a test.o || exit 1 + rm test.o libtest.a + echo "${NAME} toolchain OK" +} + +check_toolchain "ios" "iPhone" "$IOS_SDK" false +check_toolchain "tvos" "AppleTV" "$TVOS_SDK" false +check_toolchain "xros" "XR" "$XROS_SDK" false +# Check for simulator toolchains +check_toolchain "ios" "iPhone" "$IOS_SDK" true +check_toolchain "tvos" "AppleTV" "$TVOS_SDK" true +check_toolchain "xros" "XR" "$XROS_SDK" true + diff --git a/files/appleembedded/wrapper.c b/files/appleembedded/wrapper.c new file mode 100644 index 0000000..b2ec645 --- /dev/null +++ b/files/appleembedded/wrapper.c @@ -0,0 +1,172 @@ +#ifndef TARGET_CPU +#define TARGET_CPU "arm64" +#endif + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#endif + +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +#include +#endif + +#ifdef __OpenBSD__ +#include +#include +#include +#endif + +char *get_executable_path(char *epath, size_t buflen) +{ + char *p; +#ifdef __APPLE__ + unsigned int l = buflen; + if (_NSGetExecutablePath(epath, &l) != 0) return NULL; +#elif defined(__FreeBSD__) || defined(__DragonFly__) + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + size_t l = buflen; + if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL; +#elif defined(__OpenBSD__) + int mib[4]; + char **argv; + size_t len; + size_t l; + const char *comm; + int ok = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = getpid(); + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) + abort(); + if (!(argv = malloc(len))) + abort(); + if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) + abort(); + comm = argv[0]; + if (*comm == '/' || *comm == '.') + { + char *rpath; + if ((rpath = realpath(comm, NULL))) + { + strlcpy(epath, rpath, buflen); + free(rpath); + ok = 1; + } + } + else + { + char *sp; + char *xpath = strdup(getenv("PATH")); + char *path = strtok_r(xpath, ":", &sp); + struct stat st; + if (!xpath) + abort(); + while (path) + { + snprintf(epath, buflen, "%s/%s", path, comm); + if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) + { + ok = 1; + break; + } + path = strtok_r(NULL, ":", &sp); + } + free(xpath); + } + free(argv); + if (!ok) return NULL; + l = strlen(epath); +#else + ssize_t l = readlink("/proc/self/exe", epath, buflen - 1); + if (l > 0) epath[l] = '\0'; +#endif + if (l <= 0) return NULL; + epath[buflen - 1] = '\0'; + p = strrchr(epath, '/'); + if (p) *p = '\0'; + return epath; +} + +char *get_filename(char *str) +{ + char *p = strrchr(str, '/'); + return p ? &p[1] : str; +} + +void target_info(char *argv[], char **triple, char **compiler) +{ + char *p = get_filename(argv[0]); + char *x = strrchr(p, '-'); + if (!x) abort(); + *compiler = &x[1]; + *x = '\0'; + *triple = p; +} + +void env(char **p, const char *name, char *fallback) +{ + char *ev = getenv(name); + if (ev) { *p = ev; return; } + *p = fallback; +} + +int main(int argc, char *argv[]) +{ + char **args = alloca(sizeof(char*) * (argc+12)); + int i, j; + + char execpath[PATH_MAX+1]; + + char *compiler; + char *target; + char *cpu = TARGET_CPU; + + target_info(argv, &target, &compiler); + if (!get_executable_path(execpath, sizeof(execpath))) abort(); + + for (i = 1; i < argc; ++i) + { + if (!strcmp(argv[i], "-arch")) + { + cpu = NULL; + break; + } + } + + i = 0; + + args[i++] = compiler; + args[i++] = "-target"; + args[i++] = target; + + if (cpu) + { + args[i++] = "-arch"; + args[i++] = cpu; + } + + args[i++] = "-mlinker-version=955.13"; + args[i++] = "-Wl,-adhoc_codesign"; + args[i++] = "-Wno-unused-command-line-argument"; + + for (j = 1; j < argc; ++i, ++j) + args[i] = argv[j]; + + args[i] = NULL; + + setenv("COMPILER_PATH", execpath, 1); + execvp(compiler, args); + + fprintf(stderr, "cannot invoke compiler!\n"); + return 1; +} diff --git a/files/patches/osxcross-fix-visionos.patch b/files/patches/osxcross-fix-visionos.patch new file mode 100644 index 0000000..d410fce --- /dev/null +++ b/files/patches/osxcross-fix-visionos.patch @@ -0,0 +1,118 @@ +diff --git a/build_clang.sh b/build_clang.sh +index 0d9c36b..57d967e 100755 +--- a/build_clang.sh ++++ b/build_clang.sh +@@ -149,6 +149,15 @@ if [ $GITPROJECT == "apple" ]; then + # lld has been broken by this PR: + # https://github.com/swiftlang/llvm-project/pull/8119 + patch -p1 < $PATCH_DIR/unbreak-apple-lld.patch || true ++ ++ if ([[ $CLANG_VERSION == 19* ]]); then ++ # availability attributes for visionos / xros don't respect being derived from iOS ++ # and this patch fixes that ++ # ++ # https://github.com/swiftlang/llvm-project/issues/10782 ++ patch -p1 < $PATCH_DIR/xros-availability-clang.patch || true ++ fi ++ + popd &>/dev/null + fi + +diff --git a/build_compiler_rt.sh b/build_compiler_rt.sh +index da64909..feb9990 100755 +--- a/build_compiler_rt.sh ++++ b/build_compiler_rt.sh +@@ -98,6 +98,16 @@ fi + get_sources https://github.com/llvm/llvm-project.git $BRANCH "compiler-rt" + + if [ $f_res -eq 1 ]; then ++ if [ $(osxcross-cmp $CLANG_VERSION ">=" 19.0) -eq 1 ]; then ++ pushd "$CURRENT_BUILD_PROJECT_NAME" ++ # availability attributes for visionos / xros don't respect being derived from iOS ++ # and this patch fixes that ++ # ++ # https://github.com/swiftlang/llvm-project/issues/10782 ++ patch -p1 < $PATCH_DIR/xros-availability-clang.patch || true ++ popd ++ fi ++ + pushd "$CURRENT_BUILD_PROJECT_NAME/compiler-rt" &>/dev/null + + if [ $(osxcross-cmp $SDK_VERSION "<=" 10.11) -eq 1 ]; then +diff --git a/patches/xros-availability-clang.patch b/patches/xros-availability-clang.patch +new file mode 100644 +index 0000000..2666a18 +--- /dev/null ++++ b/patches/xros-availability-clang.patch +@@ -0,0 +1,71 @@ ++diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h ++index db20b968a..33b36f53c 100644 ++--- a/clang/include/clang/Basic/DarwinSDKInfo.h +++++ b/clang/include/clang/Basic/DarwinSDKInfo.h ++@@ -72,6 +72,13 @@ public: ++ llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment); ++ } ++ +++ /// Returns the os-environment mapping pair that's used to represent the +++ /// iOS -> visionOS version mapping. +++ static inline constexpr OSEnvPair iOStoXROSPair() { +++ return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, +++ llvm::Triple::XROS, llvm::Triple::UnknownEnvironment); +++ } +++ ++ private: ++ StorageType Value; ++ ++diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp ++index e2eada24f..26290b3ba 100644 ++--- a/clang/lib/Sema/SemaDeclAttr.cpp +++++ b/clang/lib/Sema/SemaDeclAttr.cpp ++@@ -2415,6 +2415,48 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { ++ auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version); ++ auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version); ++ +++ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( +++ ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, +++ NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, +++ Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform, +++ IIEnvironment); +++ if (NewAttr) +++ D->addAttr(NewAttr); +++ } +++ } else if (S.Context.getTargetInfo().getTriple().isXROS()) { +++ // Transcribe "ios" to "visionos" (and add a new attribute) if the versioning +++ // matches before the start of the visionOS platform. +++ IdentifierInfo *NewII = nullptr; +++ if (II->getName() == "ios") +++ NewII = &S.Context.Idents.get("xros"); +++ else if (II->getName() == "ios_app_extension") +++ NewII = &S.Context.Idents.get("xros_app_extension"); +++ +++ if (NewII) { +++ const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); +++ const auto *IOSToXROSMapping = +++ SDKInfo ? SDKInfo->getVersionMapping( +++ DarwinSDKInfo::OSEnvPair::iOStoXROSPair()) +++ : nullptr; +++ +++ auto AdjustTvOSVersion = +++ [IOSToXROSMapping](VersionTuple Version) -> VersionTuple { +++ if (Version.empty()) +++ return Version; +++ +++ if (IOSToXROSMapping) { +++ if (auto MappedVersion = IOSToXROSMapping->map( +++ Version, VersionTuple(1, 0), std::nullopt)) { +++ return *MappedVersion; +++ } +++ } +++ return Version; +++ }; +++ +++ auto NewIntroduced = AdjustTvOSVersion(Introduced.Version); +++ auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version); +++ auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version); +++ ++ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( ++ ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, ++ NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, diff --git a/upload.sh b/upload.sh index 34b11cc..d6a5518 100755 --- a/upload.sh +++ b/upload.sh @@ -21,5 +21,5 @@ fi "$podman" push godot-xcode:${img_version} ${registry}/godot/xcode "$podman" push godot-android:${img_version} ${registry}/godot-private/android -"$podman" push godot-ios:${img_version} ${registry}/godot-private/ios "$podman" push godot-osx:${img_version} ${registry}/godot-private/macosx +"$podman" push godot-appleembedded:${img_version} ${registry}/godot-private/appleembedded