This page documents how Godot's build system identifies target platforms and configures the compiler and linker environment for each one. It covers the detect.py interface that every platform must implement, how SConstruct loads and invokes those scripts, and the per-platform configuration details.
For information about global build options and the overall SCons setup, see Build Configuration. For how modules integrate with the platform system, see Module System.
Every supported target platform has a subdirectory under platform/ that contains a detect.py file. SConstruct scans all of these directories, invokes their detection functions to discover which platforms are buildable on the current host, and then calls the selected platform's configure() function to set compiler binaries, flags, and linked libraries.
Supported platforms and their directories:
| Platform name | Directory | Notes |
|---|---|---|
windows | platform/windows/ | Native MSVC or cross-compile with MinGW |
linuxbsd | platform/linuxbsd/ | Linux and BSDs |
macos | platform/macos/ | Native or OSXCross cross-compile |
android | platform/android/ | Requires Android SDK/NDK |
ios | platform/ios/ | Requires Xcode or OSXCROSS_IOS |
web | platform/web/ | Emscripten target |
Each detect.py must implement a set of functions. SConstruct calls them in a specific order across two passes.
Required functions:
| Function | Return type | Purpose |
|---|---|---|
get_name() | str | Human-readable platform name |
can_build() | bool | Whether this platform can be built on the current host |
get_opts() | list | Platform-specific SCons Variables entries |
get_flags() | dict | Default values for existing global flags |
configure(env) | None | Mutates the SCons environment to set up the toolchain |
Optional functions:
| Function | Return type | Purpose |
|---|---|---|
get_tools(env) | list[str] | SCons tool names to load (e.g. ["msvc", "mslink"]) |
get_doc_classes() | list[str] | Editor export class names for doc generation |
get_doc_path() | str | Relative path to doc XML files |
Two-pass invocation diagram:
Diagram: Two-pass detect.py invocation in SConstruct
Sources: SConstruct77-109 SConstruct499-509 SConstruct694
SConstruct iterates over platform/*/ subdirectories. For any directory that contains a detect.py, it temporarily adds that directory to sys.path, imports the module, and calls:
detect.can_build() — If False, the platform is skipped.detect.get_opts() — Options are accumulated into platform_opts[x].detect.get_flags() — Defaults are accumulated into platform_flags[x].detect.get_doc_classes() / detect.get_doc_path() — Paths are stored for the editor doc generator.This builds the platform_list, platform_opts, and platform_flags collections.
If no platform= argument is passed, SConstruct infers the target from sys.platform:
sys.platform starts with "linux" / "dragonfly" / "freebsd" / "netbsd" / "openbsd" → "linuxbsd"
sys.platform == "darwin" → "macos"
sys.platform == "win32" → "windows"
platform_methods.py defines old platform names that are remapped to current ones:
| Old name | Current name |
|---|---|
osx | macos |
iphone | ios |
x11 | linuxbsd |
javascript | web |
platform_methods.py12-17 SConstruct394-405
After the platform is confirmed and options are applied, SConstruct does a second import of the selected platform's detect.py to call get_tools(env) and then configure(env).
SConstruct499-509 SConstruct694
platform_methods.py is the central location for CPU architecture logic, shared by all platforms.
detect_arch() reads platform.machine() and maps it to a canonical architecture name.
validate_arch(arch, platform_name, supported_arches) aborts the build with an error if the requested arch is not in the platform's supported list.
Canonical architecture names and their aliases:
| Canonical name | Accepted aliases |
|---|---|
x86_32 | x86, i386, i486, i586, i686 |
x86_64 | x64, amd64 |
arm32 | armv7, armv8 (32-bit) |
arm64 | armv8, arm64v8, aarch64 |
rv64 | rv, riscv, riscv64 |
ppc64 | ppc64le |
wasm32 | — |
wasm64 | — |
loongarch64 | loong64 |
platform_methods.py20-48 platform_methods.py51-57
Diagram: Architecture detection call chain
Sources: platform_methods.py37-57 SConstruct167
Diagram: What configure() does in each platform detect.py
Sources: platform/windows/detect.py243-519 platform/linuxbsd/detect.py74-530 platform/macos/detect.py69-280 platform/android/detect.py117-244 platform/ios/detect.py59-193 platform/web/detect.py103-353
can_build() returns True if either os.name == "nt" (native Windows) or a gcc/clang cross-compiler is found in MINGW_PREFIX on POSIX.
get_tools(env) selects the toolchain:
["msvc", "mslink", "mslib"], sets env["TARGET_ARCH"] and env["MSVC_VERSION"]["mingw"]configure(env) branches into configure_msvc(env) or configure_mingw(env).
configure_msvc() key actions:
/MD or /MT for CRT linkingWINDOWS_ENABLED, WASAPI_ENABLED, WINMIDI_ENABLED defineswinmm, dsound, kernel32, ole32, d3d12, etc.)noneconfigure_mingw() key actions:
CC/CXX/AR/AS using get_detected(env, tool)-Wl,--subsystem,windows or consolelto=auto) resolves to thin (Clang) or full (GCC)platform/windows/detect.py49-61 platform/windows/detect.py152-162 platform/windows/detect.py243-519 platform/windows/detect.py588-740
Notable get_flags() defaults for Windows:
platform/windows/detect.py233-240
can_build() requires POSIX non-Darwin and a working pkg-config.
configure(env) does extensive library probing. When use_sowrap=yes (the default), system library headers are loaded from thirdparty/linuxbsd_headers/ and linked at runtime rather than compile time, making binaries more portable. When use_sowrap=no, pkg-config is called directly for each library.
Key conditional feature flags set by configure():
| Option | Defines set | Libraries linked |
|---|---|---|
x11=yes | X11_ENABLED | x11, xcursor, xinerama, xrandr, xi |
wayland=yes | (Wayland server enabled) | wayland-client, wayland-scanner |
alsa=yes | ALSA_ENABLED, ALSAMIDI_ENABLED | alsa |
pulseaudio=yes | PULSEAUDIO_ENABLED | libpulse |
udev=yes | UDEV_ENABLED | libudev |
dbus=yes | DBUS_ENABLED | dbus-1 |
fontconfig=yes | FONTCONFIG_ENABLED | fontconfig |
LTO default (lto=auto): thin if using LLVM, full if using GCC.
platform/linuxbsd/detect.py17-27 platform/linuxbsd/detect.py74-530
can_build() returns True on sys.platform == "darwin" or if OSXCROSS_ROOT is set (cross-compiling from Linux).
configure(env) selects compilers based on context:
clang/clang++, calls detect_darwin_sdk_path("macos", env) via xcrunmacports_clang option to find an alternate ClangOSXCROSS_ROOT and osxcross_sdkArchitecture minimum OS versions enforced:
arm64 → macOS 11.0+ (-mmacosx-version-min=11.0)x86_64 → macOS 10.13+ (-mmacosx-version-min=10.13)LTO default: none (benefits not established for macOS).
platform/macos/detect.py20-24 platform/macos/detect.py69-280
can_build() checks for the ANDROID_HOME environment variable (or ANDROID_SDK_ROOT).
configure(env) calls install_ndk_if_needed(env) which downloads the required NDK version via sdkmanager if absent. NDK version is fixed in get_ndk_version().
Target triples used per architecture:
| arch | target triple |
|---|---|
arm32 | armv7a-linux-androideabi |
arm64 | aarch64-linux-android |
x86_32 | i686-linux-android |
x86_64 | x86_64-linux-android |
Compiler binaries come from <ndk_root>/toolchains/llvm/prebuilt/<host>/bin/. Minimum API level is defined by get_min_target_api().
LTO default: none.
platform/android/detect.py18-19 platform/android/detect.py117-244
can_build() requires sys.platform == "darwin" or OSXCROSS_IOS in the environment.
configure(env) uses detect_darwin_toolchain_path(env) and detect_darwin_sdk_path(env["APPLE_PLATFORM"], env) from methods.py to locate the Xcode toolchain and SDK.
The simulator=yes option changes the Apple platform string and adds -mios-simulator-version-min=14.0. Metal is disabled automatically for the iOS Simulator.
platform/ios/detect.py16-18 platform/ios/detect.py59-193
can_build() checks if emcc (Emscripten compiler) is on PATH using WhereIs("emcc").
configure(env) sets the full Emscripten toolchain:
env["CC"] = "emcc", env["CXX"] = "em++", env["AR"] = "emar", env["RANLIB"] = "emranlib"Notable Web-specific get_flags() defaults:
"arch": "wasm32""vulkan": False"optimize": "size" (overrides the default speed to reduce download size)"module_raycast_enabled": False (Embree too heavy for WASM)Thread support requires SharedArrayBuffer and uses -sUSE_PTHREADS=1. The dlink_enabled option enables GDExtension support via WebAssembly dynamic linking.
platform/web/detect.py29-30 platform/web/detect.py76-92 platform/web/detect.py103-353
platform_methods.py is a shared utility module imported by SConstruct and several detect.py files. It is not platform-specific but contains functions used across platforms:
| Function | Used by |
|---|---|
detect_arch() | linuxbsd, macos, windows detect.py |
validate_arch(arch, name, supported) | all detect.py configure() functions |
detect_mvk(env, osname) | macos detect.py (MoltenVK search) |
lipo(prefix, suffix) | macos/ios bundle generation |
combine_libs_apple_embedded(...) | iOS bundle generation |
generate_bundle_apple_embedded(...) | iOS/macOS bundle generation |
compatibility_platform_aliases | SConstruct (alias remapping) |
architectures | SConstruct (EnumVariable choices) |
architecture_aliases | SConstruct (EnumVariable aliases) |
Diagram: Full platform detection and configuration flow
Sources: SConstruct77-109 SConstruct374-433 SConstruct499-509 SConstruct694
Refresh this wiki
This wiki was recently refreshed. Please wait 3 days to refresh again.