Files
hakorune/docs/guides/build/cross-platform.md
Moe Charm cdb75dfac1 docs: 包括的なビルドガイドを追加
- docs/guides/build/README.md - すべてのビルドパターンを網羅
- docs/guides/build/cross-platform.md - クロスプラットフォーム開発ガイド
- docs/guides/build/windows-distribution.md - Windows配布版作成の詳細手順
- docs/guides/build/aot-compilation.md - AOTネイティブコンパイルガイド
- CLAUDE.mdにビルドガイドへのリンクを追加
- cargo-xwinでのWindows向けビルド方法を文書化
- プラグインの自動拡張子変換機能(ChatGPT5実装)を説明
2025-08-29 23:38:59 +09:00

307 lines
7.4 KiB
Markdown

# 🌍 Cross-Platform Development Guide
How to build and distribute Nyash applications across Windows, Linux, and macOS.
## 🎯 Philosophy: Write Once, Run Everywhere
Nyash achieves true cross-platform compatibility through:
- **Platform-agnostic configuration** (nyash.toml)
- **Automatic library resolution** (plugin loader)
- **Unified plugin system** (C ABI)
## 🔄 Cross-Platform Plugin Loading
### The Magic Behind It
ChatGPT5's `resolve_library_path` implementation in `src/runtime/plugin_loader_v2.rs`:
```rust
// Automatic extension mapping
let cur_ext: &str = if cfg!(target_os = "windows") { "dll" }
else if cfg!(target_os = "macos") { "dylib" }
else { "so" };
// Windows: try without 'lib' prefix
if cfg!(target_os = "windows") {
if let Some(stripped) = stem.strip_prefix("lib") {
// Try nyash_plugin.dll instead of libnyash_plugin.dll
}
}
```
### Configuration That Works Everywhere
```toml
# nyash.toml - Same file works on all platforms!
[libraries."libnyash_filebox_plugin.so"]
boxes = ["FileBox"]
path = "libnyash_filebox_plugin.so" # .so works everywhere!
```
**Runtime Resolution:**
- Linux: `libnyash_filebox_plugin.so`
- Windows: `nyash_filebox_plugin.dll` ✅ (lib prefix removed)
- macOS: `libnyash_filebox_plugin.dylib`
## 🏗️ Building for Multiple Platforms
### From Linux/WSL (Recommended Hub)
```bash
# For Linux (native)
cargo build --release
# For Windows
cargo xwin build --target x86_64-pc-windows-msvc --release
# For macOS (requires macOS SDK)
# cargo build --target x86_64-apple-darwin --release
```
### Build Matrix
| Host OS | Target | Tool | Command |
|---------|--------|------|---------|
| Linux/WSL | Linux | cargo | `cargo build --release` |
| Linux/WSL | Windows | cargo-xwin | `cargo xwin build --target x86_64-pc-windows-msvc` |
| Windows | Windows | cargo | `cargo build --release` |
| Windows | Linux | cross | `cross build --target x86_64-unknown-linux-gnu` |
| macOS | macOS | cargo | `cargo build --release` |
| macOS | Linux | cross | `cross build --target x86_64-unknown-linux-gnu` |
## 📦 Creating Universal Distributions
### Directory Structure
```
nyash-universal/
├── bin/
│ ├── linux/
│ │ └── nyash
│ ├── windows/
│ │ └── nyash.exe
│ └── macos/
│ └── nyash
├── plugins/
│ ├── linux/
│ │ ├── libnyash_filebox_plugin.so
│ │ └── ...
│ ├── windows/
│ │ ├── nyash_filebox_plugin.dll
│ │ └── ...
│ └── macos/
│ ├── libnyash_filebox_plugin.dylib
│ └── ...
├── nyash.toml # Universal config
├── examples/
└── README.md
```
### Universal Launcher Script
Create `run.sh` (Linux/macOS) and `run.bat` (Windows):
**run.sh:**
```bash
#!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
OS="$(uname -s)"
case "$OS" in
Linux*) BIN="linux/nyash" ;;
Darwin*) BIN="macos/nyash" ;;
*) echo "Unsupported OS: $OS"; exit 1 ;;
esac
export NYASH_PLUGIN_PATH="$SCRIPT_DIR/plugins/$(echo $OS | tr '[:upper:]' '[:lower:]')"
"$SCRIPT_DIR/bin/$BIN" "$@"
```
**run.bat:**
```batch
@echo off
set SCRIPT_DIR=%~dp0
set NYASH_PLUGIN_PATH=%SCRIPT_DIR%plugins\windows
"%SCRIPT_DIR%bin\windows\nyash.exe" %*
```
## 🔌 Plugin Compatibility
### Building Plugins for All Platforms
Automated build script (`build_all_plugins.sh`):
```bash
#!/bin/bash
PLUGINS="filebox array map string integer net"
for plugin in $PLUGINS; do
echo "Building $plugin plugin..."
cd "plugins/nyash-$plugin-plugin" || exit 1
# Linux
cargo build --release
cp target/release/lib*.so ../../dist/plugins/linux/
# Windows (from WSL)
cargo xwin build --target x86_64-pc-windows-msvc --release
cp target/x86_64-pc-windows-msvc/release/*.dll ../../dist/plugins/windows/
cd ../..
done
```
### Plugin ABI Stability
The C ABI ensures plugins work across platforms:
```c
// Standard C ABI functions (same on all platforms)
extern "C" {
fn nyash_plugin_abi_version() -> u32;
fn nyash_plugin_init(host_fns: *const HostFunctions) -> i32;
fn nyash_plugin_invoke(params: *const InvokeParams) -> i32;
fn nyash_plugin_shutdown();
}
```
## 🎯 Testing Cross-Platform Builds
### Test Matrix Script
```bash
#!/bin/bash
# test_all_platforms.sh
echo "=== Testing Linux Build ==="
./target/release/nyash test/cross_platform.nyash
echo "=== Testing Windows Build (Wine) ==="
wine ./target/x86_64-pc-windows-msvc/release/nyash.exe test/cross_platform.nyash
echo "=== Testing WASM Build ==="
wasmtime ./target/wasm32-wasi/release/nyash.wasm test/cross_platform.nyash
```
### Cross-Platform Test Program
```nyash
// test/cross_platform.nyash
print("Platform Test Starting...")
// Test basic plugins
local arr = new ArrayBox()
arr.push("Cross")
arr.push("Platform")
arr.push("Success!")
print("Array test: " + arr.get(0) + "-" + arr.get(1) + " " + arr.get(2))
// Test file operations (platform-specific paths)
local file = new FileBox()
if file {
print("FileBox available on this platform")
}
print("✅ All tests passed!")
```
## 🚀 CI/CD for Cross-Platform
### GitHub Actions Example
```yaml
name: Cross-Platform Build
on: [push, pull_request]
jobs:
build:
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: macos-latest
target: x86_64-apple-darwin
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Test
run: cargo test --release --target ${{ matrix.target }}
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: nyash-${{ matrix.target }}
path: target/${{ matrix.target }}/release/nyash*
```
## 💡 Best Practices
### 1. Always Test on Target Platform
```bash
# Quick test after cross-compile
wine ./nyash.exe --version # Windows binary on Linux
```
### 2. Use Platform-Agnostic Paths
```nyash
// Bad
local file = new FileBox()
file.open("C:\\data\\file.txt", "r") // Windows-specific
// Good
local file = new FileBox()
file.open("./data/file.txt", "r") // Works everywhere
```
### 3. Handle Platform Differences Gracefully
```nyash
box PlatformHelper {
static getPlatformName() {
// Future: return actual platform
return "universal"
}
static getPathSeparator() {
// Future: return platform-specific separator
return "/"
}
}
```
## 🔧 Troubleshooting
### "Can't find plugin" after cross-compile
- Check file naming (lib prefix on Windows)
- Verify correct architecture (x86_64 vs ARM)
- Use `--verbose` flag for detailed logs
### Different behavior across platforms
- File path separators (`/` vs `\`)
- Case sensitivity (Linux/macOS vs Windows)
- Line endings (LF vs CRLF)
### Performance variations
- Debug vs Release builds
- Native CPU optimizations
- Plugin loading overhead
## 📚 References
- [Plugin System Architecture](../../reference/plugin-system/)
- [Build Configuration](README.md)
- [Platform-Specific Notes](../../reference/platform-notes.md)