mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-03 20:03:50 +00:00
feat: add multi-platform Docker build system for Linux, macOS, and Windows
Replace the single Ubuntu-based container build with a dedicated Dockerfile, build script, and launcher for each target platform. Infrastructure: - Add .dockerignore to minimize Docker build context - Add container/builder-linux.Dockerfile (Ubuntu 24.04, GCC, native build) - Add container/builder-macos.Dockerfile (multi-stage: SDK fetcher + osxcross/Clang 18) - Add container/builder-windows.Dockerfile (LLVM-MinGW 20240619, vcpkg) - Add container/macos/sdk-fetcher.py (auto-fetch macOS SDK from Apple catalog) - Add container/macos/osxcross-toolchain.cmake (auto-detecting CMake toolchain) - Add container/macos/triplets/arm64-osx-cross.cmake - Add container/macos/triplets/x64-osx-cross.cmake - Remove container/builder-ubuntu.Dockerfile (replaced by per-platform Dockerfiles) - Remove container/build-in-container.sh and container/build-wowee.sh (replaced) Build scripts (run inside containers): - Add container/build-linux.sh (tar copy, FidelityFX clone, cmake/ninja) - Add container/build-macos.sh (arch detection, vcpkg triplet, cross-compile) - Add container/build-windows.sh (Vulkan import lib via dlltool, cross-compile) Launcher scripts (run on host): - Add container/run-linux.sh, run-macos.sh, run-windows.sh (bash) - Add container/run-linux.ps1, run-macos.ps1, run-windows.ps1 (PowerShell) Documentation: - Add container/README.md (quick start, options, file structure, troubleshooting) - Add container/FLOW.md (comprehensive build flow for each platform) CMake changes: - Add macOS cross-compile support (VulkanHeaders, -undefined dynamic_lookup) - Add LLVM-MinGW/Windows cross-compile support - Detect osxcross toolchain and vcpkg triplets Other: - Update vcpkg.json with ffmpeg feature flags - Update resources/wowee.rc version string
This commit is contained in:
parent
c1c28d4216
commit
85f8d05061
25 changed files with 1881 additions and 74 deletions
50
.dockerignore
Normal file
50
.dockerignore
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# .dockerignore — Exclude files from the Docker build context.
|
||||||
|
# Keeps the context small and prevents leaking build artifacts or secrets.
|
||||||
|
|
||||||
|
# Build outputs
|
||||||
|
build/
|
||||||
|
cache/
|
||||||
|
|
||||||
|
# Git history
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
.github/
|
||||||
|
|
||||||
|
# Large external directories (fetched at build time inside the container)
|
||||||
|
extern/FidelityFX-FSR2/
|
||||||
|
extern/FidelityFX-SDK/
|
||||||
|
|
||||||
|
# IDE / editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Documentation (not needed for build)
|
||||||
|
docs/
|
||||||
|
*.md
|
||||||
|
!container/*.md
|
||||||
|
|
||||||
|
# Test / tool outputs
|
||||||
|
logs/
|
||||||
|
|
||||||
|
# Host build scripts that run outside the container (not needed inside)
|
||||||
|
build.sh
|
||||||
|
build.bat
|
||||||
|
build.ps1
|
||||||
|
rebuild.sh
|
||||||
|
rebuild.bat
|
||||||
|
rebuild.ps1
|
||||||
|
clean.sh
|
||||||
|
debug_texture.*
|
||||||
|
extract_assets.*
|
||||||
|
extract_warden_rsa.py
|
||||||
|
restart-worldserver.sh
|
||||||
|
test.sh
|
||||||
|
|
||||||
|
# macOS SDK tarballs that may be temporarily placed here
|
||||||
|
*.tar.xz
|
||||||
|
*.tar.gz
|
||||||
|
*.tar.bz2
|
||||||
102
CMakeLists.txt
102
CMakeLists.txt
|
|
@ -248,28 +248,98 @@ endif()
|
||||||
find_package(SDL2 REQUIRED)
|
find_package(SDL2 REQUIRED)
|
||||||
find_package(Vulkan QUIET)
|
find_package(Vulkan QUIET)
|
||||||
if(NOT Vulkan_FOUND)
|
if(NOT Vulkan_FOUND)
|
||||||
# Fallback: some distros / CMake versions need pkg-config to locate Vulkan.
|
# For Windows cross-compilation the host pkg-config finds the Linux libvulkan-dev
|
||||||
find_package(PkgConfig QUIET)
|
# and injects /usr/include as an INTERFACE_INCLUDE_DIRECTORY, which causes
|
||||||
if(PkgConfig_FOUND)
|
# MinGW clang to pull in glibc headers (bits/libc-header-start.h) instead of
|
||||||
pkg_check_modules(VULKAN_PKG vulkan)
|
# the MinGW sysroot headers. Skip the host pkg-config path entirely and instead
|
||||||
if(VULKAN_PKG_FOUND)
|
# locate Vulkan via vcpkg-installed vulkan-headers or the MinGW toolchain.
|
||||||
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
|
if(CMAKE_CROSSCOMPILING AND WIN32)
|
||||||
set_target_properties(Vulkan::Vulkan PROPERTIES
|
# The cross-compile build script generates a Vulkan import library
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${VULKAN_PKG_INCLUDE_DIRS}"
|
# (libvulkan-1.a) in ${CMAKE_BINARY_DIR}/vulkan-import from the headers.
|
||||||
INTERFACE_LINK_LIBRARIES "${VULKAN_PKG_LIBRARIES}"
|
set(_VULKAN_IMPORT_DIR "${CMAKE_BINARY_DIR}/vulkan-import")
|
||||||
)
|
|
||||||
if(VULKAN_PKG_LIBRARY_DIRS)
|
find_package(VulkanHeaders CONFIG QUIET)
|
||||||
|
if(VulkanHeaders_FOUND)
|
||||||
|
if(NOT TARGET Vulkan::Vulkan)
|
||||||
|
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
|
||||||
|
endif()
|
||||||
|
# Vulkan::Headers is provided by vcpkg's vulkan-headers port and carries
|
||||||
|
# the correct MinGW include path — no Linux system headers involved.
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_LIBRARIES Vulkan::Headers)
|
||||||
|
# Link against the Vulkan loader import library (vulkan-1.dll).
|
||||||
|
if(EXISTS "${_VULKAN_IMPORT_DIR}/libvulkan-1.a")
|
||||||
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
INTERFACE_LINK_DIRECTORIES "${VULKAN_PKG_LIBRARY_DIRS}")
|
INTERFACE_LINK_DIRECTORIES "${_VULKAN_IMPORT_DIR}")
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_LIBRARIES vulkan-1)
|
||||||
endif()
|
endif()
|
||||||
set(Vulkan_FOUND TRUE)
|
set(Vulkan_FOUND TRUE)
|
||||||
message(STATUS "Found Vulkan via pkg-config: ${VULKAN_PKG_LIBRARIES}")
|
message(STATUS "Found Vulkan headers for Windows cross-compile via vcpkg VulkanHeaders")
|
||||||
|
else()
|
||||||
|
# Last-resort: check the LLVM-MinGW toolchain sysroot directly.
|
||||||
|
find_path(_VULKAN_MINGW_INCLUDE NAMES vulkan/vulkan.h
|
||||||
|
PATHS /opt/llvm-mingw/x86_64-w64-mingw32/include NO_DEFAULT_PATH)
|
||||||
|
if(_VULKAN_MINGW_INCLUDE)
|
||||||
|
if(NOT TARGET Vulkan::Vulkan)
|
||||||
|
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
|
||||||
|
endif()
|
||||||
|
set_target_properties(Vulkan::Vulkan PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${_VULKAN_MINGW_INCLUDE}")
|
||||||
|
# Link against the Vulkan loader import library (vulkan-1.dll).
|
||||||
|
if(EXISTS "${_VULKAN_IMPORT_DIR}/libvulkan-1.a")
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_DIRECTORIES "${_VULKAN_IMPORT_DIR}")
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_LIBRARIES vulkan-1)
|
||||||
|
endif()
|
||||||
|
set(Vulkan_FOUND TRUE)
|
||||||
|
message(STATUS "Found Vulkan headers in LLVM-MinGW sysroot: ${_VULKAN_MINGW_INCLUDE}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
elseif(CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
# macOS cross-compilation: use vcpkg-installed vulkan-headers.
|
||||||
|
# The host pkg-config would find Linux libvulkan-dev headers which the
|
||||||
|
# macOS cross-compiler cannot use (different sysroot).
|
||||||
|
find_package(VulkanHeaders CONFIG QUIET)
|
||||||
|
if(VulkanHeaders_FOUND)
|
||||||
|
if(NOT TARGET Vulkan::Vulkan)
|
||||||
|
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
|
||||||
|
endif()
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_LIBRARIES Vulkan::Headers)
|
||||||
|
set(Vulkan_FOUND TRUE)
|
||||||
|
message(STATUS "Found Vulkan headers for macOS cross-compile via vcpkg VulkanHeaders")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# Fallback: some distros / CMake versions need pkg-config to locate Vulkan.
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
if(PkgConfig_FOUND)
|
||||||
|
pkg_check_modules(VULKAN_PKG vulkan)
|
||||||
|
if(VULKAN_PKG_FOUND)
|
||||||
|
add_library(Vulkan::Vulkan INTERFACE IMPORTED)
|
||||||
|
set_target_properties(Vulkan::Vulkan PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${VULKAN_PKG_INCLUDE_DIRS}"
|
||||||
|
INTERFACE_LINK_LIBRARIES "${VULKAN_PKG_LIBRARIES}"
|
||||||
|
)
|
||||||
|
if(VULKAN_PKG_LIBRARY_DIRS)
|
||||||
|
set_property(TARGET Vulkan::Vulkan APPEND PROPERTY
|
||||||
|
INTERFACE_LINK_DIRECTORIES "${VULKAN_PKG_LIBRARY_DIRS}")
|
||||||
|
endif()
|
||||||
|
set(Vulkan_FOUND TRUE)
|
||||||
|
message(STATUS "Found Vulkan via pkg-config: ${VULKAN_PKG_LIBRARIES}")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(NOT Vulkan_FOUND)
|
if(NOT Vulkan_FOUND)
|
||||||
message(FATAL_ERROR "Could not find Vulkan. Install libvulkan-dev (Linux), vulkan-loader (macOS), or the Vulkan SDK (Windows).")
|
message(FATAL_ERROR "Could not find Vulkan. Install libvulkan-dev (Linux), vulkan-loader (macOS), or the Vulkan SDK (Windows).")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
# macOS cross-compilation: the Vulkan loader (MoltenVK) is not available at link
|
||||||
|
# time. Allow unresolved Vulkan symbols — they are resolved at runtime.
|
||||||
|
if(CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
add_link_options("-undefined" "dynamic_lookup")
|
||||||
|
endif()
|
||||||
# GL/GLEW kept temporarily for unconverted sub-renderers during Vulkan migration.
|
# GL/GLEW kept temporarily for unconverted sub-renderers during Vulkan migration.
|
||||||
# These files compile against GL types but their code is never called — the Vulkan
|
# These files compile against GL types but their code is never called — the Vulkan
|
||||||
# path is the only active rendering backend. Remove in Phase 7 when all renderers
|
# path is the only active rendering backend. Remove in Phase 7 when all renderers
|
||||||
|
|
@ -674,12 +744,16 @@ set(WOWEE_HEADERS
|
||||||
|
|
||||||
set(WOWEE_PLATFORM_SOURCES)
|
set(WOWEE_PLATFORM_SOURCES)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
# Copy icon into build tree so llvm-rc can find it via the relative path in wowee.rc
|
# Copy icon into build tree so windres can find it via the relative path
|
||||||
|
# in wowee.rc ("assets\\wowee.ico"). Tell the RC compiler to also search
|
||||||
|
# the build directory — GNU windres uses cwd (already the build dir) but
|
||||||
|
# llvm-windres resolves relative to the .rc file, so it needs the hint.
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/assets/Wowee.ico
|
${CMAKE_CURRENT_SOURCE_DIR}/assets/Wowee.ico
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/assets/wowee.ico
|
${CMAKE_CURRENT_BINARY_DIR}/assets/wowee.ico
|
||||||
COPYONLY
|
COPYONLY
|
||||||
)
|
)
|
||||||
|
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -I ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
list(APPEND WOWEE_PLATFORM_SOURCES resources/wowee.rc)
|
list(APPEND WOWEE_PLATFORM_SOURCES resources/wowee.rc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
283
container/FLOW.md
Normal file
283
container/FLOW.md
Normal file
|
|
@ -0,0 +1,283 @@
|
||||||
|
# Container Build Flow
|
||||||
|
|
||||||
|
Comprehensive documentation of the Docker-based build pipeline for each target platform.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
Each platform follows the same two-phase pattern:
|
||||||
|
|
||||||
|
1. **Image Build** (one-time, cached by Docker) — installs compilers, toolchains, and pre-builds vcpkg dependencies.
|
||||||
|
2. **Container Run** (each build) — copies source into the container, runs CMake configure + build, outputs artifacts to the host.
|
||||||
|
|
||||||
|
```
|
||||||
|
Host Docker
|
||||||
|
─────────────────────────────────────────────────────────────
|
||||||
|
run-{platform}.sh/.ps1
|
||||||
|
│
|
||||||
|
├─ docker build builder-{platform}.Dockerfile
|
||||||
|
│ (cached after first run) ├─ install compilers
|
||||||
|
│ ├─ install vcpkg + packages
|
||||||
|
│ └─ COPY build-{platform}.sh
|
||||||
|
│
|
||||||
|
└─ docker run build-{platform}.sh (entrypoint)
|
||||||
|
├─ bind /src (readonly) ├─ tar copy source → /wowee-build-src
|
||||||
|
└─ bind /out (writable) ├─ git clone FidelityFX SDKs
|
||||||
|
├─ cmake -S . -B /out
|
||||||
|
├─ cmake --build /out
|
||||||
|
└─ artifacts appear in /out
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Linux Build Flow
|
||||||
|
|
||||||
|
**Image:** `wowee-builder-linux`
|
||||||
|
**Dockerfile:** `builder-linux.Dockerfile`
|
||||||
|
**Toolchain:** GCC + Ninja (native amd64)
|
||||||
|
**Base:** Ubuntu 24.04
|
||||||
|
|
||||||
|
### Docker Image Build Steps
|
||||||
|
|
||||||
|
| Step | What | Why |
|
||||||
|
|------|------|-----|
|
||||||
|
| 1 | `apt-get install` cmake, ninja-build, build-essential, pkg-config, git, python3 | Core build tools |
|
||||||
|
| 2 | `apt-get install` glslang-tools, spirv-tools | Vulkan shader compilation |
|
||||||
|
| 3 | `apt-get install` libsdl2-dev, libglew-dev, libglm-dev, libssl-dev, zlib1g-dev | Runtime dependencies (system packages) |
|
||||||
|
| 4 | `apt-get install` libavformat-dev, libavcodec-dev, libswscale-dev, libavutil-dev | FFmpeg libraries |
|
||||||
|
| 5 | `apt-get install` libvulkan-dev, vulkan-tools | Vulkan SDK |
|
||||||
|
| 6 | `apt-get install` libstorm-dev, libunicorn-dev | MPQ archive + CPU emulation |
|
||||||
|
| 7 | COPY `build-linux.sh` → `/build-platform.sh` | Container entrypoint |
|
||||||
|
|
||||||
|
### Container Run Steps (build-linux.sh)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. tar copy /src → /wowee-build-src (excludes build/, .git/, large Data/ dirs)
|
||||||
|
2. git clone FidelityFX-FSR2 (if missing)
|
||||||
|
3. git clone FidelityFX-SDK (if missing)
|
||||||
|
4. cmake configure:
|
||||||
|
-G Ninja
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
-DCMAKE_C_COMPILER=gcc
|
||||||
|
-DCMAKE_CXX_COMPILER=g++
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON
|
||||||
|
5. cmake --build (parallel)
|
||||||
|
6. Create Data symlink: build/linux/bin/Data → ../../../Data
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output
|
||||||
|
- `build/linux/bin/wowee` — ELF 64-bit x86-64 executable
|
||||||
|
- `build/linux/bin/Data` — symlink to project Data/ directory
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## macOS Build Flow
|
||||||
|
|
||||||
|
**Image:** `wowee-builder-macos`
|
||||||
|
**Dockerfile:** `builder-macos.Dockerfile` (multi-stage)
|
||||||
|
**Toolchain:** osxcross (Clang 18 + Apple ld64)
|
||||||
|
**Base:** Ubuntu 24.04
|
||||||
|
**Targets:** arm64-apple-darwin24.5 (default), x86_64-apple-darwin24.5
|
||||||
|
|
||||||
|
### Docker Image Build — Stage 1: SDK Fetcher
|
||||||
|
|
||||||
|
The macOS SDK is fetched automatically from Apple's public software update catalog.
|
||||||
|
No manual download required.
|
||||||
|
|
||||||
|
| Step | What | Why |
|
||||||
|
|------|------|-----|
|
||||||
|
| 1 | `FROM ubuntu:24.04 AS sdk-fetcher` | Lightweight stage for SDK download |
|
||||||
|
| 2 | `apt-get install` ca-certificates, python3, cpio, tar, gzip, xz-utils | SDK extraction tools |
|
||||||
|
| 3 | COPY `macos/sdk-fetcher.py` → `/opt/sdk-fetcher.py` | Python script that scrapes Apple's SUCATALOG |
|
||||||
|
| 4 | `python3 /opt/sdk-fetcher.py /opt/sdk` | Downloads, extracts, and packages MacOSX15.5.sdk.tar.gz |
|
||||||
|
|
||||||
|
**SDK Fetcher internals** (`macos/sdk-fetcher.py`):
|
||||||
|
1. Queries Apple SUCATALOG URLs for the latest macOS package
|
||||||
|
2. Downloads the `CLTools_macOSNMOS_SDK.pkg` package
|
||||||
|
3. Extracts the XAR archive (using `bsdtar` or pure-Python fallback)
|
||||||
|
4. Decompresses the PBZX payload stream
|
||||||
|
5. Extracts via `cpio` to get the SDK directory
|
||||||
|
6. Packages as `MacOSX<version>.sdk.tar.gz`
|
||||||
|
|
||||||
|
### Docker Image Build — Stage 2: Builder
|
||||||
|
|
||||||
|
| Step | What | Why |
|
||||||
|
|------|------|-----|
|
||||||
|
| 1 | `FROM ubuntu:24.04 AS builder` | Full build environment |
|
||||||
|
| 2 | `apt-get install` cmake, ninja-build, git, python3, curl, wget, xz-utils, zip, unzip, tar, make, patch, libssl-dev, zlib1g-dev, pkg-config, libbz2-dev, libxml2-dev, uuid-dev | Build tools + osxcross build deps |
|
||||||
|
| 3 | Install Clang 18 from LLVM apt repo (`llvm-toolchain-jammy-18`) | Cross-compiler backend |
|
||||||
|
| 4 | Symlink clang-18 → clang, clang++-18 → clang++, etc. | osxcross expects unversioned names |
|
||||||
|
| 5 | `git clone osxcross` → `/opt/osxcross` | Apple cross-compile toolchain wrapper |
|
||||||
|
| 6 | `COPY --from=sdk-fetcher /opt/sdk/ → /opt/osxcross/tarballs/` | SDK from stage 1 |
|
||||||
|
| 7 | `UNATTENDED=1 ./build.sh` | Builds osxcross (LLVM wrappers + cctools + ld64) |
|
||||||
|
| 8 | Create unprefixed symlinks (install_name_tool, otool, lipo, codesign) | vcpkg/CMake need these without arch prefix |
|
||||||
|
| 9 | COPY `macos/osxcross-toolchain.cmake` → `/opt/osxcross-toolchain.cmake` | Auto-detecting CMake toolchain |
|
||||||
|
| 10 | COPY `macos/triplets/` → `/opt/vcpkg-triplets/` | vcpkg cross-compile triplet definitions |
|
||||||
|
| 11 | `apt-get install` file, nasm | Mach-O detection + ffmpeg x86 asm |
|
||||||
|
| 12 | Bootstrap vcpkg → `/opt/vcpkg` | Package manager |
|
||||||
|
| 13 | `vcpkg install` sdl2, openssl, glew, glm, zlib, ffmpeg `--triplet arm64-osx-cross` | arm64 dependencies |
|
||||||
|
| 14 | `vcpkg install` same packages `--triplet x64-osx-cross` | x86_64 dependencies |
|
||||||
|
| 15 | `apt-get install` libvulkan-dev, glslang-tools | Vulkan headers (for compilation, not runtime) |
|
||||||
|
| 16 | COPY `build-macos.sh` → `/build-platform.sh` | Container entrypoint |
|
||||||
|
|
||||||
|
### Custom Toolchain Files
|
||||||
|
|
||||||
|
**`macos/osxcross-toolchain.cmake`** — Auto-detecting CMake toolchain:
|
||||||
|
- Detects SDK path via `file(GLOB)` in `/opt/osxcross/target/SDK/MacOSX*.sdk`
|
||||||
|
- Detects darwin version from compiler binary names (e.g., `arm64-apple-darwin24.5-clang`)
|
||||||
|
- Picks architecture from `CMAKE_OSX_ARCHITECTURES`
|
||||||
|
- Sets `CMAKE_C_COMPILER`, `CMAKE_CXX_COMPILER`, `CMAKE_AR`, `CMAKE_RANLIB`, `CMAKE_STRIP`
|
||||||
|
|
||||||
|
**`macos/triplets/arm64-osx-cross.cmake`**:
|
||||||
|
```cmake
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE static)
|
||||||
|
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||||
|
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE /opt/osxcross-toolchain.cmake)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Container Run Steps (build-macos.sh)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Determine arch from MACOS_ARCH env (default: arm64)
|
||||||
|
2. Pick vcpkg triplet: arm64-osx-cross or x64-osx-cross
|
||||||
|
3. Auto-detect darwin target from osxcross binaries
|
||||||
|
4. tar copy /src → /wowee-build-src
|
||||||
|
5. git clone FidelityFX-FSR2 + FidelityFX-SDK (if missing)
|
||||||
|
6. cmake configure:
|
||||||
|
-G Ninja
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
-DCMAKE_SYSTEM_NAME=Darwin
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=${ARCH}
|
||||||
|
-DCMAKE_C_COMPILER=osxcross clang
|
||||||
|
-DCMAKE_CXX_COMPILER=osxcross clang++
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=vcpkg.cmake
|
||||||
|
-DVCPKG_TARGET_TRIPLET=arm64-osx-cross
|
||||||
|
-DVCPKG_OVERLAY_TRIPLETS=/opt/vcpkg-triplets
|
||||||
|
7. cmake --build (parallel)
|
||||||
|
```
|
||||||
|
|
||||||
|
### CMakeLists.txt Integration
|
||||||
|
|
||||||
|
The main CMakeLists.txt has a macOS cross-compile branch that:
|
||||||
|
- Finds Vulkan headers via vcpkg (`VulkanHeaders` package) instead of the Vulkan SDK
|
||||||
|
- Adds `-undefined dynamic_lookup` linker flag for Vulkan loader symbols (resolved at runtime via MoltenVK)
|
||||||
|
|
||||||
|
### Output
|
||||||
|
- `build/macos/bin/wowee` — Mach-O 64-bit arm64 (or x86_64) executable (~40 MB)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Windows Build Flow
|
||||||
|
|
||||||
|
**Image:** `wowee-builder-windows`
|
||||||
|
**Dockerfile:** `builder-windows.Dockerfile`
|
||||||
|
**Toolchain:** LLVM-MinGW (Clang + LLD) targeting x86_64-w64-mingw32-ucrt
|
||||||
|
**Base:** Ubuntu 24.04
|
||||||
|
|
||||||
|
### Docker Image Build Steps
|
||||||
|
|
||||||
|
| Step | What | Why |
|
||||||
|
|------|------|-----|
|
||||||
|
| 1 | `apt-get install` ca-certificates, build-essential, cmake, ninja-build, git, python3, curl, zip, unzip, tar, xz-utils, pkg-config, nasm, libssl-dev, zlib1g-dev | Build tools |
|
||||||
|
| 2 | Download + extract LLVM-MinGW (v20240619 ucrt) → `/opt/llvm-mingw` | Clang/LLD cross-compiler for Windows |
|
||||||
|
| 3 | Add `/opt/llvm-mingw/bin` to PATH | Makes `x86_64-w64-mingw32-clang` etc. available |
|
||||||
|
| 4 | Bootstrap vcpkg → `/opt/vcpkg` | Package manager |
|
||||||
|
| 5 | `vcpkg install` sdl2, openssl, glew, glm, zlib, ffmpeg `--triplet x64-mingw-static` | Static Windows dependencies |
|
||||||
|
| 6 | `apt-get install` libvulkan-dev, glslang-tools | Vulkan headers + shader tools |
|
||||||
|
| 7 | Create no-op `powershell.exe` stub | vcpkg MinGW post-build hook needs it |
|
||||||
|
| 8 | COPY `build-windows.sh` → `/build-platform.sh` | Container entrypoint |
|
||||||
|
|
||||||
|
### Container Run Steps (build-windows.sh)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Set up no-op powershell.exe (if not already present)
|
||||||
|
2. tar copy /src → /wowee-build-src
|
||||||
|
3. git clone FidelityFX-FSR2 + FidelityFX-SDK (if missing)
|
||||||
|
4. Generate Vulkan import library:
|
||||||
|
a. Extract vk* symbols from vulkan_core.h
|
||||||
|
b. Create vulkan-1.def file
|
||||||
|
c. Run dlltool to create libvulkan-1.a
|
||||||
|
5. Lock PKG_CONFIG_LIBDIR to vcpkg packages only
|
||||||
|
6. cmake configure:
|
||||||
|
-G Ninja
|
||||||
|
-DCMAKE_BUILD_TYPE=Release
|
||||||
|
-DCMAKE_SYSTEM_NAME=Windows
|
||||||
|
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-clang
|
||||||
|
-DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-clang++
|
||||||
|
-DCMAKE_RC_COMPILER=x86_64-w64-mingw32-windres
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE=vcpkg.cmake
|
||||||
|
-DVCPKG_TARGET_TRIPLET=x64-mingw-static
|
||||||
|
-DVCPKG_APPLOCAL_DEPS=OFF
|
||||||
|
7. cmake --build (parallel)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulkan Import Library Generation
|
||||||
|
|
||||||
|
Windows applications link against `vulkan-1.dll` (the Khronos Vulkan loader). Since the LLVM-MinGW toolchain doesn't ship a Vulkan import library, the build script generates one:
|
||||||
|
|
||||||
|
1. Parses `vulkan_core.h` for `VKAPI_CALL vk*` function names
|
||||||
|
2. Creates a `.def` file mapping symbols to `vulkan-1.dll`
|
||||||
|
3. Uses `dlltool` to produce `libvulkan-1.a` (PE import library)
|
||||||
|
|
||||||
|
This allows the linker to resolve Vulkan symbols at build time, while deferring actual loading to the runtime DLL.
|
||||||
|
|
||||||
|
### Output
|
||||||
|
- `build/windows/bin/wowee.exe` — PE32+ x86-64 executable (~135 MB)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Patterns
|
||||||
|
|
||||||
|
### Source Tree Copy
|
||||||
|
|
||||||
|
All three platforms use the same tar-based copy with exclusions:
|
||||||
|
```bash
|
||||||
|
tar -C /src \
|
||||||
|
--exclude='./build' --exclude='./logs' --exclude='./cache' \
|
||||||
|
--exclude='./container' --exclude='./.git' \
|
||||||
|
--exclude='./Data/character' --exclude='./Data/creature' \
|
||||||
|
--exclude='./Data/db' --exclude='./Data/environment' \
|
||||||
|
--exclude='./Data/interface' --exclude='./Data/item' \
|
||||||
|
--exclude='./Data/misc' --exclude='./Data/sound' \
|
||||||
|
--exclude='./Data/spell' --exclude='./Data/terrain' \
|
||||||
|
--exclude='./Data/world' \
|
||||||
|
-cf - . | tar -C /wowee-build-src -xf -
|
||||||
|
```
|
||||||
|
|
||||||
|
**Kept:** `Data/opcodes/`, `Data/expansions/` (small, needed at build time for configuration).
|
||||||
|
**Excluded:** Large game asset directories (character, creature, environment, etc.) not needed for compilation.
|
||||||
|
|
||||||
|
### FidelityFX SDK Fetch
|
||||||
|
|
||||||
|
All platforms clone the same two repos at build time:
|
||||||
|
1. **FidelityFX-FSR2** — FSR 2.0 upscaling
|
||||||
|
2. **FidelityFX-SDK** — FSR 3.0 frame generation (repo URL/ref configurable via env vars)
|
||||||
|
|
||||||
|
### .dockerignore
|
||||||
|
|
||||||
|
The `.dockerignore` at the project root minimizes the Docker build context by excluding:
|
||||||
|
- `build/`, `cache/`, `logs/`, `.git/`
|
||||||
|
- Large external dirs (`extern/FidelityFX-*`)
|
||||||
|
- IDE files, documentation, host-only scripts
|
||||||
|
- SDK tarballs (`*.tar.xz`, `*.tar.gz`, etc.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Timing Estimates
|
||||||
|
|
||||||
|
These are approximate times on a 4-core machine with 16 GB RAM:
|
||||||
|
|
||||||
|
| Phase | Linux | macOS | Windows |
|
||||||
|
|-------|-------|-------|---------|
|
||||||
|
| Docker image build (first time) | ~5 min | ~25 min | ~15 min |
|
||||||
|
| Docker image build (cached) | seconds | seconds | seconds |
|
||||||
|
| Source copy + SDK fetch | ~10 sec | ~10 sec | ~10 sec |
|
||||||
|
| CMake configure | ~20 sec | ~30 sec | ~30 sec |
|
||||||
|
| Compilation | ~8 min | ~8 min | ~8 min |
|
||||||
|
| **Total (first build)** | **~14 min** | **~34 min** | **~24 min** |
|
||||||
|
| **Total (subsequent)** | **~9 min** | **~9 min** | **~9 min** |
|
||||||
|
|
||||||
|
macOS image is slowest because osxcross builds a subset of LLVM + cctools, and vcpkg packages are compiled for two architectures (arm64 + x64).
|
||||||
119
container/README.md
Normal file
119
container/README.md
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
# Container Builds
|
||||||
|
|
||||||
|
Build WoWee for **Linux**, **macOS**, or **Windows** with a single command.
|
||||||
|
All builds run inside Docker — no toolchains to install on your host.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- [Docker](https://docs.docker.com/get-docker/) (Docker Desktop on Windows/macOS, or Docker Engine on Linux)
|
||||||
|
- ~20 GB free disk space (toolchains + vcpkg packages are cached in the Docker image)
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
Run **from the project root directory**.
|
||||||
|
|
||||||
|
### Linux (native amd64)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Bash / Linux / macOS terminal
|
||||||
|
./container/run-linux.sh
|
||||||
|
```
|
||||||
|
```powershell
|
||||||
|
# PowerShell (Windows)
|
||||||
|
.\container\run-linux.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Output: `build/linux/bin/wowee`
|
||||||
|
|
||||||
|
### macOS (cross-compile, arm64 default)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./container/run-macos.sh
|
||||||
|
```
|
||||||
|
```powershell
|
||||||
|
.\container\run-macos.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Output: `build/macos/bin/wowee`
|
||||||
|
|
||||||
|
For Intel (x86_64):
|
||||||
|
```bash
|
||||||
|
MACOS_ARCH=x86_64 ./container/run-macos.sh
|
||||||
|
```
|
||||||
|
```powershell
|
||||||
|
.\container\run-macos.ps1 -Arch x86_64
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows (cross-compile, x86_64)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./container/run-windows.sh
|
||||||
|
```
|
||||||
|
```powershell
|
||||||
|
.\container\run-windows.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Output: `build/windows/bin/wowee.exe`
|
||||||
|
|
||||||
|
## Options
|
||||||
|
|
||||||
|
| Option | Bash | PowerShell | Description |
|
||||||
|
|--------|------|------------|-------------|
|
||||||
|
| Rebuild image | `--rebuild-image` | `-RebuildImage` | Force a fresh Docker image build |
|
||||||
|
| macOS arch | `MACOS_ARCH=x86_64` | `-Arch x86_64` | Build for Intel instead of Apple Silicon |
|
||||||
|
| FidelityFX SDK repo | `WOWEE_FFX_SDK_REPO=<url>` | `$env:WOWEE_FFX_SDK_REPO="<url>"` | Custom FidelityFX SDK git URL |
|
||||||
|
| FidelityFX SDK ref | `WOWEE_FFX_SDK_REF=<ref>` | `$env:WOWEE_FFX_SDK_REF="<ref>"` | Custom FidelityFX SDK git ref/tag |
|
||||||
|
|
||||||
|
## Docker Image Caching
|
||||||
|
|
||||||
|
The first build takes longer because Docker builds the toolchain image (installing compilers, vcpkg packages, etc.). Subsequent builds reuse the cached image and only run the compilation step.
|
||||||
|
|
||||||
|
To force a full image rebuild:
|
||||||
|
```bash
|
||||||
|
./container/run-linux.sh --rebuild-image
|
||||||
|
```
|
||||||
|
|
||||||
|
## Output Locations
|
||||||
|
|
||||||
|
| Target | Binary | Size |
|
||||||
|
|--------|--------|------|
|
||||||
|
| Linux | `build/linux/bin/wowee` | ~135 MB |
|
||||||
|
| macOS | `build/macos/bin/wowee` | ~40 MB |
|
||||||
|
| Windows | `build/windows/bin/wowee.exe` | ~135 MB |
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
container/
|
||||||
|
├── run-linux.sh / .ps1 # Host launchers (bash / PowerShell)
|
||||||
|
├── run-macos.sh / .ps1
|
||||||
|
├── run-windows.sh / .ps1
|
||||||
|
├── build-linux.sh # Container entrypoints (run inside Docker)
|
||||||
|
├── build-macos.sh
|
||||||
|
├── build-windows.sh
|
||||||
|
├── builder-linux.Dockerfile # Docker image definitions
|
||||||
|
├── builder-macos.Dockerfile
|
||||||
|
├── builder-windows.Dockerfile
|
||||||
|
├── macos/
|
||||||
|
│ ├── sdk-fetcher.py # Auto-fetches macOS SDK from Apple's catalog
|
||||||
|
│ ├── osxcross-toolchain.cmake # CMake toolchain for osxcross
|
||||||
|
│ └── triplets/ # vcpkg cross-compile triplets
|
||||||
|
│ ├── arm64-osx-cross.cmake
|
||||||
|
│ └── x64-osx-cross.cmake
|
||||||
|
├── README.md # This file
|
||||||
|
└── FLOW.md # Detailed build flow documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**"docker is not installed or not in PATH"**
|
||||||
|
Install Docker and ensure the `docker` command is available in your terminal.
|
||||||
|
|
||||||
|
**Build fails on first run**
|
||||||
|
Some vcpkg packages (ffmpeg, SDL2) take a while to compile. Ensure you have enough RAM (4 GB+) and disk space.
|
||||||
|
|
||||||
|
**macOS build: "could not find osxcross compiler"**
|
||||||
|
The Docker image may not have built correctly. Run with `--rebuild-image` to rebuild from scratch.
|
||||||
|
|
||||||
|
**Windows build: linker errors about vulkan-1.dll**
|
||||||
|
The build script auto-generates a Vulkan import library. If this fails, ensure the Docker image has `libvulkan-dev` installed (it should, by default).
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
||||||
|
|
||||||
podman build \
|
|
||||||
-f "${SCRIPT_DIR}/builder-ubuntu.Dockerfile" \
|
|
||||||
-t wowee-builder-ubuntu
|
|
||||||
|
|
||||||
BUILD_DIR="$(mktemp --tmpdir -d wowee.XXXXX \
|
|
||||||
--suffix=".$(cd "${PROJECT_ROOT}"; git rev-parse --short HEAD)")"
|
|
||||||
podman run \
|
|
||||||
--mount "type=bind,src=${PROJECT_ROOT},dst=/WoWee-src,ro=true" \
|
|
||||||
--mount "type=bind,src=${BUILD_DIR},dst=/build" \
|
|
||||||
localhost/wowee-builder-ubuntu \
|
|
||||||
./build-wowee.sh
|
|
||||||
62
container/build-linux.sh
Executable file
62
container/build-linux.sh
Executable file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Linux amd64 build entrypoint — runs INSIDE the linux container.
|
||||||
|
# Bind-mounts:
|
||||||
|
# /src (ro) — project source
|
||||||
|
# /out (rw) — host ./build/linux
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SRC=/src
|
||||||
|
OUT=/out
|
||||||
|
NPROC=$(nproc)
|
||||||
|
|
||||||
|
echo "==> [linux] Copying source tree..."
|
||||||
|
tar -C "${SRC}" \
|
||||||
|
--exclude='./build' --exclude='./logs' --exclude='./cache' \
|
||||||
|
--exclude='./container' --exclude='./.git' \
|
||||||
|
--exclude='./Data/character' --exclude='./Data/creature' \
|
||||||
|
--exclude='./Data/db' --exclude='./Data/environment' \
|
||||||
|
--exclude='./Data/interface' --exclude='./Data/item' \
|
||||||
|
--exclude='./Data/misc' --exclude='./Data/sound' \
|
||||||
|
--exclude='./Data/spell' --exclude='./Data/terrain' \
|
||||||
|
--exclude='./Data/world' \
|
||||||
|
-cf - . | tar -C /wowee-build-src -xf -
|
||||||
|
|
||||||
|
cd /wowee-build-src
|
||||||
|
|
||||||
|
echo "==> [linux] Fetching external SDKs (if needed)..."
|
||||||
|
if [ ! -f extern/FidelityFX-FSR2/src/ffx-fsr2-api/ffx_fsr2.h ]; then
|
||||||
|
git clone --depth 1 \
|
||||||
|
https://github.com/GPUOpen-Effects/FidelityFX-FSR2.git \
|
||||||
|
extern/FidelityFX-FSR2 || echo "Warning: FSR2 clone failed — continuing without FSR2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SDK_REPO="${WOWEE_FFX_SDK_REPO:-https://github.com/Kelsidavis/FidelityFX-SDK.git}"
|
||||||
|
SDK_REF="${WOWEE_FFX_SDK_REF:-main}"
|
||||||
|
if [ ! -f "extern/FidelityFX-SDK/sdk/include/FidelityFX/host/ffx_frameinterpolation.h" ]; then
|
||||||
|
git clone --depth 1 --branch "${SDK_REF}" "${SDK_REPO}" extern/FidelityFX-SDK \
|
||||||
|
|| echo "Warning: FidelityFX-SDK clone failed — continuing without FSR3"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [linux] Configuring with CMake (Release, Ninja, amd64)..."
|
||||||
|
cmake -S . -B "${OUT}" \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_C_COMPILER=gcc \
|
||||||
|
-DCMAKE_CXX_COMPILER=g++ \
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON
|
||||||
|
|
||||||
|
echo "==> [linux] Building with ${NPROC} cores..."
|
||||||
|
cmake --build "${OUT}" --parallel "${NPROC}"
|
||||||
|
|
||||||
|
echo "==> [linux] Creating Data symlink..."
|
||||||
|
mkdir -p "${OUT}/bin"
|
||||||
|
if [ ! -e "${OUT}/bin/Data" ]; then
|
||||||
|
# Relative symlink so it resolves correctly on the host:
|
||||||
|
# build/linux/bin/Data -> ../../../Data (project root)
|
||||||
|
ln -s ../../../Data "${OUT}/bin/Data"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==> [linux] Build complete. Artifacts in: ./build/linux/"
|
||||||
|
echo " Binary: ./build/linux/bin/wowee"
|
||||||
83
container/build-macos.sh
Executable file
83
container/build-macos.sh
Executable file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# macOS cross-compile entrypoint — runs INSIDE the macos container.
|
||||||
|
# Toolchain: osxcross + Apple Clang, target: arm64-apple-darwin (default) or
|
||||||
|
# x86_64-apple-darwin when MACOS_ARCH=x86_64.
|
||||||
|
# Bind-mounts:
|
||||||
|
# /src (ro) — project source
|
||||||
|
# /out (rw) — host ./build/macos
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SRC=/src
|
||||||
|
OUT=/out
|
||||||
|
NPROC=$(nproc)
|
||||||
|
|
||||||
|
# Arch selection: arm64 (Apple Silicon) is the default primary target.
|
||||||
|
ARCH="${MACOS_ARCH:-arm64}"
|
||||||
|
case "${ARCH}" in
|
||||||
|
arm64) VCPKG_TRIPLET=arm64-osx-cross ;;
|
||||||
|
x86_64) VCPKG_TRIPLET=x64-osx-cross ;;
|
||||||
|
*) echo "ERROR: unsupported MACOS_ARCH '${ARCH}'. Use arm64 or x86_64." ; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Auto-detect darwin target from osxcross binaries (e.g. arm64-apple-darwin24.5).
|
||||||
|
OSXCROSS_BIN=/opt/osxcross/target/bin
|
||||||
|
TARGET=$(basename "$(ls "${OSXCROSS_BIN}/${ARCH}-apple-darwin"*-clang 2>/dev/null | head -1)" | sed 's/-clang$//')
|
||||||
|
if [[ -z "${TARGET}" ]]; then
|
||||||
|
echo "ERROR: could not find osxcross ${ARCH} compiler in ${OSXCROSS_BIN}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "==> Detected osxcross target: ${TARGET}"
|
||||||
|
|
||||||
|
echo "==> [macos/${ARCH}] Copying source tree..."
|
||||||
|
mkdir -p /wowee-build-src
|
||||||
|
tar -C "${SRC}" \
|
||||||
|
--exclude='./build' --exclude='./logs' --exclude='./cache' \
|
||||||
|
--exclude='./container' --exclude='./.git' \
|
||||||
|
--exclude='./Data/character' --exclude='./Data/creature' \
|
||||||
|
--exclude='./Data/db' --exclude='./Data/environment' \
|
||||||
|
--exclude='./Data/interface' --exclude='./Data/item' \
|
||||||
|
--exclude='./Data/misc' --exclude='./Data/sound' \
|
||||||
|
--exclude='./Data/spell' --exclude='./Data/terrain' \
|
||||||
|
--exclude='./Data/world' \
|
||||||
|
-cf - . | tar -C /wowee-build-src -xf -
|
||||||
|
|
||||||
|
cd /wowee-build-src
|
||||||
|
|
||||||
|
echo "==> [macos/${ARCH}] Fetching external SDKs (if needed)..."
|
||||||
|
if [ ! -f extern/FidelityFX-FSR2/src/ffx-fsr2-api/ffx_fsr2.h ]; then
|
||||||
|
git clone --depth 1 \
|
||||||
|
https://github.com/GPUOpen-Effects/FidelityFX-FSR2.git \
|
||||||
|
extern/FidelityFX-FSR2 || echo "Warning: FSR2 clone failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SDK_REPO="${WOWEE_FFX_SDK_REPO:-https://github.com/Kelsidavis/FidelityFX-SDK.git}"
|
||||||
|
SDK_REF="${WOWEE_FFX_SDK_REF:-main}"
|
||||||
|
if [ ! -f "extern/FidelityFX-SDK/sdk/include/FidelityFX/host/ffx_frameinterpolation.h" ]; then
|
||||||
|
git clone --depth 1 --branch "${SDK_REF}" "${SDK_REPO}" extern/FidelityFX-SDK \
|
||||||
|
|| echo "Warning: FidelityFX-SDK clone failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [macos/${ARCH}] Configuring with CMake (Release, Ninja, osxcross ${TARGET})..."
|
||||||
|
cmake -S . -B "${OUT}" \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_SYSTEM_NAME=Darwin \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES="${ARCH}" \
|
||||||
|
-DCMAKE_OSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET:-13.0}" \
|
||||||
|
-DCMAKE_C_COMPILER="${OSXCROSS_BIN}/${TARGET}-clang" \
|
||||||
|
-DCMAKE_CXX_COMPILER="${OSXCROSS_BIN}/${TARGET}-clang++" \
|
||||||
|
-DCMAKE_AR="${OSXCROSS_BIN}/${TARGET}-ar" \
|
||||||
|
-DCMAKE_RANLIB="${OSXCROSS_BIN}/${TARGET}-ranlib" \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \
|
||||||
|
-DVCPKG_TARGET_TRIPLET="${VCPKG_TRIPLET}" \
|
||||||
|
-DVCPKG_OVERLAY_TRIPLETS=/opt/vcpkg-triplets \
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
|
||||||
|
-DWOWEE_ENABLE_ASAN=OFF
|
||||||
|
|
||||||
|
echo "==> [macos/${ARCH}] Building with ${NPROC} cores..."
|
||||||
|
cmake --build "${OUT}" --parallel "${NPROC}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==> [macos/${ARCH}] Build complete. Artifacts in: ./build/macos/"
|
||||||
|
echo " Binary: ./build/macos/bin/wowee"
|
||||||
110
container/build-windows.sh
Executable file
110
container/build-windows.sh
Executable file
|
|
@ -0,0 +1,110 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Windows cross-compile entrypoint — runs INSIDE the windows container.
|
||||||
|
# Toolchain: LLVM-MinGW (Clang + LLD), target: x86_64-w64-mingw32-ucrt
|
||||||
|
# Bind-mounts:
|
||||||
|
# /src (ro) — project source
|
||||||
|
# /out (rw) — host ./build/windows
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SRC=/src
|
||||||
|
OUT=/out
|
||||||
|
NPROC=$(nproc)
|
||||||
|
TARGET=x86_64-w64-mingw32
|
||||||
|
|
||||||
|
# vcpkg's MinGW applocal hook always appends a powershell.exe post-build step to
|
||||||
|
# copy DLLs next to each binary, even when VCPKG_APPLOCAL_DEPS=OFF. For the
|
||||||
|
# x64-mingw-static triplet the bin/ dir is empty (no DLLs) so the script does
|
||||||
|
# nothing — but it still needs to exit 0. Provide a no-op stub if the real
|
||||||
|
# PowerShell isn't available.
|
||||||
|
if ! command -v powershell.exe &>/dev/null; then
|
||||||
|
printf '#!/bin/sh\nexit 0\n' > /usr/local/bin/powershell.exe
|
||||||
|
chmod +x /usr/local/bin/powershell.exe
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [windows] Copying source tree..."
|
||||||
|
mkdir -p /wowee-build-src
|
||||||
|
tar -C "${SRC}" \
|
||||||
|
--exclude='./build' --exclude='./logs' --exclude='./cache' \
|
||||||
|
--exclude='./container' --exclude='./.git' \
|
||||||
|
--exclude='./Data/character' --exclude='./Data/creature' \
|
||||||
|
--exclude='./Data/db' --exclude='./Data/environment' \
|
||||||
|
--exclude='./Data/interface' --exclude='./Data/item' \
|
||||||
|
--exclude='./Data/misc' --exclude='./Data/sound' \
|
||||||
|
--exclude='./Data/spell' --exclude='./Data/terrain' \
|
||||||
|
--exclude='./Data/world' \
|
||||||
|
-cf - . | tar -C /wowee-build-src -xf -
|
||||||
|
|
||||||
|
|
||||||
|
cd /wowee-build-src
|
||||||
|
|
||||||
|
echo "==> [windows] Fetching external SDKs (if needed)..."
|
||||||
|
if [ ! -f extern/FidelityFX-FSR2/src/ffx-fsr2-api/ffx_fsr2.h ]; then
|
||||||
|
git clone --depth 1 \
|
||||||
|
https://github.com/GPUOpen-Effects/FidelityFX-FSR2.git \
|
||||||
|
extern/FidelityFX-FSR2 || echo "Warning: FSR2 clone failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SDK_REPO="${WOWEE_FFX_SDK_REPO:-https://github.com/Kelsidavis/FidelityFX-SDK.git}"
|
||||||
|
SDK_REF="${WOWEE_FFX_SDK_REF:-main}"
|
||||||
|
if [ ! -f "extern/FidelityFX-SDK/sdk/include/FidelityFX/host/ffx_frameinterpolation.h" ]; then
|
||||||
|
git clone --depth 1 --branch "${SDK_REF}" "${SDK_REPO}" extern/FidelityFX-SDK \
|
||||||
|
|| echo "Warning: FidelityFX-SDK clone failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [windows] Generating Vulkan import library for cross-compile..."
|
||||||
|
# Windows applications link against vulkan-1.dll (the Khronos Vulkan loader).
|
||||||
|
# The cross-compile toolchain only ships Vulkan *headers* (via vcpkg), not the
|
||||||
|
# import library. Generate a minimal libvulkan-1.a from the header prototypes
|
||||||
|
# so the linker can resolve vk* symbols → vulkan-1.dll at runtime.
|
||||||
|
# We use the host libvulkan-dev header for function name extraction — the Vulkan
|
||||||
|
# API prototypes are platform-independent.
|
||||||
|
VULKAN_IMP_DIR="${OUT}/vulkan-import"
|
||||||
|
if [ ! -f "${VULKAN_IMP_DIR}/libvulkan-1.a" ]; then
|
||||||
|
mkdir -p "${VULKAN_IMP_DIR}"
|
||||||
|
# Try vcpkg-installed header first (available on incremental builds),
|
||||||
|
# then fall back to the host libvulkan-dev header (always present in the image).
|
||||||
|
VK_HEADER="${OUT}/vcpkg_installed/x64-mingw-static/include/vulkan/vulkan_core.h"
|
||||||
|
if [ ! -f "${VK_HEADER}" ]; then
|
||||||
|
VK_HEADER="/usr/include/vulkan/vulkan_core.h"
|
||||||
|
fi
|
||||||
|
{
|
||||||
|
echo "LIBRARY vulkan-1.dll"
|
||||||
|
echo "EXPORTS"
|
||||||
|
grep -oP 'VKAPI_ATTR \S+ VKAPI_CALL \K(vk\w+)' "${VK_HEADER}" | sort -u | sed 's/^/ /'
|
||||||
|
} > "${VULKAN_IMP_DIR}/vulkan-1.def"
|
||||||
|
"${TARGET}-dlltool" -d "${VULKAN_IMP_DIR}/vulkan-1.def" \
|
||||||
|
-l "${VULKAN_IMP_DIR}/libvulkan-1.a" -m i386:x86-64
|
||||||
|
echo " Generated $(wc -l < "${VULKAN_IMP_DIR}/vulkan-1.def") export entries"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "==> [windows] Configuring with CMake (Release, Ninja, LLVM-MinGW cross)..."
|
||||||
|
# Lock pkg-config to the cross-compiled vcpkg packages only.
|
||||||
|
# Without this, CMake's Vulkan pkg-config fallback finds the *Linux* libvulkan-dev
|
||||||
|
# and injects /usr/include into every MinGW compile command, which then fails
|
||||||
|
# because the glibc-specific bits/libc-header-start.h is not in the MinGW sysroot.
|
||||||
|
export PKG_CONFIG_LIBDIR="${OUT}/vcpkg_installed/x64-mingw-static/lib/pkgconfig"
|
||||||
|
export PKG_CONFIG_PATH=""
|
||||||
|
cmake -S . -B "${OUT}" \
|
||||||
|
-G Ninja \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_SYSTEM_NAME=Windows \
|
||||||
|
-DCMAKE_C_COMPILER="${TARGET}-clang" \
|
||||||
|
-DCMAKE_CXX_COMPILER="${TARGET}-clang++" \
|
||||||
|
-DCMAKE_RC_COMPILER="${TARGET}-windres" \
|
||||||
|
-DCMAKE_AR="/opt/llvm-mingw/bin/llvm-ar" \
|
||||||
|
-DCMAKE_RANLIB="/opt/llvm-mingw/bin/llvm-ranlib" \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \
|
||||||
|
-DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" \
|
||||||
|
-DVCPKG_TARGET_TRIPLET=x64-mingw-static \
|
||||||
|
-DVCPKG_APPLOCAL_DEPS=OFF \
|
||||||
|
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=OFF \
|
||||||
|
-DWOWEE_ENABLE_ASAN=OFF
|
||||||
|
|
||||||
|
echo "==> [windows] Building with ${NPROC} cores..."
|
||||||
|
cmake --build "${OUT}" --parallel "${NPROC}"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==> [windows] Build complete. Artifacts in: ./build/windows/"
|
||||||
|
echo " Binary: ./build/windows/bin/wowee.exe"
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
cp -r /WoWee-src /WoWee
|
|
||||||
|
|
||||||
pushd /WoWee
|
|
||||||
./build.sh
|
|
||||||
popd
|
|
||||||
|
|
||||||
pushd /WoWee/build
|
|
||||||
cmake --install . --prefix=/build
|
|
||||||
popd
|
|
||||||
33
container/builder-linux.Dockerfile
Normal file
33
container/builder-linux.Dockerfile
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
FROM ubuntu:24.04
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
build-essential \
|
||||||
|
pkg-config \
|
||||||
|
git \
|
||||||
|
python3 \
|
||||||
|
glslang-tools \
|
||||||
|
spirv-tools \
|
||||||
|
libsdl2-dev \
|
||||||
|
libglew-dev \
|
||||||
|
libglm-dev \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
libavformat-dev \
|
||||||
|
libavcodec-dev \
|
||||||
|
libswscale-dev \
|
||||||
|
libavutil-dev \
|
||||||
|
libvulkan-dev \
|
||||||
|
vulkan-tools \
|
||||||
|
libstorm-dev \
|
||||||
|
libunicorn-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY build-linux.sh /build-platform.sh
|
||||||
|
RUN chmod +x /build-platform.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/build-platform.sh"]
|
||||||
143
container/builder-macos.Dockerfile
Normal file
143
container/builder-macos.Dockerfile
Normal file
|
|
@ -0,0 +1,143 @@
|
||||||
|
FROM ubuntu:24.04 AS sdk-fetcher
|
||||||
|
|
||||||
|
# Stage 1: Fetch macOS SDK from Apple's public software update catalog.
|
||||||
|
# This avoids requiring the user to supply the SDK tarball manually.
|
||||||
|
# The SDK is downloaded, extracted, and packaged as a .tar.gz.
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
python3 \
|
||||||
|
cpio \
|
||||||
|
tar \
|
||||||
|
gzip \
|
||||||
|
xz-utils && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY macos/sdk-fetcher.py /opt/sdk-fetcher.py
|
||||||
|
RUN python3 /opt/sdk-fetcher.py /opt/sdk
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
FROM ubuntu:24.04 AS builder
|
||||||
|
|
||||||
|
# Stage 2: macOS cross-compile image using osxcross + Clang 18.
|
||||||
|
#
|
||||||
|
# Target triplets (auto-detected from osxcross):
|
||||||
|
# arm64-apple-darwinNN (Apple Silicon)
|
||||||
|
# x86_64-apple-darwinNN (Intel)
|
||||||
|
# Default: arm64. Override with MACOS_ARCH=x86_64 env var at run time.
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV OSXCROSS_VERSION=1.5
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
git \
|
||||||
|
python3 \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
xz-utils \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
tar \
|
||||||
|
make \
|
||||||
|
patch \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
pkg-config \
|
||||||
|
libbz2-dev \
|
||||||
|
libxml2-dev \
|
||||||
|
libz-dev \
|
||||||
|
liblzma-dev \
|
||||||
|
uuid-dev \
|
||||||
|
python3-lxml \
|
||||||
|
gnupg \
|
||||||
|
software-properties-common && \
|
||||||
|
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \
|
||||||
|
echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main" > /etc/apt/sources.list.d/llvm-18.list && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
clang-18 \
|
||||||
|
lld-18 \
|
||||||
|
llvm-18 && \
|
||||||
|
ln -sf /usr/bin/clang-18 /usr/bin/clang && \
|
||||||
|
ln -sf /usr/bin/clang++-18 /usr/bin/clang++ && \
|
||||||
|
ln -sf /usr/bin/lld-18 /usr/bin/lld && \
|
||||||
|
ln -sf /usr/bin/ld.lld-18 /usr/bin/ld.lld && \
|
||||||
|
ln -sf /usr/bin/llvm-ar-18 /usr/bin/llvm-ar && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Build osxcross with SDK from stage 1
|
||||||
|
RUN git clone --depth 1 https://github.com/tpoechtrager/osxcross.git /opt/osxcross
|
||||||
|
|
||||||
|
COPY --from=sdk-fetcher /opt/sdk/ /opt/osxcross/tarballs/
|
||||||
|
|
||||||
|
ENV MACOSX_DEPLOYMENT_TARGET=13.0
|
||||||
|
RUN cd /opt/osxcross && \
|
||||||
|
unset OSXCROSS_VERSION && \
|
||||||
|
UNATTENDED=1 ./build.sh && \
|
||||||
|
rm -rf /opt/osxcross/build /opt/osxcross/tarballs
|
||||||
|
|
||||||
|
ENV PATH="/opt/osxcross/target/bin:${PATH}"
|
||||||
|
ENV OSXCROSS_TARGET_DIR="/opt/osxcross/target"
|
||||||
|
ENV MACOSX_DEPLOYMENT_TARGET=13.0
|
||||||
|
|
||||||
|
# Create unprefixed symlinks for macOS tools that vcpkg/CMake expect
|
||||||
|
RUN cd /opt/osxcross/target/bin && \
|
||||||
|
for tool in install_name_tool otool lipo codesign; do \
|
||||||
|
src="$(ls *-apple-darwin*-"${tool}" 2>/dev/null | head -1)"; \
|
||||||
|
if [ -n "$src" ]; then \
|
||||||
|
ln -sf "$src" "$tool"; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# Custom osxcross toolchain + vcpkg triplets
|
||||||
|
COPY macos/osxcross-toolchain.cmake /opt/osxcross-toolchain.cmake
|
||||||
|
COPY macos/triplets/ /opt/vcpkg-triplets/
|
||||||
|
|
||||||
|
# Extra tools needed by vcpkg's Mach-O rpath fixup and ffmpeg x86 asm
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends file nasm && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# vcpkg — macOS cross triplets (arm64-osx-cross / x64-osx-cross)
|
||||||
|
ENV VCPKG_ROOT=/opt/vcpkg
|
||||||
|
RUN git clone --depth 1 https://github.com/microsoft/vcpkg.git "${VCPKG_ROOT}" && \
|
||||||
|
"${VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics
|
||||||
|
|
||||||
|
# Pre-install deps for both arches; the launcher script picks the right one at run time.
|
||||||
|
RUN "${VCPKG_ROOT}/vcpkg" install \
|
||||||
|
sdl2[vulkan] \
|
||||||
|
openssl \
|
||||||
|
glew \
|
||||||
|
glm \
|
||||||
|
zlib \
|
||||||
|
ffmpeg \
|
||||||
|
--triplet arm64-osx-cross \
|
||||||
|
--overlay-triplets=/opt/vcpkg-triplets
|
||||||
|
|
||||||
|
RUN "${VCPKG_ROOT}/vcpkg" install \
|
||||||
|
sdl2[vulkan] \
|
||||||
|
openssl \
|
||||||
|
glew \
|
||||||
|
glm \
|
||||||
|
zlib \
|
||||||
|
ffmpeg \
|
||||||
|
--triplet x64-osx-cross \
|
||||||
|
--overlay-triplets=/opt/vcpkg-triplets
|
||||||
|
|
||||||
|
# Vulkan SDK headers (MoltenVK is the runtime — headers only needed to compile)
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends libvulkan-dev glslang-tools && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
COPY build-macos.sh /build-platform.sh
|
||||||
|
RUN chmod +x /build-platform.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/build-platform.sh"]
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
FROM ubuntu:24.04
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt install -y \
|
|
||||||
cmake \
|
|
||||||
build-essential \
|
|
||||||
pkg-config \
|
|
||||||
git \
|
|
||||||
libsdl2-dev \
|
|
||||||
libglew-dev \
|
|
||||||
libglm-dev \
|
|
||||||
libssl-dev \
|
|
||||||
zlib1g-dev \
|
|
||||||
libavformat-dev \
|
|
||||||
libavcodec-dev \
|
|
||||||
libswscale-dev \
|
|
||||||
libavutil-dev \
|
|
||||||
libvulkan-dev \
|
|
||||||
vulkan-tools \
|
|
||||||
libstorm-dev && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
COPY build-wowee.sh /
|
|
||||||
|
|
||||||
ENTRYPOINT ./build-wowee.sh
|
|
||||||
67
container/builder-windows.Dockerfile
Normal file
67
container/builder-windows.Dockerfile
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
FROM ubuntu:24.04
|
||||||
|
|
||||||
|
# Windows cross-compile using LLVM-MinGW — best-in-class Clang/LLD toolchain
|
||||||
|
# targeting x86_64-w64-mingw32. Produces native .exe/.dll without MSVC or Wine.
|
||||||
|
# LLVM-MinGW ships: clang, clang++, lld, libc++ / libunwind headers, winpthreads.
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
ENV LLVM_MINGW_VERSION=20240619
|
||||||
|
ENV LLVM_MINGW_URL=https://github.com/mstorsjo/llvm-mingw/releases/download/${LLVM_MINGW_VERSION}/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-20.04-x86_64.tar.xz
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends \
|
||||||
|
ca-certificates \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
ninja-build \
|
||||||
|
git \
|
||||||
|
python3 \
|
||||||
|
curl \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
tar \
|
||||||
|
xz-utils \
|
||||||
|
pkg-config \
|
||||||
|
nasm \
|
||||||
|
libssl-dev \
|
||||||
|
zlib1g-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install LLVM-MinGW toolchain
|
||||||
|
RUN curl -fsSL "${LLVM_MINGW_URL}" -o /tmp/llvm-mingw.tar.xz && \
|
||||||
|
tar -xf /tmp/llvm-mingw.tar.xz -C /opt && \
|
||||||
|
mv /opt/llvm-mingw-${LLVM_MINGW_VERSION}-ucrt-ubuntu-20.04-x86_64 /opt/llvm-mingw && \
|
||||||
|
rm /tmp/llvm-mingw.tar.xz
|
||||||
|
|
||||||
|
ENV PATH="/opt/llvm-mingw/bin:${PATH}"
|
||||||
|
|
||||||
|
# Windows dependencies via vcpkg (static, x64-mingw-static triplet)
|
||||||
|
ENV VCPKG_ROOT=/opt/vcpkg
|
||||||
|
RUN git clone --depth 1 https://github.com/microsoft/vcpkg.git "${VCPKG_ROOT}" && \
|
||||||
|
"${VCPKG_ROOT}/bootstrap-vcpkg.sh" -disableMetrics
|
||||||
|
|
||||||
|
ENV VCPKG_DEFAULT_TRIPLET=x64-mingw-static
|
||||||
|
RUN "${VCPKG_ROOT}/vcpkg" install \
|
||||||
|
sdl2[vulkan] \
|
||||||
|
openssl \
|
||||||
|
glew \
|
||||||
|
glm \
|
||||||
|
zlib \
|
||||||
|
ffmpeg \
|
||||||
|
--triplet x64-mingw-static
|
||||||
|
|
||||||
|
# Vulkan SDK headers (loader is linked statically via SDL2's vulkan surface)
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends libvulkan-dev glslang-tools && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Provide a no-op powershell.exe so vcpkg's MinGW applocal post-build hook
|
||||||
|
# exits cleanly. The x64-mingw-static triplet is fully static (no DLLs to
|
||||||
|
# copy), so the script has nothing to do — it just needs to not fail.
|
||||||
|
RUN printf '#!/bin/sh\nexit 0\n' > /usr/local/bin/powershell.exe && \
|
||||||
|
chmod +x /usr/local/bin/powershell.exe
|
||||||
|
|
||||||
|
COPY build-windows.sh /build-platform.sh
|
||||||
|
RUN chmod +x /build-platform.sh
|
||||||
|
|
||||||
|
ENTRYPOINT ["/build-platform.sh"]
|
||||||
62
container/macos/osxcross-toolchain.cmake
Normal file
62
container/macos/osxcross-toolchain.cmake
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# osxcross CMake toolchain file for cross-compiling to macOS from Linux.
|
||||||
|
# Used by vcpkg triplets and the WoWee build.
|
||||||
|
# Auto-detects SDK, darwin version, and arch from the osxcross installation
|
||||||
|
# and the VCPKG_OSX_ARCHITECTURES / CMAKE_OSX_ARCHITECTURES setting.
|
||||||
|
|
||||||
|
set(CMAKE_SYSTEM_NAME Darwin)
|
||||||
|
|
||||||
|
# ── osxcross paths ──────────────────────────────────────────────────
|
||||||
|
set(_target_dir "/opt/osxcross/target")
|
||||||
|
if(DEFINED ENV{OSXCROSS_TARGET_DIR})
|
||||||
|
set(_target_dir "$ENV{OSXCROSS_TARGET_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Auto-detect SDK (pick the newest if several are present)
|
||||||
|
file(GLOB _sdk_dirs "${_target_dir}/SDK/MacOSX*.sdk")
|
||||||
|
list(SORT _sdk_dirs)
|
||||||
|
list(GET _sdk_dirs -1 _sdk_dir)
|
||||||
|
set(CMAKE_OSX_SYSROOT "${_sdk_dir}" CACHE PATH "" FORCE)
|
||||||
|
|
||||||
|
# Deployment target
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "13.0" CACHE STRING "" FORCE)
|
||||||
|
if(DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# ── auto-detect darwin version from compiler names ──────────────────
|
||||||
|
file(GLOB _darwin_compilers "${_target_dir}/bin/*-apple-darwin*-clang")
|
||||||
|
list(GET _darwin_compilers 0 _first_compiler)
|
||||||
|
get_filename_component(_compiler_name "${_first_compiler}" NAME)
|
||||||
|
string(REGEX MATCH "apple-darwin[0-9.]+" _darwin_part "${_compiler_name}")
|
||||||
|
|
||||||
|
# ── pick architecture ───────────────────────────────────────────────
|
||||||
|
# CMAKE_OSX_ARCHITECTURES is set by vcpkg from VCPKG_OSX_ARCHITECTURES
|
||||||
|
if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
|
||||||
|
set(_arch "arm64")
|
||||||
|
elseif(CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64")
|
||||||
|
set(_arch "x86_64")
|
||||||
|
elseif(DEFINED ENV{OSXCROSS_ARCH})
|
||||||
|
set(_arch "$ENV{OSXCROSS_ARCH}")
|
||||||
|
else()
|
||||||
|
set(_arch "arm64")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_host "${_arch}-${_darwin_part}")
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR "${_arch}" CACHE STRING "" FORCE)
|
||||||
|
|
||||||
|
# ── compilers ───────────────────────────────────────────────────────
|
||||||
|
set(CMAKE_C_COMPILER "${_target_dir}/bin/${_host}-clang" CACHE FILEPATH "" FORCE)
|
||||||
|
set(CMAKE_CXX_COMPILER "${_target_dir}/bin/${_host}-clang++" CACHE FILEPATH "" FORCE)
|
||||||
|
|
||||||
|
# ── tools ───────────────────────────────────────────────────────────
|
||||||
|
set(CMAKE_AR "${_target_dir}/bin/${_host}-ar" CACHE FILEPATH "" FORCE)
|
||||||
|
set(CMAKE_RANLIB "${_target_dir}/bin/${_host}-ranlib" CACHE FILEPATH "" FORCE)
|
||||||
|
set(CMAKE_STRIP "${_target_dir}/bin/${_host}-strip" CACHE FILEPATH "" FORCE)
|
||||||
|
set(CMAKE_INSTALL_NAME_TOOL "${_target_dir}/bin/${_host}-install_name_tool" CACHE FILEPATH "" FORCE)
|
||||||
|
|
||||||
|
# ── search paths ────────────────────────────────────────────────────
|
||||||
|
set(CMAKE_FIND_ROOT_PATH "${_sdk_dir}" "${_target_dir}")
|
||||||
|
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)
|
||||||
366
container/macos/sdk-fetcher.py
Normal file
366
container/macos/sdk-fetcher.py
Normal file
|
|
@ -0,0 +1,366 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Download and extract macOS SDK from Apple's Command Line Tools package.
|
||||||
|
|
||||||
|
Apple publishes Command Line Tools (CLT) packages via their publicly
|
||||||
|
accessible software update catalog. This script downloads the latest CLT,
|
||||||
|
extracts just the macOS SDK, and packages it as a .tar.gz tarball suitable
|
||||||
|
for osxcross.
|
||||||
|
|
||||||
|
No Apple ID or paid developer account required.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 sdk-fetcher.py [output_dir]
|
||||||
|
|
||||||
|
The script prints the absolute path of the resulting tarball to stdout.
|
||||||
|
All progress / status messages go to stderr.
|
||||||
|
If a cached SDK tarball already exists in output_dir, it is reused.
|
||||||
|
|
||||||
|
Dependencies: python3 (>= 3.6), cpio, tar, gzip
|
||||||
|
Optional: bsdtar (libarchive-tools) or xar -- faster XAR extraction.
|
||||||
|
Falls back to a pure-Python XAR parser when neither is available.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import glob
|
||||||
|
import gzip
|
||||||
|
import lzma
|
||||||
|
import os
|
||||||
|
import plistlib
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import struct
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import urllib.request
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
# -- Configuration -----------------------------------------------------------
|
||||||
|
|
||||||
|
CATALOG_URLS = [
|
||||||
|
# Try newest catalog first; first successful fetch wins.
|
||||||
|
"https://swscan.apple.com/content/catalogs/others/"
|
||||||
|
"index-16-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-"
|
||||||
|
"mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz",
|
||||||
|
|
||||||
|
"https://swscan.apple.com/content/catalogs/others/"
|
||||||
|
"index-15-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-"
|
||||||
|
"mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz",
|
||||||
|
|
||||||
|
"https://swscan.apple.com/content/catalogs/others/"
|
||||||
|
"index-14-13-12-10.16-10.15-10.14-10.13-10.12-10.11-10.10-10.9-"
|
||||||
|
"mountainlion-lion-snowleopard-leopard.merged-1.sucatalog.gz",
|
||||||
|
]
|
||||||
|
|
||||||
|
USER_AGENT = "Software%20Update"
|
||||||
|
|
||||||
|
|
||||||
|
# -- Helpers -----------------------------------------------------------------
|
||||||
|
|
||||||
|
def log(msg):
|
||||||
|
print(msg, file=sys.stderr, flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
# -- 1) Catalog & URL discovery ----------------------------------------------
|
||||||
|
|
||||||
|
def find_sdk_pkg_url():
|
||||||
|
"""Search Apple catalogs for the latest CLTools_macOSNMOS_SDK.pkg URL."""
|
||||||
|
for cat_url in CATALOG_URLS:
|
||||||
|
short = cat_url.split("/index-")[1][:25] + "..."
|
||||||
|
log(f" Trying catalog: {short}")
|
||||||
|
try:
|
||||||
|
req = urllib.request.Request(cat_url, headers={"User-Agent": USER_AGENT})
|
||||||
|
with urllib.request.urlopen(req, timeout=60) as resp:
|
||||||
|
raw = gzip.decompress(resp.read())
|
||||||
|
catalog = plistlib.loads(raw)
|
||||||
|
except Exception as exc:
|
||||||
|
log(f" -> fetch failed: {exc}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
products = catalog.get("Products", {})
|
||||||
|
candidates = []
|
||||||
|
for pid, product in products.items():
|
||||||
|
post_date = str(product.get("PostDate", ""))
|
||||||
|
for pkg in product.get("Packages", []):
|
||||||
|
url = pkg.get("URL", "")
|
||||||
|
size = pkg.get("Size", 0)
|
||||||
|
if "CLTools_macOSNMOS_SDK" in url and url.endswith(".pkg"):
|
||||||
|
candidates.append((post_date, url, size, pid))
|
||||||
|
|
||||||
|
if not candidates:
|
||||||
|
log(f" -> no CLTools SDK packages in this catalog, trying next...")
|
||||||
|
continue
|
||||||
|
|
||||||
|
candidates.sort(reverse=True)
|
||||||
|
_date, url, size, pid = candidates[0]
|
||||||
|
log(f"==> Found: CLTools_macOSNMOS_SDK (product {pid}, {size // 1048576} MB)")
|
||||||
|
return url
|
||||||
|
|
||||||
|
log("ERROR: No CLTools SDK packages found in any Apple catalog.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# -- 2) Download -------------------------------------------------------------
|
||||||
|
|
||||||
|
def download(url, dest):
|
||||||
|
"""Download *url* to *dest* with a basic progress indicator."""
|
||||||
|
req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT})
|
||||||
|
with urllib.request.urlopen(req, timeout=600) as resp:
|
||||||
|
total = int(resp.headers.get("Content-Length", 0))
|
||||||
|
done = 0
|
||||||
|
with open(dest, "wb") as f:
|
||||||
|
while True:
|
||||||
|
chunk = resp.read(1 << 20)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
f.write(chunk)
|
||||||
|
done += len(chunk)
|
||||||
|
if total:
|
||||||
|
pct = done * 100 // total
|
||||||
|
log(f"\r {done // 1048576} / {total // 1048576} MB ({pct}%)")
|
||||||
|
log("")
|
||||||
|
|
||||||
|
|
||||||
|
# -- 3) XAR extraction -------------------------------------------------------
|
||||||
|
|
||||||
|
def extract_xar(pkg_path, dest_dir):
|
||||||
|
"""Extract a XAR (.pkg) archive -- external tool or pure-Python fallback."""
|
||||||
|
for tool in ("bsdtar", "xar"):
|
||||||
|
if shutil.which(tool):
|
||||||
|
log(f"==> Extracting .pkg with {tool}...")
|
||||||
|
r = subprocess.run([tool, "-xf", pkg_path, "-C", dest_dir],
|
||||||
|
capture_output=True)
|
||||||
|
if r.returncode == 0:
|
||||||
|
return
|
||||||
|
log(f" {tool} exited {r.returncode}, trying next method...")
|
||||||
|
|
||||||
|
log("==> Extracting .pkg with built-in Python XAR parser...")
|
||||||
|
_extract_xar_python(pkg_path, dest_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_xar_python(pkg_path, dest_dir):
|
||||||
|
"""Pure-Python XAR extractor (no external dependencies)."""
|
||||||
|
with open(pkg_path, "rb") as f:
|
||||||
|
raw = f.read(28)
|
||||||
|
if len(raw) < 28:
|
||||||
|
raise ValueError("File too small to be a valid XAR archive")
|
||||||
|
magic, hdr_size, _ver, toc_clen, _toc_ulen, _ck = struct.unpack(
|
||||||
|
">4sHHQQI", raw,
|
||||||
|
)
|
||||||
|
if magic != b"xar!":
|
||||||
|
raise ValueError(f"Not a XAR file (magic: {magic!r})")
|
||||||
|
|
||||||
|
f.seek(hdr_size)
|
||||||
|
toc_xml = zlib.decompress(f.read(toc_clen))
|
||||||
|
heap_off = hdr_size + toc_clen
|
||||||
|
|
||||||
|
root = ET.fromstring(toc_xml)
|
||||||
|
toc = root.find("toc")
|
||||||
|
if toc is None:
|
||||||
|
raise ValueError("Malformed XAR: no <toc> element")
|
||||||
|
|
||||||
|
def _walk(elem, base):
|
||||||
|
for fe in elem.findall("file"):
|
||||||
|
name = fe.findtext("name", "")
|
||||||
|
ftype = fe.findtext("type", "file")
|
||||||
|
path = os.path.join(base, name)
|
||||||
|
|
||||||
|
if ftype == "directory":
|
||||||
|
os.makedirs(path, exist_ok=True)
|
||||||
|
_walk(fe, path)
|
||||||
|
continue
|
||||||
|
|
||||||
|
de = fe.find("data")
|
||||||
|
if de is None:
|
||||||
|
continue
|
||||||
|
offset = int(de.findtext("offset", "0"))
|
||||||
|
size = int(de.findtext("size", "0"))
|
||||||
|
enc_el = de.find("encoding")
|
||||||
|
enc = enc_el.get("style", "") if enc_el is not None else ""
|
||||||
|
|
||||||
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||||
|
f.seek(heap_off + offset)
|
||||||
|
|
||||||
|
if "gzip" in enc:
|
||||||
|
with open(path, "wb") as out:
|
||||||
|
out.write(zlib.decompress(f.read(size), 15 + 32))
|
||||||
|
elif "bzip2" in enc:
|
||||||
|
import bz2
|
||||||
|
with open(path, "wb") as out:
|
||||||
|
out.write(bz2.decompress(f.read(size)))
|
||||||
|
else:
|
||||||
|
with open(path, "wb") as out:
|
||||||
|
rem = size
|
||||||
|
while rem > 0:
|
||||||
|
blk = f.read(min(rem, 1 << 20))
|
||||||
|
if not blk:
|
||||||
|
break
|
||||||
|
out.write(blk)
|
||||||
|
rem -= len(blk)
|
||||||
|
|
||||||
|
_walk(toc, dest_dir)
|
||||||
|
|
||||||
|
|
||||||
|
# -- 4) Payload extraction (pbzx / gzip cpio) --------------------------------
|
||||||
|
|
||||||
|
def _pbzx_stream(path):
|
||||||
|
"""Yield decompressed chunks from a pbzx-compressed file."""
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
if f.read(4) != b"pbzx":
|
||||||
|
raise ValueError("Not a pbzx file")
|
||||||
|
f.read(8)
|
||||||
|
while True:
|
||||||
|
hdr = f.read(16)
|
||||||
|
if len(hdr) < 16:
|
||||||
|
break
|
||||||
|
_usize, csize = struct.unpack(">QQ", hdr)
|
||||||
|
data = f.read(csize)
|
||||||
|
if len(data) < csize:
|
||||||
|
break
|
||||||
|
if csize == _usize:
|
||||||
|
yield data
|
||||||
|
else:
|
||||||
|
yield lzma.decompress(data)
|
||||||
|
|
||||||
|
|
||||||
|
def _gzip_stream(path):
|
||||||
|
"""Yield decompressed chunks from a gzip file."""
|
||||||
|
with gzip.open(path, "rb") as f:
|
||||||
|
while True:
|
||||||
|
chunk = f.read(1 << 20)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
yield chunk
|
||||||
|
|
||||||
|
|
||||||
|
def _raw_stream(path):
|
||||||
|
"""Yield raw 1 MiB chunks (last resort)."""
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
while True:
|
||||||
|
chunk = f.read(1 << 20)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
yield chunk
|
||||||
|
|
||||||
|
|
||||||
|
def extract_payload(payload_path, out_dir):
|
||||||
|
"""Decompress a CLT Payload (pbzx or gzip cpio) into *out_dir*."""
|
||||||
|
with open(payload_path, "rb") as pf:
|
||||||
|
magic = pf.read(4)
|
||||||
|
|
||||||
|
if magic == b"pbzx":
|
||||||
|
log(" Payload format: pbzx (LZMA chunks)")
|
||||||
|
stream = _pbzx_stream(payload_path)
|
||||||
|
elif magic[:2] == b"\x1f\x8b":
|
||||||
|
log(" Payload format: gzip")
|
||||||
|
stream = _gzip_stream(payload_path)
|
||||||
|
else:
|
||||||
|
log(f" Payload format: unknown (magic: {magic.hex()}), trying raw cpio...")
|
||||||
|
stream = _raw_stream(payload_path)
|
||||||
|
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
["cpio", "-id", "--quiet"],
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
cwd=out_dir,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
)
|
||||||
|
for chunk in stream:
|
||||||
|
try:
|
||||||
|
proc.stdin.write(chunk)
|
||||||
|
except BrokenPipeError:
|
||||||
|
break
|
||||||
|
proc.stdin.close()
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
|
# -- Main --------------------------------------------------------------------
|
||||||
|
|
||||||
|
def main():
|
||||||
|
output_dir = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else os.getcwd()
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Re-use a previously fetched SDK if present.
|
||||||
|
cached = glob.glob(os.path.join(output_dir, "MacOSX*.sdk.tar.*"))
|
||||||
|
if cached:
|
||||||
|
cached.sort()
|
||||||
|
result = os.path.realpath(cached[-1])
|
||||||
|
log(f"==> Using cached SDK: {os.path.basename(result)}")
|
||||||
|
print(result)
|
||||||
|
return
|
||||||
|
|
||||||
|
work = tempfile.mkdtemp(prefix="fetch-macos-sdk-")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 1 -- Locate SDK package URL from Apple's catalog
|
||||||
|
log("==> Searching Apple software-update catalogs...")
|
||||||
|
sdk_url = find_sdk_pkg_url()
|
||||||
|
|
||||||
|
# 2 -- Download (just the SDK component, ~55 MB)
|
||||||
|
pkg = os.path.join(work, "sdk.pkg")
|
||||||
|
log("==> Downloading CLTools SDK package...")
|
||||||
|
download(sdk_url, pkg)
|
||||||
|
|
||||||
|
# 3 -- Extract the flat .pkg (XAR format) to get the Payload
|
||||||
|
pkg_dir = os.path.join(work, "pkg")
|
||||||
|
os.makedirs(pkg_dir)
|
||||||
|
extract_xar(pkg, pkg_dir)
|
||||||
|
os.unlink(pkg)
|
||||||
|
|
||||||
|
# 4 -- Locate the Payload file
|
||||||
|
log("==> Locating SDK payload...")
|
||||||
|
sdk_payload = None
|
||||||
|
for dirpath, _dirs, files in os.walk(pkg_dir):
|
||||||
|
if "Payload" in files:
|
||||||
|
sdk_payload = os.path.join(dirpath, "Payload")
|
||||||
|
log(f" Found: {os.path.relpath(sdk_payload, pkg_dir)}")
|
||||||
|
break
|
||||||
|
|
||||||
|
if sdk_payload is None:
|
||||||
|
log("ERROR: No Payload found in extracted package")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# 5 -- Decompress Payload -> cpio -> filesystem
|
||||||
|
sdk_root = os.path.join(work, "sdk")
|
||||||
|
os.makedirs(sdk_root)
|
||||||
|
log("==> Extracting SDK from payload (this may take a minute)...")
|
||||||
|
extract_payload(sdk_payload, sdk_root)
|
||||||
|
shutil.rmtree(pkg_dir)
|
||||||
|
|
||||||
|
# 6 -- Find MacOSX*.sdk directory
|
||||||
|
sdk_found = None
|
||||||
|
for dirpath, dirs, _files in os.walk(sdk_root):
|
||||||
|
for d in dirs:
|
||||||
|
if re.match(r"MacOSX\d+(\.\d+)?\.sdk$", d):
|
||||||
|
sdk_found = os.path.join(dirpath, d)
|
||||||
|
break
|
||||||
|
if sdk_found:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not sdk_found:
|
||||||
|
log("ERROR: MacOSX*.sdk directory not found. Extracted contents:")
|
||||||
|
for dp, ds, fs in os.walk(sdk_root):
|
||||||
|
depth = dp.replace(sdk_root, "").count(os.sep)
|
||||||
|
if depth < 4:
|
||||||
|
log(f" {' ' * depth}{os.path.basename(dp)}/")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
sdk_name = os.path.basename(sdk_found)
|
||||||
|
log(f"==> Found: {sdk_name}")
|
||||||
|
|
||||||
|
# 7 -- Package as .tar.gz
|
||||||
|
tarball = os.path.join(output_dir, f"{sdk_name}.tar.gz")
|
||||||
|
log(f"==> Packaging: {sdk_name}.tar.gz ...")
|
||||||
|
subprocess.run(
|
||||||
|
["tar", "-czf", tarball, "-C", os.path.dirname(sdk_found), sdk_name],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
log(f"==> macOS SDK ready: {tarball}")
|
||||||
|
print(tarball)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(work, ignore_errors=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
10
container/macos/triplets/arm64-osx-cross.cmake
Normal file
10
container/macos/triplets/arm64-osx-cross.cmake
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||||
|
set(VCPKG_CRT_LINKAGE dynamic)
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE static)
|
||||||
|
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||||
|
|
||||||
|
set(VCPKG_OSX_ARCHITECTURES arm64)
|
||||||
|
set(VCPKG_OSX_DEPLOYMENT_TARGET 13.0)
|
||||||
|
|
||||||
|
# osxcross toolchain
|
||||||
|
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE /opt/osxcross-toolchain.cmake)
|
||||||
10
container/macos/triplets/x64-osx-cross.cmake
Normal file
10
container/macos/triplets/x64-osx-cross.cmake
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||||
|
set(VCPKG_CRT_LINKAGE dynamic)
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE static)
|
||||||
|
set(VCPKG_CMAKE_SYSTEM_NAME Darwin)
|
||||||
|
|
||||||
|
set(VCPKG_OSX_ARCHITECTURES x86_64)
|
||||||
|
set(VCPKG_OSX_DEPLOYMENT_TARGET 13.0)
|
||||||
|
|
||||||
|
# osxcross toolchain
|
||||||
|
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE /opt/osxcross-toolchain.cmake)
|
||||||
64
container/run-linux.ps1
Normal file
64
container/run-linux.ps1
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
# run-linux.ps1 — Build WoWee for Linux (amd64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# .\container\run-linux.ps1 [-RebuildImage]
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$RebuildImage
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$ProjectRoot = (Resolve-Path "$ScriptDir\..").Path
|
||||||
|
|
||||||
|
$ImageName = "wowee-builder-linux"
|
||||||
|
$BuildOutput = "$ProjectRoot\build\linux"
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error "docker is not installed or not in PATH."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the image (skip if already present and -RebuildImage not given)
|
||||||
|
$imageExists = docker image inspect $ImageName 2>$null
|
||||||
|
if ($RebuildImage -or -not $imageExists) {
|
||||||
|
Write-Host "==> Building Docker image: $ImageName"
|
||||||
|
docker build `
|
||||||
|
-f "$ScriptDir\builder-linux.Dockerfile" `
|
||||||
|
-t $ImageName `
|
||||||
|
"$ScriptDir"
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
} else {
|
||||||
|
Write-Host "==> Using existing Docker image: $ImageName"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
New-Item -ItemType Directory -Force -Path $BuildOutput | Out-Null
|
||||||
|
|
||||||
|
Write-Host "==> Starting Linux build (output: $BuildOutput)"
|
||||||
|
|
||||||
|
$dockerArgs = @(
|
||||||
|
"run", "--rm",
|
||||||
|
"--mount", "type=bind,src=$ProjectRoot,dst=/src,readonly",
|
||||||
|
"--mount", "type=bind,src=$BuildOutput,dst=/out"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($env:WOWEE_FFX_SDK_REPO) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REPO=$env:WOWEE_FFX_SDK_REPO")
|
||||||
|
}
|
||||||
|
if ($env:WOWEE_FFX_SDK_REF) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REF=$env:WOWEE_FFX_SDK_REF")
|
||||||
|
}
|
||||||
|
|
||||||
|
$dockerArgs += $ImageName
|
||||||
|
|
||||||
|
& docker @dockerArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
|
||||||
|
Write-Host "==> Linux build complete. Artifacts in: $BuildOutput"
|
||||||
58
container/run-linux.sh
Executable file
58
container/run-linux.sh
Executable file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# run-linux.sh — Build WoWee for Linux (amd64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# ./container/run-linux.sh [--rebuild-image]
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
# REBUILD_IMAGE — Set to 1 to force a fresh docker build (same as --rebuild-image)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
|
IMAGE_NAME="wowee-builder-linux"
|
||||||
|
BUILD_OUTPUT="${PROJECT_ROOT}/build/linux"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
REBUILD_IMAGE="${REBUILD_IMAGE:-0}"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--rebuild-image) REBUILD_IMAGE=1 ;;
|
||||||
|
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
echo "Error: docker is not installed or not in PATH." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the image (skip if already present and --rebuild-image not given)
|
||||||
|
if [[ "$REBUILD_IMAGE" == "1" ]] || ! docker image inspect "$IMAGE_NAME" &>/dev/null; then
|
||||||
|
echo "==> Building Docker image: ${IMAGE_NAME}"
|
||||||
|
docker build \
|
||||||
|
-f "${SCRIPT_DIR}/builder-linux.Dockerfile" \
|
||||||
|
-t "$IMAGE_NAME" \
|
||||||
|
"${SCRIPT_DIR}"
|
||||||
|
else
|
||||||
|
echo "==> Using existing Docker image: ${IMAGE_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
mkdir -p "$BUILD_OUTPUT"
|
||||||
|
|
||||||
|
echo "==> Starting Linux build (output: ${BUILD_OUTPUT})"
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
--mount "type=bind,src=${PROJECT_ROOT},dst=/src,readonly" \
|
||||||
|
--mount "type=bind,src=${BUILD_OUTPUT},dst=/out" \
|
||||||
|
${WOWEE_FFX_SDK_REPO:+--env "WOWEE_FFX_SDK_REPO=${WOWEE_FFX_SDK_REPO}"} \
|
||||||
|
${WOWEE_FFX_SDK_REF:+--env "WOWEE_FFX_SDK_REF=${WOWEE_FFX_SDK_REF}"} \
|
||||||
|
"$IMAGE_NAME"
|
||||||
|
|
||||||
|
echo "==> Linux build complete. Artifacts in: ${BUILD_OUTPUT}"
|
||||||
71
container/run-macos.ps1
Normal file
71
container/run-macos.ps1
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# run-macos.ps1 — Cross-compile WoWee for macOS (arm64 or x86_64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# .\container\run-macos.ps1 [-RebuildImage] [-Arch arm64|x86_64]
|
||||||
|
#
|
||||||
|
# The macOS SDK is fetched automatically inside the Docker build from Apple's
|
||||||
|
# public software update catalog. No manual SDK download required.
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$RebuildImage,
|
||||||
|
[ValidateSet("arm64", "x86_64")]
|
||||||
|
[string]$Arch = "arm64"
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$ProjectRoot = (Resolve-Path "$ScriptDir\..").Path
|
||||||
|
|
||||||
|
$ImageName = "wowee-builder-macos"
|
||||||
|
$BuildOutput = "$ProjectRoot\build\macos"
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error "docker is not installed or not in PATH."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the image (skip if already present and -RebuildImage not given)
|
||||||
|
$imageExists = docker image inspect $ImageName 2>$null
|
||||||
|
if ($RebuildImage -or -not $imageExists) {
|
||||||
|
Write-Host "==> Building Docker image: $ImageName"
|
||||||
|
Write-Host " (SDK will be fetched automatically from Apple's catalog)"
|
||||||
|
docker build `
|
||||||
|
-f "$ScriptDir\builder-macos.Dockerfile" `
|
||||||
|
-t $ImageName `
|
||||||
|
"$ScriptDir"
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
} else {
|
||||||
|
Write-Host "==> Using existing Docker image: $ImageName"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
New-Item -ItemType Directory -Force -Path $BuildOutput | Out-Null
|
||||||
|
|
||||||
|
Write-Host "==> Starting macOS cross-compile build (arch=$Arch, output: $BuildOutput)"
|
||||||
|
|
||||||
|
$dockerArgs = @(
|
||||||
|
"run", "--rm",
|
||||||
|
"--mount", "type=bind,src=$ProjectRoot,dst=/src,readonly",
|
||||||
|
"--mount", "type=bind,src=$BuildOutput,dst=/out",
|
||||||
|
"--env", "MACOS_ARCH=$Arch"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($env:WOWEE_FFX_SDK_REPO) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REPO=$env:WOWEE_FFX_SDK_REPO")
|
||||||
|
}
|
||||||
|
if ($env:WOWEE_FFX_SDK_REF) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REF=$env:WOWEE_FFX_SDK_REF")
|
||||||
|
}
|
||||||
|
|
||||||
|
$dockerArgs += $ImageName
|
||||||
|
|
||||||
|
& docker @dockerArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
|
||||||
|
Write-Host "==> macOS cross-compile build complete. Artifacts in: $BuildOutput"
|
||||||
74
container/run-macos.sh
Executable file
74
container/run-macos.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# run-macos.sh — Cross-compile WoWee for macOS (arm64 or x86_64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# ./container/run-macos.sh [--rebuild-image]
|
||||||
|
#
|
||||||
|
# The macOS SDK is fetched automatically inside the Docker build from Apple's
|
||||||
|
# public software update catalog. No manual SDK download required.
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# MACOS_ARCH — Target arch: arm64 (default) or x86_64
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
# REBUILD_IMAGE — Set to 1 to force a fresh docker build (same as --rebuild-image)
|
||||||
|
#
|
||||||
|
# Toolchain: osxcross (Clang + Apple ld)
|
||||||
|
# vcpkg triplets: arm64-osx-cross (arm64) / x64-osx-cross (x86_64)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
|
IMAGE_NAME="wowee-builder-macos"
|
||||||
|
MACOS_ARCH="${MACOS_ARCH:-arm64}"
|
||||||
|
BUILD_OUTPUT="${PROJECT_ROOT}/build/macos"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
REBUILD_IMAGE="${REBUILD_IMAGE:-0}"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--rebuild-image) REBUILD_IMAGE=1 ;;
|
||||||
|
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Validate arch
|
||||||
|
if [[ "$MACOS_ARCH" != "arm64" && "$MACOS_ARCH" != "x86_64" ]]; then
|
||||||
|
echo "Error: MACOS_ARCH must be 'arm64' or 'x86_64' (got: ${MACOS_ARCH})" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
echo "Error: docker is not installed or not in PATH." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the image (skip if already present and --rebuild-image not given)
|
||||||
|
if [[ "$REBUILD_IMAGE" == "1" ]] || ! docker image inspect "$IMAGE_NAME" &>/dev/null; then
|
||||||
|
echo "==> Building Docker image: ${IMAGE_NAME}"
|
||||||
|
echo " (SDK will be fetched automatically from Apple's catalog)"
|
||||||
|
docker build \
|
||||||
|
-f "${SCRIPT_DIR}/builder-macos.Dockerfile" \
|
||||||
|
-t "$IMAGE_NAME" \
|
||||||
|
"${SCRIPT_DIR}"
|
||||||
|
else
|
||||||
|
echo "==> Using existing Docker image: ${IMAGE_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
mkdir -p "$BUILD_OUTPUT"
|
||||||
|
|
||||||
|
echo "==> Starting macOS cross-compile build (arch=${MACOS_ARCH}, output: ${BUILD_OUTPUT})"
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
--mount "type=bind,src=${PROJECT_ROOT},dst=/src,readonly" \
|
||||||
|
--mount "type=bind,src=${BUILD_OUTPUT},dst=/out" \
|
||||||
|
--env "MACOS_ARCH=${MACOS_ARCH}" \
|
||||||
|
${WOWEE_FFX_SDK_REPO:+--env "WOWEE_FFX_SDK_REPO=${WOWEE_FFX_SDK_REPO}"} \
|
||||||
|
${WOWEE_FFX_SDK_REF:+--env "WOWEE_FFX_SDK_REF=${WOWEE_FFX_SDK_REF}"} \
|
||||||
|
"$IMAGE_NAME"
|
||||||
|
|
||||||
|
echo "==> macOS cross-compile build complete. Artifacts in: ${BUILD_OUTPUT}"
|
||||||
64
container/run-windows.ps1
Normal file
64
container/run-windows.ps1
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
# run-windows.ps1 — Cross-compile WoWee for Windows (x86_64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# .\container\run-windows.ps1 [-RebuildImage]
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$RebuildImage
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||||
|
$ProjectRoot = (Resolve-Path "$ScriptDir\..").Path
|
||||||
|
|
||||||
|
$ImageName = "wowee-builder-windows"
|
||||||
|
$BuildOutput = "$ProjectRoot\build\windows"
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if (-not (Get-Command docker -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Error "docker is not installed or not in PATH."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build the image (skip if already present and -RebuildImage not given)
|
||||||
|
$imageExists = docker image inspect $ImageName 2>$null
|
||||||
|
if ($RebuildImage -or -not $imageExists) {
|
||||||
|
Write-Host "==> Building Docker image: $ImageName"
|
||||||
|
docker build `
|
||||||
|
-f "$ScriptDir\builder-windows.Dockerfile" `
|
||||||
|
-t $ImageName `
|
||||||
|
"$ScriptDir"
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
} else {
|
||||||
|
Write-Host "==> Using existing Docker image: $ImageName"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
New-Item -ItemType Directory -Force -Path $BuildOutput | Out-Null
|
||||||
|
|
||||||
|
Write-Host "==> Starting Windows cross-compile build (output: $BuildOutput)"
|
||||||
|
|
||||||
|
$dockerArgs = @(
|
||||||
|
"run", "--rm",
|
||||||
|
"--mount", "type=bind,src=$ProjectRoot,dst=/src,readonly",
|
||||||
|
"--mount", "type=bind,src=$BuildOutput,dst=/out"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($env:WOWEE_FFX_SDK_REPO) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REPO=$env:WOWEE_FFX_SDK_REPO")
|
||||||
|
}
|
||||||
|
if ($env:WOWEE_FFX_SDK_REF) {
|
||||||
|
$dockerArgs += @("--env", "WOWEE_FFX_SDK_REF=$env:WOWEE_FFX_SDK_REF")
|
||||||
|
}
|
||||||
|
|
||||||
|
$dockerArgs += $ImageName
|
||||||
|
|
||||||
|
& docker @dockerArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||||
|
|
||||||
|
Write-Host "==> Windows cross-compile build complete. Artifacts in: $BuildOutput"
|
||||||
61
container/run-windows.sh
Executable file
61
container/run-windows.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# run-windows.sh — Cross-compile WoWee for Windows (x86_64) inside a Docker container.
|
||||||
|
#
|
||||||
|
# Usage (run from project root):
|
||||||
|
# ./container/run-windows.sh [--rebuild-image]
|
||||||
|
#
|
||||||
|
# Environment variables:
|
||||||
|
# WOWEE_FFX_SDK_REPO — FidelityFX SDK git repo URL (passed through to container)
|
||||||
|
# WOWEE_FFX_SDK_REF — FidelityFX SDK git ref / tag (passed through to container)
|
||||||
|
# REBUILD_IMAGE — Set to 1 to force a fresh docker build (same as --rebuild-image)
|
||||||
|
#
|
||||||
|
# Toolchain: LLVM-MinGW (Clang + LLD) targeting x86_64-w64-mingw32-ucrt
|
||||||
|
# vcpkg triplet: x64-mingw-static
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
|
IMAGE_NAME="wowee-builder-windows"
|
||||||
|
BUILD_OUTPUT="${PROJECT_ROOT}/build/windows"
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
REBUILD_IMAGE="${REBUILD_IMAGE:-0}"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--rebuild-image) REBUILD_IMAGE=1 ;;
|
||||||
|
*) echo "Unknown argument: $arg" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Verify Docker is available
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
echo "Error: docker is not installed or not in PATH." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build the image (skip if already present and --rebuild-image not given)
|
||||||
|
if [[ "$REBUILD_IMAGE" == "1" ]] || ! docker image inspect "$IMAGE_NAME" &>/dev/null; then
|
||||||
|
echo "==> Building Docker image: ${IMAGE_NAME}"
|
||||||
|
docker build \
|
||||||
|
-f "${SCRIPT_DIR}/builder-windows.Dockerfile" \
|
||||||
|
-t "$IMAGE_NAME" \
|
||||||
|
"${SCRIPT_DIR}"
|
||||||
|
else
|
||||||
|
echo "==> Using existing Docker image: ${IMAGE_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create output directory on the host
|
||||||
|
mkdir -p "$BUILD_OUTPUT"
|
||||||
|
|
||||||
|
echo "==> Starting Windows cross-compile build (output: ${BUILD_OUTPUT})"
|
||||||
|
|
||||||
|
docker run --rm \
|
||||||
|
--mount "type=bind,src=${PROJECT_ROOT},dst=/src,readonly" \
|
||||||
|
--mount "type=bind,src=${BUILD_OUTPUT},dst=/out" \
|
||||||
|
${WOWEE_FFX_SDK_REPO:+--env "WOWEE_FFX_SDK_REPO=${WOWEE_FFX_SDK_REPO}"} \
|
||||||
|
${WOWEE_FFX_SDK_REF:+--env "WOWEE_FFX_SDK_REF=${WOWEE_FFX_SDK_REF}"} \
|
||||||
|
"$IMAGE_NAME"
|
||||||
|
|
||||||
|
echo "==> Windows cross-compile build complete. Artifacts in: ${BUILD_OUTPUT}"
|
||||||
|
|
@ -1 +1 @@
|
||||||
IDI_APP_ICON ICON "assets\\wowee.ico"
|
IDI_APP_ICON ICON "assets/wowee.ico"
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
"glew",
|
"glew",
|
||||||
"glm",
|
"glm",
|
||||||
"zlib",
|
"zlib",
|
||||||
"ffmpeg"
|
"ffmpeg",
|
||||||
|
"vulkan-headers"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue