diff --git a/docs/ja/setup/build.md b/docs/ja/setup/build.md index 3c9957a..109db4c 100644 --- a/docs/ja/setup/build.md +++ b/docs/ja/setup/build.md @@ -127,6 +127,92 @@ $env:PYTHONUTF8=1 > Linux 向けのカスタムモジュール用一括ビルドスクリプトは未整備です。`./scripts/build.sh platform=linux target=...` を `editor` / `template_debug` / `template_release` で個別に呼び出してください。 +## カスタムモジュールのデバッグ方法 + +カスタムモジュールとして組み込んだプラグインのC++コード(`ss_player` 以下)をデバッグしたい場合は、以下の手順で行います。 + +1. **デバッグ用バイナリの確認** + `target=editor` あるいは `target=template_debug` を指定してビルドしたGodotバイナリには、デフォルトでデバッグシンボルが含まれています。 + * **macOS:** `godot/Godot.app/Contents/MacOS/Godot` + * **Windows:** `godot/bin/godot.windows.editor.x86_64.exe` 等 + * **Linux:** `godot/bin/godot.linuxbsd.editor.x86_64` 等 + +2. **デバッガのアタッチと起動引数** + VSCode、Visual Studio、XcodeなどのIDEやコマンドラインのデバッガ(LLDB/GDB)から、上記のバイナリを起動プログラムとして指定します。 + 引数として対象プロジェクトへのパス(例: `--path examples/dev_module`)を渡すことで、エディタ画面を挟まずに直接プロジェクトを開いてデバッグを開始できます。 + +**VSCode (`launch.json`) の設定例 (macOS / LLDB の場合):** + +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Godot Custom Module", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/godot/Godot.app/Contents/MacOS/Godot", + "args": [ + "--path", + "${workspaceFolder}/examples/dev_module" + ], + "cwd": "${workspaceFolder}" + } + ] +} +``` + +## エクスポート機能のテスト・デバッグ方法 + +開発したカスタムモジュールやGDExtensionが、ビルド後のアプリで正常に動作するか(エクスポートが成功するか)を確認・デバッグするには、CLIを用いたヘッドレスエクスポートが便利です。 + +以下の流れで、手元でテンプレートをビルド・インストールし、サンプルプロジェクトをエクスポートします。(以下はmacOSの例です) + +1. **ランタイムとテンプレートのビルド** + 事前に `libssruntime` を用意し、対象プラットフォームのリリーススクリプトを実行します。 + ```bash + # (必要に応じて) ランタイムをリリースビルドで用意 + ./scripts/build-runtime.sh build=release platform=macos + + # エクスポート用テンプレートのビルド + ./scripts/release-macos.sh + ``` + +2. **テンプレートのインストール** + ビルドしたテンプレートを、Godotが認識するローカルの所定ディレクトリへインストールします。 + **macOS / Linux:** + ```bash + ./scripts/install-template.sh macos + ``` + **Windows (PowerShell):** + ```powershell + .\scripts\install-template.ps1 windows + ``` + +3. **CLIからのエクスポート実行** + ビルドしたGodotエディタ(headlessモード)を使い、コマンドラインから直接エクスポート処理を呼び出します。 + ```bash + # 例: dev_module プロジェクトを macOS 向けにエクスポート (.appとして直接出力) + ./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless --export-debug "macOS" output.app + ``` + > **Note:** エクスポートを実行するには、対象プロジェクト内の `export_presets.cfg` に指定したプラットフォーム名(上記の場合は `"macOS"`)のプリセットが存在し、必要な識別子(バンドルIDなど)が正しく設定されている必要があります。 + +### Webプラットフォームのエクスポートと動作確認 + +Web向けのエクスポートでは複数のファイル(`.html`, `.wasm`, `.pck`等)が出力されるため、専用のディレクトリを作成してエクスポートします。また、ブラウザのセキュリティ制限を回避するためローカルサーバーでの確認が必要です。 + +```bash +# 1. 出力用ディレクトリを作成し、Web向けにエクスポート +mkdir -p build_web +./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless --export-debug "Web" ../../build_web/index.html + +# 2. ローカルHTTPサーバーを起動 +cd build_web +python3 -m http.server 8000 +``` +サーバー起動後、ブラウザで `http://localhost:8000` にアクセスすると動作確認ができます。 +(本プラグインは Web においては `nothread` での動作となるため、特殊なCORSヘッダーなしの単純なHTTPサーバーで起動可能です) + ## SpriteStudio-SDK 開発者向け > 以降のセクションは **SpriteStudio-SDK 自体を手元で開発・カスタマイズしながら Godot 側もビルドしたい場合のみ** 必要です。SpriteStudio-SDK のリリース成果物を使う一般的な Godot ビルダーは読み飛ばして構いません。 diff --git a/scripts/install-template.ps1 b/scripts/install-template.ps1 new file mode 100644 index 0000000..b266147 --- /dev/null +++ b/scripts/install-template.ps1 @@ -0,0 +1,130 @@ +param ( + [Parameter(Mandatory=$true, HelpMessage="Available platforms: macos, windows, linux, ios, android, web")] + [ValidateSet("macos", "windows", "linux", "ios", "android", "web")] + [string]$Platform +) + +$ErrorActionPreference = "Stop" + +$BaseDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$RootDir = Resolve-Path "$BaseDir\.." | Select-Object -ExpandProperty Path + +Push-Location $RootDir + +# 1. 実行OSの判定とベースディレクトリの設定 (Windows) +$TemplatesBase = "$env:APPDATA\Godot\export_templates" + +# 2. Godotのバージョン情報を version.py から取得してディレクトリ名を生成 +$VersionPy = Get-Content "godot\version.py" +$GodotMajor = ($VersionPy | Select-String '^major').Line.Split('=')[1].Trim(" `'""") +$GodotMinor = ($VersionPy | Select-String '^minor').Line.Split('=')[1].Trim(" `'""") +$GodotPatch = ($VersionPy | Select-String '^patch').Line.Split('=')[1].Trim(" `'""") +$GodotStatus = ($VersionPy | Select-String '^status').Line.Split('=')[1].Trim(" `'""") + +if ($GodotPatch -ne "0") { + $VersionString = "${GodotMajor}.${GodotMinor}.${GodotPatch}.${GodotStatus}" +} else { + $VersionString = "${GodotMajor}.${GodotMinor}.${GodotStatus}" +} + +$TemplatesDir = "$TemplatesBase\$VersionString" +if (-not (Test-Path $TemplatesDir)) { + New-Item -ItemType Directory -Force -Path $TemplatesDir | Out-Null +} +Write-Host "Target template directory: $TemplatesDir" + +Push-Location "godot\bin" + +switch ($Platform) { + "windows" { + Write-Host "Processing Windows templates..." + Get-ChildItem -Filter "godot.windows.template_release.*.exe" | ForEach-Object { + if ($_.Name -match "godot\.windows\.template_release\.(.*)\.exe") { + $arch = $matches[1] + Copy-Item $_.FullName "$TemplatesDir\windows_release_${arch}.exe" -Force + } + } + Get-ChildItem -Filter "godot.windows.template_debug.*.exe" | ForEach-Object { + if ($_.Name -match "godot\.windows\.template_debug\.(.*)\.exe") { + $arch = $matches[1] + Copy-Item $_.FullName "$TemplatesDir\windows_debug_${arch}.exe" -Force + } + } + } + + "linux" { + Write-Host "Processing Linux templates..." + Get-ChildItem -Filter "godot.linuxbsd.template_release.*" | ForEach-Object { + if ($_.Name -match "godot\.linuxbsd\.template_release\.(.*)") { + $arch = $matches[1] + Copy-Item $_.FullName "$TemplatesDir\linux_release.${arch}" -Force + } + } + Get-ChildItem -Filter "godot.linuxbsd.template_debug.*" | ForEach-Object { + if ($_.Name -match "godot\.linuxbsd\.template_debug\.(.*)") { + $arch = $matches[1] + Copy-Item $_.FullName "$TemplatesDir\linux_debug.${arch}" -Force + } + } + } + + "android" { + Write-Host "Processing Android templates..." + if (Test-Path "android_source.zip") { Copy-Item "android_source.zip" "$TemplatesDir\android_source.zip" -Force } + if (Test-Path "android_release.apk") { Copy-Item "android_release.apk" "$TemplatesDir\android_release.apk" -Force } + if (Test-Path "android_debug.apk") { Copy-Item "android_debug.apk" "$TemplatesDir\android_debug.apk" -Force } + } + + "web" { + Write-Host "Processing Web (nothreads) templates..." + if (Test-Path "godot.web.template_release.wasm32.nothreads.zip") { Copy-Item "godot.web.template_release.wasm32.nothreads.zip" "$TemplatesDir\web_nothreads_release.zip" -Force } + if (Test-Path "godot.web.template_debug.wasm32.nothreads.zip") { Copy-Item "godot.web.template_debug.wasm32.nothreads.zip" "$TemplatesDir\web_nothreads_debug.zip" -Force } + if (Test-Path "godot.web.template_release.wasm32.nothreads.dlink.zip") { Copy-Item "godot.web.template_release.wasm32.nothreads.dlink.zip" "$TemplatesDir\web_nothreads_dlink_release.zip" -Force } + if (Test-Path "godot.web.template_debug.wasm32.nothreads.dlink.zip") { Copy-Item "godot.web.template_debug.wasm32.nothreads.dlink.zip" "$TemplatesDir\web_nothreads_dlink_debug.zip" -Force } + } + + "macos" { + Write-Host "Processing macOS templates..." + if (Test-Path "macos_template.app") { Remove-Item -Recurse -Force "macos_template.app" } + if (Test-Path "macos.zip") { Remove-Item -Force "macos.zip" } + Copy-Item -Recurse -Force "..\misc\dist\macos_template.app" ".\" + New-Item -ItemType Directory -Force -Path "macos_template.app\Contents\MacOS" | Out-Null + + if (Test-Path "godot.macos.template_release.universal") { Copy-Item "godot.macos.template_release.universal" "macos_template.app\Contents\MacOS\godot_macos_release.universal" -Force } + if (Test-Path "godot.macos.template_debug.universal") { Copy-Item "godot.macos.template_debug.universal" "macos_template.app\Contents\MacOS\godot_macos_debug.universal" -Force } + + Compress-Archive -Path "macos_template.app" -DestinationPath "macos.zip" -Force + Copy-Item "macos.zip" "$TemplatesDir\macos.zip" -Force + } + + "ios" { + Write-Host "Processing iOS templates..." + if (Test-Path "apple_embedded_xcode") { Remove-Item -Recurse -Force "apple_embedded_xcode" } + if (Test-Path "ios.zip") { Remove-Item -Force "ios.zip" } + Copy-Item -Recurse -Force "..\misc\dist\apple_embedded_xcode" ".\" + + if (Test-Path "libgodot.ios.template_release.xcframework") { + Remove-Item -Recurse -Force "apple_embedded_xcode\libgodot.ios.release.xcframework" -ErrorAction SilentlyContinue + Copy-Item -Recurse -Force "libgodot.ios.template_release.xcframework" "apple_embedded_xcode\libgodot.ios.release.xcframework" + } + if (Test-Path "libgodot.ios.template_debug.xcframework") { + Remove-Item -Recurse -Force "apple_embedded_xcode\libgodot.ios.debug.xcframework" -ErrorAction SilentlyContinue + Copy-Item -Recurse -Force "libgodot.ios.template_debug.xcframework" "apple_embedded_xcode\libgodot.ios.debug.xcframework" + } + + Push-Location "apple_embedded_xcode" + # Compress-Archive puts files in zip but we want contents. + # * requires PS 5.1+ to work nicely or just zip the folder + Compress-Archive -Path "*" -DestinationPath "..\ios.zip" -Force + Pop-Location + + Copy-Item "ios.zip" "$TemplatesDir\ios.zip" -Force + } +} + +Write-Host "======================================" +Write-Host "Successfully installed $Platform templates to:" +Write-Host $TemplatesDir + +Pop-Location +Pop-Location diff --git a/scripts/install-template.sh b/scripts/install-template.sh new file mode 100755 index 0000000..344643f --- /dev/null +++ b/scripts/install-template.sh @@ -0,0 +1,136 @@ +#!/usr/bin/env bash +set -e + +if [ -z "$1" ]; then + echo "Usage: $0 " + echo "Available platforms: macos, windows, linux, ios, android, web" + exit 1 +fi + +PLATFORM=$1 + +BASEDIR=$(dirname "$0") +BASEDIR=$(cd "$BASEDIR" && pwd -P) +ROOTDIR="${BASEDIR}/.." +ROOTDIR=$(cd "$ROOTDIR" && pwd -P) + +pushd "$ROOTDIR" > /dev/null + +# 1. 実行OSの判定とベースディレクトリの設定 +if [ "$(uname)" = "Darwin" ]; then + TEMPLATES_BASE="$HOME/Library/Application Support/Godot/export_templates" +else + TEMPLATES_BASE="$HOME/.local/share/godot/export_templates" +fi + +# 2. Godotのバージョン情報を version.py から取得してディレクトリ名を生成 +GODOT_MAJOR=$(grep '^major' godot/version.py | cut -d '=' -f 2 | tr -d ' ') +GODOT_MINOR=$(grep '^minor' godot/version.py | cut -d '=' -f 2 | tr -d ' ') +GODOT_PATCH=$(grep '^patch' godot/version.py | cut -d '=' -f 2 | tr -d ' ') +GODOT_STATUS=$(grep '^status' godot/version.py | cut -d '=' -f 2 | tr -d ' "' ) + +if [ "$GODOT_PATCH" != "0" ]; then + VERSION_STRING="${GODOT_MAJOR}.${GODOT_MINOR}.${GODOT_PATCH}.${GODOT_STATUS}" +else + VERSION_STRING="${GODOT_MAJOR}.${GODOT_MINOR}.${GODOT_STATUS}" +fi + +TEMPLATES_DIR="${TEMPLATES_BASE}/${VERSION_STRING}" +mkdir -p "$TEMPLATES_DIR" +echo "Target template directory: $TEMPLATES_DIR" + +pushd godot/bin > /dev/null + +case "$PLATFORM" in + macos) + echo "Processing macOS templates..." + [ -d macos_template.app ] && rm -r macos_template.app + [ -f macos.zip ] && rm macos.zip + cp -R ../misc/dist/macos_template.app ./ + mkdir -p macos_template.app/Contents/MacOS + + [ -f godot.macos.template_release.universal ] && cp godot.macos.template_release.universal macos_template.app/Contents/MacOS/godot_macos_release.universal + [ -f godot.macos.template_debug.universal ] && cp godot.macos.template_debug.universal macos_template.app/Contents/MacOS/godot_macos_debug.universal + chmod +x macos_template.app/Contents/MacOS/* 2>/dev/null || true + + zip -q -9 -r macos.zip macos_template.app + cp macos.zip "$TEMPLATES_DIR/macos.zip" + ;; + + windows) + echo "Processing Windows templates..." + for f in godot.windows.template_release.*.exe; do + [ -e "$f" ] || continue + arch=$(echo "$f" | sed -E 's/godot\.windows\.template_release\.(.*)\.exe/\1/') + cp "$f" "$TEMPLATES_DIR/windows_release_${arch}.exe" + done + for f in godot.windows.template_debug.*.exe; do + [ -e "$f" ] || continue + arch=$(echo "$f" | sed -E 's/godot\.windows\.template_debug\.(.*)\.exe/\1/') + cp "$f" "$TEMPLATES_DIR/windows_debug_${arch}.exe" + done + ;; + + linux) + echo "Processing Linux templates..." + for f in godot.linuxbsd.template_release.*; do + [ -e "$f" ] || continue + arch=$(echo "$f" | sed -E 's/godot\.linuxbsd\.template_release\.(.*)/\1/') + cp "$f" "$TEMPLATES_DIR/linux_release.${arch}" + done + for f in godot.linuxbsd.template_debug.*; do + [ -e "$f" ] || continue + arch=$(echo "$f" | sed -E 's/godot\.linuxbsd\.template_debug\.(.*)/\1/') + cp "$f" "$TEMPLATES_DIR/linux_debug.${arch}" + done + ;; + + ios) + echo "Processing iOS templates..." + [ -d apple_embedded_xcode ] && rm -r apple_embedded_xcode + [ -f ios.zip ] && rm ios.zip + cp -R ../misc/dist/apple_embedded_xcode ./ + + if [ -d libgodot.ios.template_release.xcframework ]; then + rm -rf apple_embedded_xcode/libgodot.ios.release.xcframework + cp -R libgodot.ios.template_release.xcframework apple_embedded_xcode/libgodot.ios.release.xcframework + fi + if [ -d libgodot.ios.template_debug.xcframework ]; then + rm -rf apple_embedded_xcode/libgodot.ios.debug.xcframework + cp -R libgodot.ios.template_debug.xcframework apple_embedded_xcode/libgodot.ios.debug.xcframework + fi + + pushd apple_embedded_xcode > /dev/null + zip -q -9 -r ../ios.zip * + popd > /dev/null + cp ios.zip "$TEMPLATES_DIR/ios.zip" + ;; + + android) + echo "Processing Android templates..." + [ -f android_source.zip ] && cp android_source.zip "$TEMPLATES_DIR/android_source.zip" + [ -f android_release.apk ] && cp android_release.apk "$TEMPLATES_DIR/android_release.apk" + [ -f android_debug.apk ] && cp android_debug.apk "$TEMPLATES_DIR/android_debug.apk" + ;; + + web) + echo "Processing Web (nothreads) templates..." + [ -f godot.web.template_release.wasm32.nothreads.zip ] && cp godot.web.template_release.wasm32.nothreads.zip "$TEMPLATES_DIR/web_nothreads_release.zip" + [ -f godot.web.template_debug.wasm32.nothreads.zip ] && cp godot.web.template_debug.wasm32.nothreads.zip "$TEMPLATES_DIR/web_nothreads_debug.zip" + [ -f godot.web.template_release.wasm32.nothreads.dlink.zip ] && cp godot.web.template_release.wasm32.nothreads.dlink.zip "$TEMPLATES_DIR/web_nothreads_dlink_release.zip" + [ -f godot.web.template_debug.wasm32.nothreads.dlink.zip ] && cp godot.web.template_debug.wasm32.nothreads.dlink.zip "$TEMPLATES_DIR/web_nothreads_dlink_debug.zip" + ;; + + *) + echo "Error: Unknown platform '$PLATFORM'." + echo "Available platforms: macos, windows, linux, ios, android, web" + exit 1 + ;; +esac + +echo "======================================" +echo "Successfully installed $PLATFORM templates to:" +echo "$TEMPLATES_DIR" + +popd > /dev/null +popd > /dev/null diff --git a/scripts/release-android.sh b/scripts/release-android.sh index 8ed7201..45ff1c7 100755 --- a/scripts/release-android.sh +++ b/scripts/release-android.sh @@ -15,4 +15,9 @@ for target in ${targets[@]}; do scripts/build.sh platform=android arch=x86_64 compiledb=no strip=yes target=${target} done +# After building the shared libraries for all architectures, generate the APKs and source zip +pushd godot/platform/android/java > /dev/null +./gradlew generateGodotTemplates +popd > /dev/null + popd > /dev/null # ${ROOTDIR} diff --git a/scripts/release-ios.sh b/scripts/release-ios.sh index 735d77e..2cc727f 100755 --- a/scripts/release-ios.sh +++ b/scripts/release-ios.sh @@ -16,4 +16,15 @@ for target in ${targets[@]}; do scripts/build.sh platform=ios arch=universal compiledb=no strip=yes target=${target} ios_simulator=yes done +# iOS requires .xcframework containing both device (arm64) and simulator (universal) binaries +for target in ${targets[@]}; do + if [ -f "godot/bin/libgodot.ios.${target}.arm64.a" ] && [ -f "godot/bin/libgodot.ios.${target}.simulator.universal.a" ]; then + /bin/rm -rf "godot/bin/libgodot.ios.${target}.xcframework" + xcodebuild -create-xcframework \ + -library "godot/bin/libgodot.ios.${target}.arm64.a" \ + -library "godot/bin/libgodot.ios.${target}.simulator.universal.a" \ + -output "godot/bin/libgodot.ios.${target}.xcframework" + fi +done + popd > /dev/null # ${ROOTDIR} diff --git a/scripts/release-macos.sh b/scripts/release-macos.sh index feae74e..10b2f50 100755 --- a/scripts/release-macos.sh +++ b/scripts/release-macos.sh @@ -13,4 +13,12 @@ for target in ${targets[@]}; do scripts/build.sh platform=macos arch=universal compiledb=no strip=yes target=${target} done +# Godot 4 macOS templates build x86_64 and arm64 separately even with arch=universal, so we lipo them. +if [ -f "godot/bin/godot.macos.template_release.x86_64" ] && [ -f "godot/bin/godot.macos.template_release.arm64" ]; then + lipo -create godot/bin/godot.macos.template_release.x86_64 godot/bin/godot.macos.template_release.arm64 -output godot/bin/godot.macos.template_release.universal +fi +if [ -f "godot/bin/godot.macos.template_debug.x86_64" ] && [ -f "godot/bin/godot.macos.template_debug.arm64" ]; then + lipo -create godot/bin/godot.macos.template_debug.x86_64 godot/bin/godot.macos.template_debug.arm64 -output godot/bin/godot.macos.template_debug.universal +fi + popd > /dev/null # ${ROOTDIR}