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
|
||||
|
|
@ -248,6 +248,70 @@ endif()
|
|||
find_package(SDL2 REQUIRED)
|
||||
find_package(Vulkan QUIET)
|
||||
if(NOT Vulkan_FOUND)
|
||||
# For Windows cross-compilation the host pkg-config finds the Linux libvulkan-dev
|
||||
# and injects /usr/include as an INTERFACE_INCLUDE_DIRECTORY, which causes
|
||||
# MinGW clang to pull in glibc headers (bits/libc-header-start.h) instead of
|
||||
# the MinGW sysroot headers. Skip the host pkg-config path entirely and instead
|
||||
# locate Vulkan via vcpkg-installed vulkan-headers or the MinGW toolchain.
|
||||
if(CMAKE_CROSSCOMPILING AND WIN32)
|
||||
# The cross-compile build script generates a Vulkan import library
|
||||
# (libvulkan-1.a) in ${CMAKE_BINARY_DIR}/vulkan-import from the headers.
|
||||
set(_VULKAN_IMPORT_DIR "${CMAKE_BINARY_DIR}/vulkan-import")
|
||||
|
||||
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
|
||||
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 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)
|
||||
|
|
@ -266,10 +330,16 @@ if(NOT Vulkan_FOUND)
|
|||
message(STATUS "Found Vulkan via pkg-config: ${VULKAN_PKG_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT Vulkan_FOUND)
|
||||
message(FATAL_ERROR "Could not find Vulkan. Install libvulkan-dev (Linux), vulkan-loader (macOS), or the Vulkan SDK (Windows).")
|
||||
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.
|
||||
# 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
|
||||
|
|
@ -674,12 +744,16 @@ set(WOWEE_HEADERS
|
|||
|
||||
set(WOWEE_PLATFORM_SOURCES)
|
||||
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(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/assets/Wowee.ico
|
||||
${CMAKE_CURRENT_BINARY_DIR}/assets/wowee.ico
|
||||
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)
|
||||
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",
|
||||
"glm",
|
||||
"zlib",
|
||||
"ffmpeg"
|
||||
"ffmpeg",
|
||||
"vulkan-headers"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue