├── .gitignore ├── setup.sh ├── Dockerfile.base ├── Dockerfile.web ├── Dockerfile.windows ├── Dockerfile.xcode ├── Dockerfile.android ├── upload.sh ├── files ├── appleembedded │ ├── check-arm.sh │ ├── wrapper.c │ └── build.sh ├── swift │ └── create-sdk-bundle.sh └── patches │ └── osxcross-fix-visionos.patch ├── Dockerfile.appleembedded ├── Dockerfile.linux ├── Dockerfile.osx ├── extract_xcode_sdks.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.tar 2 | *.tar.gz 3 | *.tar.bz2 4 | *.tar.xz 5 | *.exe 6 | *.swp 7 | *.dmg 8 | *.zip 9 | *.xip 10 | 11 | files/mono-*/ 12 | logs/ 13 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | podman=`command -v podman` 4 | 5 | if [ -z "$podman" ]; then 6 | echo "podman needs to be in PATH for this script to work." 7 | exit 1 8 | fi 9 | -------------------------------------------------------------------------------- /Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM fedora:42 2 | 3 | WORKDIR /root 4 | 5 | ENV DOTNET_NOLOGO=1 6 | ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 7 | 8 | RUN dnf -y install --setopt=install_weak_deps=False \ 9 | bash binutils bzip2 curl file findutils gettext git make nano patch pkgconfig python3-pip unzip which xz \ 10 | dotnet-sdk-8.0 && \ 11 | pip install scons==4.9.1 12 | 13 | CMD /bin/bash 14 | -------------------------------------------------------------------------------- /Dockerfile.web: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | ENV EMSCRIPTEN_VERSION=4.0.10 5 | 6 | RUN dnf -y install --setopt=install_weak_deps=False libatomic && \ 7 | git clone --branch ${EMSCRIPTEN_VERSION} --progress https://github.com/emscripten-core/emsdk && \ 8 | emsdk/emsdk install ${EMSCRIPTEN_VERSION} && \ 9 | emsdk/emsdk activate ${EMSCRIPTEN_VERSION} 10 | 11 | CMD /bin/bash 12 | -------------------------------------------------------------------------------- /Dockerfile.windows: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | RUN dnf -y install --setopt=install_weak_deps=False \ 5 | mingw32-gcc mingw32-gcc-c++ mingw32-winpthreads-static mingw64-gcc mingw64-gcc-c++ mingw64-winpthreads-static && \ 6 | export LLVM_MINGW_VERSION=20250528 && \ 7 | export LLVM_MINGW_NAME=llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-22.04-x86_64 && \ 8 | curl -LO https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/${LLVM_MINGW_NAME}.tar.xz && \ 9 | tar xf ${LLVM_MINGW_NAME}.tar.xz && \ 10 | rm -f ${LLVM_MINGW_NAME}.tar.xz && \ 11 | mv -f ${LLVM_MINGW_NAME} /root/llvm-mingw 12 | 13 | CMD /bin/bash 14 | -------------------------------------------------------------------------------- /Dockerfile.xcode: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | RUN dnf -y install --setopt=install_weak_deps=False \ 5 | clang xar xar-devel xz-devel cpio && \ 6 | git clone --progress https://github.com/nrosenstein-stuff/pbzx && \ 7 | cd pbzx && \ 8 | git checkout bf536e167f2e514866f91d7baa0df1dff5a13711 && \ 9 | clang -O3 -llzma -lxar -I /usr/local/include pbzx.c -o pbzx 10 | 11 | ENV XCODE_SDKV= 12 | ENV APPLE_SDKV= 13 | ENV OSX_SDKV= 14 | ENV IOS_SDKV= 15 | ENV TVOS_SDKV= 16 | ENV VISIONOS_SDKV= 17 | 18 | COPY extract_xcode_sdks.sh /root/extract_xcode_sdks.sh 19 | RUN chmod +x /root/extract_xcode_sdks.sh 20 | 21 | CMD /root/extract_xcode_sdks.sh 22 | -------------------------------------------------------------------------------- /Dockerfile.android: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | ENV ANDROID_SDK_ROOT=/root/sdk 5 | ENV ANDROID_NDK_VERSION=28.1.13356709 6 | ENV ANDROID_NDK_ROOT=${ANDROID_SDK_ROOT}/ndk/${ANDROID_NDK_VERSION} 7 | 8 | RUN dnf -y install --setopt=install_weak_deps=False \ 9 | java-21-openjdk-devel ncurses-compat-libs && \ 10 | mkdir -p sdk && cd sdk && \ 11 | export CMDLINETOOLS=commandlinetools-linux-13114758_latest.zip && \ 12 | curl -LO https://dl.google.com/android/repository/${CMDLINETOOLS} && \ 13 | unzip ${CMDLINETOOLS} && \ 14 | rm ${CMDLINETOOLS} && \ 15 | yes | cmdline-tools/bin/sdkmanager --sdk_root="${ANDROID_SDK_ROOT}" --licenses && \ 16 | cmdline-tools/bin/sdkmanager --sdk_root="${ANDROID_SDK_ROOT}" "ndk;${ANDROID_NDK_VERSION}" 'cmdline-tools;latest' 'build-tools;35.0.0' 'platforms;android-35' 'cmake;3.31.6' 17 | 18 | CMD /bin/bash 19 | -------------------------------------------------------------------------------- /upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source $(dirname "$0")/setup.sh 4 | 5 | img_version=$1 6 | registry=$2 7 | 8 | if [ -z "${img_version}" ]; then 9 | echo "No image version was provided, aborting. Check script for usage." 10 | exit 1 11 | fi 12 | 13 | if [ -z "${registry}" ]; then 14 | registry=registry.prehensile-tales.com 15 | fi 16 | 17 | "$podman" push godot-export:${img_version} ${registry}/godot/export 18 | "$podman" push godot-linux:${img_version} ${registry}/godot/linux 19 | "$podman" push godot-windows:${img_version} ${registry}/godot/windows 20 | "$podman" push godot-web:${img_version} ${registry}/godot/web 21 | "$podman" push godot-xcode:${img_version} ${registry}/godot/xcode 22 | 23 | "$podman" push godot-android:${img_version} ${registry}/godot-private/android 24 | "$podman" push godot-osx:${img_version} ${registry}/godot-private/macosx 25 | "$podman" push godot-appleembedded:${img_version} ${registry}/godot-private/appleembedded 26 | -------------------------------------------------------------------------------- /files/appleembedded/check-arm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | function check_toolchain 4 | { 5 | local platform=$1 6 | local sdk_prefix=$2 7 | # if $3 is true, use the simulator SDK 8 | if [ "$3" == "true" ]; then 9 | SDK_DIR="/root/Xcode.app/Contents/Developer/Platforms/${sdk_prefix}Simulator.platform/Developer/SDKs/${sdk_prefix}Simulator.sdk" 10 | TARGET_OS="${platform}${APPLE_SDKV}-simulator" 11 | NAME="${platform} (Simulator)" 12 | else 13 | SDK_DIR="/root/Xcode.app/Contents/Developer/Platforms/${sdk_prefix}OS.platform/Developer/SDKs/${sdk_prefix}OS.sdk" 14 | TARGET_OS="${platform}${APPLE_SDKV}" 15 | NAME="${platform} (Device)" 16 | fi 17 | 18 | echo "" 19 | echo "*** checking ${NAME} toolchain ***" 20 | echo "" 21 | echo "" 22 | 23 | echo "int main(){return 0;}" | arm-apple-darwin11-clang -isysroot "$SDK_DIR" -mtargetos=${TARGET_OS} -xc -O2 -c -o test.o - || exit 1 24 | arm-apple-darwin11-ar rcs libtest.a test.o || exit 1 25 | rm test.o libtest.a 26 | echo "${NAME} toolchain OK" 27 | } 28 | 29 | check_toolchain "ios" "iPhone" false 30 | check_toolchain "tvos" "AppleTV" false 31 | check_toolchain "xros" "XR" false 32 | # Check for simulator toolchains 33 | check_toolchain "ios" "iPhone" true 34 | check_toolchain "tvos" "AppleTV" true 35 | check_toolchain "xros" "XR" true 36 | 37 | -------------------------------------------------------------------------------- /Dockerfile.appleembedded: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-osx:${img_version} 3 | 4 | RUN dnf -y install --setopt=install_weak_deps=False \ 5 | automake autoconf gcc gcc-c++ gcc-objc gcc-objc++ cmake libicu-devel libtool libxml2-devel openssl-devel perl python yasm 6 | 7 | RUN git clone --depth 1 --no-checkout https://github.com/tpoechtrager/cctools-port.git && \ 8 | cd /root/cctools-port && \ 9 | git fetch --depth 1 origin 7224fd5c9390ea15cff6ee69ff92ea677b40014b && \ 10 | git checkout 7224fd5c9390ea15cff6ee69ff92ea677b40014b 11 | 12 | COPY files/appleembedded/build.sh /root/cctools-port/usage_examples/ios_toolchain/build.sh 13 | COPY files/appleembedded/wrapper.c /root/cctools-port/usage_examples/ios_toolchain/wrapper.c 14 | 15 | RUN chmod +x /root/cctools-port/usage_examples/ios_toolchain/build.sh 16 | 17 | RUN cd /root/cctools-port && \ 18 | usage_examples/ios_toolchain/build.sh arm64 && \ 19 | mkdir -p /root/ioscross/arm64 && \ 20 | mv usage_examples/ios_toolchain/target/* /root/ioscross/arm64 && \ 21 | mkdir /root/ioscross/arm64/usr && \ 22 | ln -s /root/ioscross/arm64/bin /root/ioscross/arm64/usr/bin 23 | 24 | RUN cd /root/cctools-port && \ 25 | usage_examples/ios_toolchain/build.sh x86_64 && \ 26 | mkdir -p /root/ioscross/x86_64 && \ 27 | mv usage_examples/ios_toolchain/target/* /root/ioscross/x86_64 && \ 28 | mkdir /root/ioscross/x86_64/usr && \ 29 | ln -s /root/ioscross/x86_64/bin /root/ioscross/x86_64/usr/bin 30 | 31 | RUN PATH=/root/ioscross/arm64/bin:$PATH /root/files/appleembedded/check-arm.sh 32 | 33 | ENV OSXCROSS_IOS=not_nothing 34 | ENV OSXCROSS_TVOS=not_nothing 35 | ENV OSXCROSS_VISIONOS=not_nothing 36 | ENV OSXCROSS_APPLEEMBEDDED=not_nothing 37 | 38 | ENV PATH="/root/ioscross/arm64/bin:/root/ioscross/x86_64/bin:${PATH}" 39 | 40 | CMD /bin/bash 41 | -------------------------------------------------------------------------------- /Dockerfile.linux: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | ENV GODOT_SDK_LINUX_X86_64=/root/x86_64-godot-linux-gnu_sdk-buildroot 5 | ENV GODOT_SDK_LINUX_X86_32=/root/i686-godot-linux-gnu_sdk-buildroot 6 | ENV GODOT_SDK_LINUX_ARM64=/root/aarch64-godot-linux-gnu_sdk-buildroot 7 | ENV GODOT_SDK_LINUX_ARM32=/root/arm-godot-linux-gnueabihf_sdk-buildroot 8 | ENV BASE_PATH=${PATH} 9 | 10 | RUN dnf install -y wayland-devel && \ 11 | curl -LO https://github.com/godotengine/buildroot/releases/download/godot-2023.08.x-4/x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 12 | tar xf x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 13 | rm -f x86_64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 14 | cd x86_64-godot-linux-gnu_sdk-buildroot && \ 15 | ./relocate-sdk.sh && \ 16 | cd /root && \ 17 | curl -LO https://github.com/godotengine/buildroot/releases/download/godot-2023.08.x-4/i686-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 18 | tar xf i686-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 19 | rm -f i686-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 20 | cd i686-godot-linux-gnu_sdk-buildroot && \ 21 | ./relocate-sdk.sh && \ 22 | cd /root && \ 23 | curl -LO https://github.com/godotengine/buildroot/releases/download/godot-2023.08.x-4/aarch64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 24 | tar xf aarch64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 25 | rm -f aarch64-godot-linux-gnu_sdk-buildroot.tar.bz2 && \ 26 | cd aarch64-godot-linux-gnu_sdk-buildroot && \ 27 | ./relocate-sdk.sh && \ 28 | cd /root && \ 29 | curl -LO https://github.com/godotengine/buildroot/releases/download/godot-2023.08.x-4/arm-godot-linux-gnueabihf_sdk-buildroot.tar.bz2 && \ 30 | tar xf arm-godot-linux-gnueabihf_sdk-buildroot.tar.bz2 && \ 31 | rm -f arm-godot-linux-gnueabihf_sdk-buildroot.tar.bz2 && \ 32 | cd arm-godot-linux-gnueabihf_sdk-buildroot && \ 33 | ./relocate-sdk.sh 34 | 35 | CMD /bin/bash 36 | -------------------------------------------------------------------------------- /Dockerfile.osx: -------------------------------------------------------------------------------- 1 | ARG img_version 2 | FROM godot-fedora:${img_version} 3 | 4 | # Additional packages for Swift 5 | # 6 | # sudo dnf install gnupg2 7 | 8 | ENV XCODE_SDKV=26.0.1 9 | ENV APPLE_SDKV=26.0 10 | ENV OSX_SDK=26.0 11 | 12 | RUN dnf -y install --setopt=install_weak_deps=False \ 13 | automake autoconf bzip2-devel cmake gawk gcc gcc-c++ libdispatch libicu-devel libtool \ 14 | libxml2-devel openssl-devel uuid-devel yasm gpg && \ 15 | git clone --progress https://github.com/tpoechtrager/osxcross && \ 16 | cd /root/osxcross && \ 17 | git checkout f873f534c6cdb0776e457af8c7513da1e02abe59 && \ 18 | # Patch to fix visionOS support. 19 | # See: https://github.com/llvm/llvm-project/issues/142502 20 | patch -p1 < /root/files/patches/osxcross-fix-visionos.patch && \ 21 | ln -s /root/files/MacOSX${OSX_SDK}.sdk.tar.xz /root/osxcross/tarballs && \ 22 | export UNATTENDED=1 && \ 23 | export SDK_VERSION=${OSX_SDK} && \ 24 | # Custom build Apple Clang to ensure compatibility. 25 | # Find the equivalent LLVM version for the SDK from: 26 | # https://en.wikipedia.org/wiki/Xcode#Toolchain_versions 27 | CLANG_VERSION=19.1.4 ENABLE_CLANG_INSTALL=1 INSTALLPREFIX=/usr ./build_apple_clang.sh && \ 28 | ./build.sh && \ 29 | ./build_compiler_rt.sh && \ 30 | rm -rf /root/osxcross/build 31 | 32 | ENV OSXCROSS_ROOT=/root/osxcross 33 | ENV PATH="/root/osxcross/target/bin:${PATH}" 34 | 35 | # Install Swift 6.2 toolchain 36 | 37 | RUN mkdir -p /root/Xcode.app/Contents/Developer 38 | RUN cd /root/Xcode.app/Contents/Developer && tar xf /root/files/Xcode-Developer${XCODE_SDKV}.tar.xz --strip-components=1 39 | 40 | RUN curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \ 41 | tar zxf swiftly-$(uname -m).tar.gz && \ 42 | ./swiftly init --platform ubi9 --quiet-shell-followup -y && \ 43 | . "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \ 44 | hash -r 45 | 46 | RUN /root/files/swift/create-sdk-bundle.sh /root/Xcode.app/Contents/Developer /root/.swiftpm/swift-sdks 47 | 48 | CMD /bin/bash 49 | -------------------------------------------------------------------------------- /extract_xcode_sdks.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | # Configurable variables (can be set via env) 6 | XCODE_APP_PATH="${XCODE_APP_PATH:-/root/xcode/Xcode.app}" 7 | XCODE_XIP_PATH="${XCODE_XIP_PATH:-/root/files/Xcode_${XCODE_SDKV}.xip}" 8 | EXTRACT_FROM_XIP="${EXTRACT_FROM_XIP:-1}" 9 | 10 | OUT_DIR="${OUT_DIR:-/root/files}" 11 | 12 | # SDK versions (should be set via env or Dockerfile) 13 | APPLE_SDKV="${APPLE_SDKV:-}" 14 | 15 | # Which SDKs to extract (set to 1 to enable) 16 | # Note: These defaults are overridden below based on execution context 17 | 18 | # Optionally extract Xcode.app from .xip if needed 19 | if [[ "$EXTRACT_FROM_XIP" == "1" ]]; then 20 | mkdir -p /root/xcode 21 | cd /root/xcode 22 | xar -xf "$XCODE_XIP_PATH" 23 | /root/pbzx/pbzx -n Content | cpio -i 24 | XCODE_APP_PATH="/root/xcode/Xcode.app" 25 | fi 26 | 27 | if [[ "${EXTRACT_FROM_XIP:-1}" == "1" ]]; then 28 | EXTRACT_MACOS="${EXTRACT_MACOS:-1}" 29 | EXTRACT_XCODE="${EXTRACT_XCODE:-1}" 30 | else 31 | # When called manually, require explicit SDK selection 32 | EXTRACT_MACOS="${EXTRACT_MACOS:-0}" 33 | EXTRACT_XCODE="${EXTRACT_XCODE:-0}" 34 | fi 35 | 36 | extract_and_pack() { 37 | local sdk_dir="$1" 38 | local sdk_name="$2" 39 | local versioned_name="$3" 40 | local tar_name="$4" 41 | 42 | if [[ -d "$sdk_dir/$sdk_name" ]]; then 43 | 44 | # Use tar to copy and preserve everything, then repackage 45 | echo "=== Copying SDK using tar to preserve special files ===" 46 | cd "$sdk_dir" 47 | tar -cf - "$sdk_name" | tar -xf - -C /tmp 48 | 49 | # Rename to versioned name 50 | mv "/tmp/$sdk_name" "/tmp/$versioned_name" 51 | 52 | # Verify SDKSettings.json exists and has content 53 | if [[ -f "/tmp/$versioned_name/SDKSettings.json" ]]; then 54 | echo "=== SDKSettings.json found, size: $(wc -c < "/tmp/$versioned_name/SDKSettings.json") bytes ===" 55 | echo "=== MD5 check ===" 56 | echo "Source file MD5: $(md5sum "$sdk_dir/$sdk_name/SDKSettings.json" | cut -d' ' -f1)" 57 | echo "Copied file MD5: $(md5sum "/tmp/$versioned_name/SDKSettings.json" | cut -d' ' -f1)" 58 | else 59 | echo "⚠️ Warning: SDKSettings.json not found in extracted SDK" 60 | fi 61 | 62 | # Create tar with versioned directory name 63 | tar -cJf "/tmp/$tar_name" -C "/tmp" "$versioned_name" 64 | 65 | # Clean up temporary directory 66 | rm -rf "/tmp/$versioned_name" 67 | mv "/tmp/$tar_name" "$OUT_DIR/$tar_name" 68 | 69 | echo "✓ Packed $tar_name" 70 | else 71 | echo "✗ SDK not found: $sdk_dir/$sdk_name" 72 | exit 1 73 | fi 74 | } 75 | 76 | # Xcode Developer 77 | if [[ "$EXTRACT_XCODE" == "1" ]]; then 78 | extract_and_pack \ 79 | "$XCODE_APP_PATH/Contents" \ 80 | "Developer" \ 81 | "Xcode-Developer${XCODE_SDKV}" \ 82 | "Xcode-Developer${XCODE_SDKV}.tar.xz" 83 | fi 84 | 85 | # macOS SDK 86 | if [[ "$EXTRACT_MACOS" == "1" ]]; then 87 | extract_and_pack \ 88 | "$XCODE_APP_PATH/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs" \ 89 | "MacOSX.sdk" \ 90 | "MacOSX${APPLE_SDKV}.sdk" \ 91 | "MacOSX${APPLE_SDKV}.sdk.tar.xz" 92 | fi 93 | 94 | echo "Done extracting selected SDKs." 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Godot engine build containers 2 | 3 | This repository contains the Dockerfiles for the official Godot engine builds. 4 | These containers should help you build Godot for all platforms supported on 5 | any machine that can run Docker containers. 6 | 7 | The in-container build scripts are in a separate repository: 8 | https://github.com/godotengine/godot-build-scripts 9 | 10 | 11 | ## Introduction 12 | 13 | These scripts build a number of containers which are then used to build final 14 | Godot tools, templates and server packages for several platforms. 15 | 16 | Once these containers are built, they can be used to compile different Godot 17 | versions without the need of recreating them. 18 | 19 | The `upload.sh` file is meant to be used by Godot Release Team and is not 20 | documented here. 21 | 22 | 23 | ## Requirements 24 | 25 | These containers have been tested under currently supported Fedora releases 26 | (other distros may work too). 27 | 28 | The tool used to build and manage the containers is `podman` (install it with 29 | `dnf -y podman`). 30 | 31 | We currently use `podman` as root to build and use these containers. Documenting 32 | a workflow to configure the host OS to be able to do all this without root would 33 | be welcome (but back when we tried we ran into performance issues). 34 | 35 | 36 | ## Usage 37 | 38 | The `build.sh` script included is used to build the containers themselves. 39 | 40 | The two arguments can take any value and are meant to convey what Godot branch 41 | you are building for (e.g. `4.5`) and what Linux distribution the `Dockerfile.base` 42 | is based on (e.g. `f42` for Fedora 42). 43 | 44 | Run the command using: 45 | 46 | ./build.sh 4.5 f42 47 | 48 | The above will generate images using the tag '4.5-f42'. 49 | You can then specify it in the `build.sh` of 50 | [godot-build-scripts](https://github.com/godotengine/godot-build-scripts). 51 | 52 | 53 | ### Selecting which images to build 54 | 55 | If you don't need to build all versions or you want to try with a single target OS first, 56 | you can comment out the corresponding lines from the script: 57 | 58 | podman_build linux 59 | podman_build windows 60 | podman_build web 61 | podman_build android 62 | ... 63 | 64 | 65 | ## Image sizes 66 | 67 | These are the expected container image sizes, so you can plan your disk usage in advance: 68 | 69 | REPOSITORY TAG SIZE 70 | localhost/godot-fedora 4.5-f42 949 MB 71 | localhost/godot-linux 4.5-f42 2.74 GB 72 | localhost/godot-windows 4.5-f42 2.54 GB 73 | localhost/godot-web 4.5-f42 2.35 GB 74 | localhost/godot-android 4.5-f42 4.19 GB 75 | localhost/godot-osx 4.5-f42 5.30 GB 76 | localhost/godot-appleembedded 4.5-f42 14.1 GB 77 | 78 | In addition to this, generating containers will also require some host disk space 79 | (up to 10 GB) for the dependencies (Xcode). 80 | 81 | 82 | ## Toolchains 83 | 84 | These are the toolchains currently in use for Godot 4.3 and later: 85 | 86 | - Base image: Fedora 42 87 | - SCons: 4.9.1 88 | - Linux: GCC 13.2.0 built against glibc 2.28, binutils 2.40, from our own [Linux SDK](https://github.com/godotengine/buildroot) 89 | - Windows: 90 | * x86_64/x86_32: MinGW 12.0.0, GCC 14.2.1, binutils 2.43.1 91 | * arm64: llvm-mingw 20250528, LLVM 20.1.6 92 | - Web: Emscripten 4.0.10 93 | - Android: Android NDK 28.1.13356709, build-tools 35.0.0, platform android-35, CMake 3.31.6, JDK 21 94 | - Apple: Xcode 16.4 with Apple Clang (LLVM 19.1.4), cctools 1024.3, ld64 955.13 95 | * macOS: MacOSX SDK 15.5 96 | * Apple Embedded: iPhoneOS and iPhoneSimulator SDKs 18.5, AppleTVOS and AppleTVSimulator SDKs 18.5, XROS and XRSimulator SDKs 2.5 97 | -------------------------------------------------------------------------------- /files/swift/create-sdk-bundle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | if [ $# -lt 2 ]; then 5 | echo "Usage: $0 " 6 | echo "Example: $0 /path/to/Xcode.app/Contents/Developer ./sdk-bundle" 7 | exit 1 8 | fi 9 | 10 | DEV_DIR="$1" 11 | OUTPUT="$2/darwin.artifactbundle" 12 | 13 | echo "Creating artifact bundle at $OUTPUT" 14 | mkdir -p "$OUTPUT" 15 | 16 | # Find SDKs 17 | find_sdk() { 18 | local platform=$1 19 | local prefix=$2 20 | local sdk_dir="$DEV_DIR/Platforms/$platform.platform/Developer/SDKs" 21 | ls -1 "$sdk_dir" 2>/dev/null | grep "^$prefix[0-9]" | head -1 || echo "" 22 | } 23 | 24 | IOS_SDK=$(find_sdk "iPhoneOS" "iPhoneOS") 25 | SIM_SDK=$(find_sdk "iPhoneSimulator" "iPhoneSimulator") 26 | MAC_SDK=$(find_sdk "MacOSX" "MacOSX") 27 | TVOS_SDK=$(find_sdk "AppleTVOS" "AppleTVOS") 28 | TVSIM_SDK=$(find_sdk "AppleTVSimulator" "AppleTVSimulator") 29 | XROS_SDK=$(find_sdk "XROS" "XROS") 30 | XRSIM_SDK=$(find_sdk "XRSimulator" "XRSimulator") 31 | 32 | echo "Found SDKs:" 33 | [ -n "$IOS_SDK" ] && echo " iOS: $IOS_SDK" 34 | [ -n "$SIM_SDK" ] && echo " iOS Sim: $SIM_SDK" 35 | [ -n "$MAC_SDK" ] && echo " macOS: $MAC_SDK" 36 | [ -n "$TVOS_SDK" ] && echo " tvOS: $TVOS_SDK" 37 | [ -n "$TVSIM_SDK" ] && echo " tvOS Sim: $TVSIM_SDK" 38 | [ -n "$XROS_SDK" ] && echo " visionOS: $XROS_SDK" 39 | [ -n "$XRSIM_SDK" ] && echo " visionOS Sim: $XRSIM_SDK" 40 | 41 | # Symlink Developer directory 42 | ln -sf "$DEV_DIR" "$OUTPUT/Developer" 43 | 44 | # Generate info.json 45 | cat > "$OUTPUT/info.json" < "$OUTPUT/toolset.json" < "$OUTPUT/swift-sdk.json" <> "$OUTPUT/swift-sdk.json" 92 | first=false 93 | cat >> "$OUTPUT/swift-sdk.json" <> "$OUTPUT/swift-sdk.json" < 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #ifdef __APPLE__ 15 | #include 16 | #endif 17 | 18 | #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 19 | #include 20 | #endif 21 | 22 | #ifdef __OpenBSD__ 23 | #include 24 | #include 25 | #include 26 | #endif 27 | 28 | char *get_executable_path(char *epath, size_t buflen) 29 | { 30 | char *p; 31 | #ifdef __APPLE__ 32 | unsigned int l = buflen; 33 | if (_NSGetExecutablePath(epath, &l) != 0) return NULL; 34 | #elif defined(__FreeBSD__) || defined(__DragonFly__) 35 | int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; 36 | size_t l = buflen; 37 | if (sysctl(mib, 4, epath, &l, NULL, 0) != 0) return NULL; 38 | #elif defined(__OpenBSD__) 39 | int mib[4]; 40 | char **argv; 41 | size_t len; 42 | size_t l; 43 | const char *comm; 44 | int ok = 0; 45 | mib[0] = CTL_KERN; 46 | mib[1] = KERN_PROC_ARGS; 47 | mib[2] = getpid(); 48 | mib[3] = KERN_PROC_ARGV; 49 | if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) 50 | abort(); 51 | if (!(argv = malloc(len))) 52 | abort(); 53 | if (sysctl(mib, 4, argv, &len, NULL, 0) < 0) 54 | abort(); 55 | comm = argv[0]; 56 | if (*comm == '/' || *comm == '.') 57 | { 58 | char *rpath; 59 | if ((rpath = realpath(comm, NULL))) 60 | { 61 | strlcpy(epath, rpath, buflen); 62 | free(rpath); 63 | ok = 1; 64 | } 65 | } 66 | else 67 | { 68 | char *sp; 69 | char *xpath = strdup(getenv("PATH")); 70 | char *path = strtok_r(xpath, ":", &sp); 71 | struct stat st; 72 | if (!xpath) 73 | abort(); 74 | while (path) 75 | { 76 | snprintf(epath, buflen, "%s/%s", path, comm); 77 | if (!stat(epath, &st) && (st.st_mode & S_IXUSR)) 78 | { 79 | ok = 1; 80 | break; 81 | } 82 | path = strtok_r(NULL, ":", &sp); 83 | } 84 | free(xpath); 85 | } 86 | free(argv); 87 | if (!ok) return NULL; 88 | l = strlen(epath); 89 | #else 90 | ssize_t l = readlink("/proc/self/exe", epath, buflen - 1); 91 | if (l > 0) epath[l] = '\0'; 92 | #endif 93 | if (l <= 0) return NULL; 94 | epath[buflen - 1] = '\0'; 95 | p = strrchr(epath, '/'); 96 | if (p) *p = '\0'; 97 | return epath; 98 | } 99 | 100 | char *get_filename(char *str) 101 | { 102 | char *p = strrchr(str, '/'); 103 | return p ? &p[1] : str; 104 | } 105 | 106 | void target_info(char *argv[], char **triple, char **compiler) 107 | { 108 | char *p = get_filename(argv[0]); 109 | char *x = strrchr(p, '-'); 110 | if (!x) abort(); 111 | *compiler = &x[1]; 112 | *x = '\0'; 113 | *triple = p; 114 | } 115 | 116 | void env(char **p, const char *name, char *fallback) 117 | { 118 | char *ev = getenv(name); 119 | if (ev) { *p = ev; return; } 120 | *p = fallback; 121 | } 122 | 123 | int main(int argc, char *argv[]) 124 | { 125 | char **args = alloca(sizeof(char*) * (argc+12)); 126 | int i, j; 127 | 128 | char execpath[PATH_MAX+1]; 129 | 130 | char *compiler; 131 | char *target; 132 | char *cpu = TARGET_CPU; 133 | 134 | target_info(argv, &target, &compiler); 135 | if (!get_executable_path(execpath, sizeof(execpath))) abort(); 136 | 137 | for (i = 1; i < argc; ++i) 138 | { 139 | if (!strcmp(argv[i], "-arch")) 140 | { 141 | cpu = NULL; 142 | break; 143 | } 144 | } 145 | 146 | i = 0; 147 | 148 | args[i++] = compiler; 149 | args[i++] = "-target"; 150 | args[i++] = target; 151 | 152 | if (cpu) 153 | { 154 | args[i++] = "-arch"; 155 | args[i++] = cpu; 156 | } 157 | 158 | args[i++] = "-mlinker-version=955.13"; 159 | args[i++] = "-Wl,-adhoc_codesign"; 160 | args[i++] = "-Wno-unused-command-line-argument"; 161 | 162 | for (j = 1; j < argc; ++i, ++j) 163 | args[i] = argv[j]; 164 | 165 | args[i] = NULL; 166 | 167 | setenv("COMPILER_PATH", execpath, 1); 168 | execvp(compiler, args); 169 | 170 | fprintf(stderr, "cannot invoke compiler!\n"); 171 | return 1; 172 | } 173 | -------------------------------------------------------------------------------- /files/appleembedded/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | export LC_ALL=C 4 | pushd "${0%/*}" &>/dev/null 5 | 6 | PLATFORM=$(uname -s) 7 | OPERATING_SYSTEM=$(uname -o || echo "-") 8 | 9 | if [ $OPERATING_SYSTEM == "Android" ]; then 10 | export CC="clang -D__ANDROID_API__=26" 11 | export CXX="clang++ -D__ANDROID_API__=26" 12 | fi 13 | 14 | if [ -z "$LLVM_DSYMUTIL" ]; then 15 | if command -v llvm-dsymutil &>/dev/null; then 16 | LLVM_DSYMUTIL=llvm-dsymutil 17 | else 18 | LLVM_DSYMUTIL=dsymutil 19 | fi 20 | fi 21 | 22 | if [ -z "$JOBS" ]; then 23 | JOBS=$(nproc 2>/dev/null || ncpus 2>/dev/null || echo 1) 24 | fi 25 | 26 | set -e 27 | 28 | function verbose_cmd 29 | { 30 | echo "$@" 31 | eval "$@" 32 | } 33 | 34 | function git_clone_repository 35 | { 36 | local url=$1 37 | local branch=$2 38 | local directory 39 | 40 | directory=$(basename $url) 41 | directory=${directory/\.git/} 42 | 43 | if [ -n "$CCTOOLS_IOS_DEV" ]; then 44 | rm -rf $directory 45 | cp -r $CCTOOLS_IOS_DEV/$directory . 46 | return 47 | fi 48 | 49 | if [ ! -d $directory ]; then 50 | local args="" 51 | test "$branch" = "master" && args="--depth 1" 52 | git clone $url $args 53 | fi 54 | 55 | pushd $directory &>/dev/null 56 | 57 | git reset --hard 58 | git clean -fdx 59 | git checkout $branch 60 | git pull origin $branch 61 | 62 | popd &>/dev/null 63 | } 64 | 65 | 66 | if [ $# -lt 1 ]; then 67 | echo "usage: $0 " 1>&2 68 | echo "i.e. $0 arm64" 1>&2 69 | exit 1 70 | fi 71 | 72 | TARGET_CPU="$1" 73 | if [ "$TARGET_CPU" != "arm64" ] && [ "$TARGET_CPU" != "x86_64" ]; then 74 | echo "target cpu must be either 'arm64' or 'x86_64'" 1>&2 75 | exit 1 76 | fi 77 | 78 | if [ "$TARGET_CPU" == "arm64" ]; then 79 | TRIPLE="arm-apple-darwin11" 80 | else 81 | TRIPLE="x86_64-apple-darwin11" 82 | fi 83 | 84 | TARGETDIR="$PWD/target" 85 | 86 | if [ -d $TARGETDIR ]; then 87 | echo "cleaning up ..." 88 | rm -rf $TARGETDIR 89 | fi 90 | 91 | mkdir -p $TARGETDIR 92 | mkdir -p $TARGETDIR/bin 93 | 94 | echo "" 95 | echo "*** building wrapper ***" 96 | echo "" 97 | 98 | OK=0 99 | 100 | set +e 101 | version=$(echo "$($LLVM_DSYMUTIL --version 2>&1)" | grep -oP 'LLVM version \K[^\s]+') 102 | 103 | if [ $? -eq 0 ]; then 104 | major_version=$(echo "$version" | awk -F'\\.' '{print $1}') 105 | minor_version=$(echo "$version" | awk -F'\\.' '{print $2}') 106 | if ((major_version > 3 || (major_version == 3 && minor_version >= 8))); then 107 | OK=1 108 | 109 | if [ "$LLVM_DSYMUTIL" == "llvm-dsymutil" ]; then 110 | ln -sf "$(command -v $LLVM_DSYMUTIL)" "$TARGETDIR/bin/dsymutil" 111 | fi 112 | fi 113 | fi 114 | set -e 115 | 116 | if [ $OK -ne 1 ]; then 117 | echo "int main(){return 0;}" | cc -xc -O2 -o $TARGETDIR/bin/dsymutil - 118 | fi 119 | 120 | pushd $TARGETDIR/bin &>/dev/null 121 | ln -sf $TRIPLE-lipo lipo 122 | popd &>/dev/null 123 | 124 | verbose_cmd cc -O2 -Wall -Wextra -pedantic wrapper.c \ 125 | -DTARGET_CPU=\"\\\"${TARGET_CPU}\\\"\" \ 126 | -o $TARGETDIR/bin/$TRIPLE-clang 127 | 128 | pushd $TARGETDIR/bin &>/dev/null 129 | verbose_cmd ln -sf $TRIPLE-clang $TRIPLE-clang++ 130 | popd &>/dev/null 131 | 132 | rm -rf tmp 133 | mkdir -p tmp 134 | 135 | echo "" 136 | echo "*** building ldid ***" 137 | echo "" 138 | 139 | pushd tmp &>/dev/null 140 | git_clone_repository https://github.com/tpoechtrager/ldid.git master 141 | pushd ldid &>/dev/null 142 | make INSTALLPREFIX=$TARGETDIR -j$JOBS install 143 | popd &>/dev/null 144 | popd &>/dev/null 145 | 146 | echo "" 147 | echo "*** building apple-libdispatch ***" 148 | echo "" 149 | 150 | pushd tmp &>/dev/null 151 | git_clone_repository https://github.com/tpoechtrager/apple-libdispatch.git main 152 | pushd apple-libdispatch &>/dev/null 153 | mkdir -p build 154 | pushd build &>/dev/null 155 | CC=clang CXX=clang++ \ 156 | cmake .. -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=$TARGETDIR 157 | make install -j$JOBS 158 | popd &>/dev/null 159 | popd &>/dev/null 160 | popd &>/dev/null 161 | 162 | echo "" 163 | echo "*** building apple-libtapi ***" 164 | echo "" 165 | 166 | pushd tmp &>/dev/null 167 | git_clone_repository https://github.com/tpoechtrager/apple-libtapi.git 1300.6.5 168 | pushd apple-libtapi &>/dev/null 169 | INSTALLPREFIX=$TARGETDIR ./build.sh 170 | ./install.sh 171 | popd &>/dev/null 172 | popd &>/dev/null 173 | 174 | echo "" 175 | echo "*** building cctools / ld64 ***" 176 | echo "" 177 | 178 | pushd ../../cctools &>/dev/null 179 | git clean -fdx &>/dev/null || true 180 | popd &>/dev/null 181 | 182 | pushd tmp &>/dev/null 183 | mkdir -p cctools 184 | pushd cctools &>/dev/null 185 | ../../../../cctools/configure \ 186 | --target=$TRIPLE \ 187 | --prefix=$TARGETDIR \ 188 | --with-libtapi=$TARGETDIR \ 189 | --with-libdispatch=$TARGETDIR \ 190 | --with-libblocksruntime=$TARGETDIR 191 | make -j$JOBS && make install 192 | popd &>/dev/null 193 | popd &>/dev/null 194 | 195 | 196 | echo "" 197 | echo "*** all done ***" 198 | -------------------------------------------------------------------------------- /files/patches/osxcross-fix-visionos.patch: -------------------------------------------------------------------------------- 1 | diff --git a/build_clang.sh b/build_clang.sh 2 | index 0d9c36b..57d967e 100755 3 | --- a/build_clang.sh 4 | +++ b/build_clang.sh 5 | @@ -149,6 +149,15 @@ if [ $GITPROJECT == "apple" ]; then 6 | # lld has been broken by this PR: 7 | # https://github.com/swiftlang/llvm-project/pull/8119 8 | patch -p1 < $PATCH_DIR/unbreak-apple-lld.patch || true 9 | + 10 | + if ([[ $CLANG_VERSION == 19* ]]); then 11 | + # availability attributes for visionos / xros don't respect being derived from iOS 12 | + # and this patch fixes that 13 | + # 14 | + # https://github.com/swiftlang/llvm-project/issues/10782 15 | + patch -p1 < $PATCH_DIR/xros-availability-clang.patch || true 16 | + fi 17 | + 18 | popd &>/dev/null 19 | fi 20 | 21 | diff --git a/build_compiler_rt.sh b/build_compiler_rt.sh 22 | index da64909..feb9990 100755 23 | --- a/build_compiler_rt.sh 24 | +++ b/build_compiler_rt.sh 25 | @@ -98,6 +98,16 @@ fi 26 | get_sources https://github.com/llvm/llvm-project.git $BRANCH "compiler-rt" 27 | 28 | if [ $f_res -eq 1 ]; then 29 | + if [ $(osxcross-cmp $CLANG_VERSION ">=" 19.0) -eq 1 ]; then 30 | + pushd "$CURRENT_BUILD_PROJECT_NAME" 31 | + # availability attributes for visionos / xros don't respect being derived from iOS 32 | + # and this patch fixes that 33 | + # 34 | + # https://github.com/swiftlang/llvm-project/issues/10782 35 | + patch -p1 < $PATCH_DIR/xros-availability-clang.patch || true 36 | + popd 37 | + fi 38 | + 39 | pushd "$CURRENT_BUILD_PROJECT_NAME/compiler-rt" &>/dev/null 40 | 41 | if [ $(osxcross-cmp $SDK_VERSION "<=" 10.11) -eq 1 ]; then 42 | diff --git a/patches/xros-availability-clang.patch b/patches/xros-availability-clang.patch 43 | new file mode 100644 44 | index 0000000..2666a18 45 | --- /dev/null 46 | +++ b/patches/xros-availability-clang.patch 47 | @@ -0,0 +1,71 @@ 48 | +diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h 49 | +index db20b968a..33b36f53c 100644 50 | +--- a/clang/include/clang/Basic/DarwinSDKInfo.h 51 | ++++ b/clang/include/clang/Basic/DarwinSDKInfo.h 52 | +@@ -72,6 +72,13 @@ public: 53 | + llvm::Triple::TvOS, llvm::Triple::UnknownEnvironment); 54 | + } 55 | + 56 | ++ /// Returns the os-environment mapping pair that's used to represent the 57 | ++ /// iOS -> visionOS version mapping. 58 | ++ static inline constexpr OSEnvPair iOStoXROSPair() { 59 | ++ return OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, 60 | ++ llvm::Triple::XROS, llvm::Triple::UnknownEnvironment); 61 | ++ } 62 | ++ 63 | + private: 64 | + StorageType Value; 65 | + 66 | +diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp 67 | +index e2eada24f..26290b3ba 100644 68 | +--- a/clang/lib/Sema/SemaDeclAttr.cpp 69 | ++++ b/clang/lib/Sema/SemaDeclAttr.cpp 70 | +@@ -2415,6 +2415,48 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { 71 | + auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version); 72 | + auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version); 73 | + 74 | ++ AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( 75 | ++ ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, 76 | ++ NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, 77 | ++ Sema::AMK_None, PriorityModifier + Sema::AP_InferredFromOtherPlatform, 78 | ++ IIEnvironment); 79 | ++ if (NewAttr) 80 | ++ D->addAttr(NewAttr); 81 | ++ } 82 | ++ } else if (S.Context.getTargetInfo().getTriple().isXROS()) { 83 | ++ // Transcribe "ios" to "visionos" (and add a new attribute) if the versioning 84 | ++ // matches before the start of the visionOS platform. 85 | ++ IdentifierInfo *NewII = nullptr; 86 | ++ if (II->getName() == "ios") 87 | ++ NewII = &S.Context.Idents.get("xros"); 88 | ++ else if (II->getName() == "ios_app_extension") 89 | ++ NewII = &S.Context.Idents.get("xros_app_extension"); 90 | ++ 91 | ++ if (NewII) { 92 | ++ const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); 93 | ++ const auto *IOSToXROSMapping = 94 | ++ SDKInfo ? SDKInfo->getVersionMapping( 95 | ++ DarwinSDKInfo::OSEnvPair::iOStoXROSPair()) 96 | ++ : nullptr; 97 | ++ 98 | ++ auto AdjustTvOSVersion = 99 | ++ [IOSToXROSMapping](VersionTuple Version) -> VersionTuple { 100 | ++ if (Version.empty()) 101 | ++ return Version; 102 | ++ 103 | ++ if (IOSToXROSMapping) { 104 | ++ if (auto MappedVersion = IOSToXROSMapping->map( 105 | ++ Version, VersionTuple(1, 0), std::nullopt)) { 106 | ++ return *MappedVersion; 107 | ++ } 108 | ++ } 109 | ++ return Version; 110 | ++ }; 111 | ++ 112 | ++ auto NewIntroduced = AdjustTvOSVersion(Introduced.Version); 113 | ++ auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version); 114 | ++ auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version); 115 | ++ 116 | + AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr( 117 | + ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated, 118 | + NewObsoleted, IsUnavailable, Str, IsStrict, Replacement, 119 | --------------------------------------------------------------------------------