# Building and Cross-Compilation Guide

This comprehensive guide covers everything you need to know about building nushell plugins, including cross-compilation for multiple platforms.

## Table of Contents

- [Quick Start](#quick-start)
- [Prerequisites](#prerequisites)
- [Build Methods](#build-methods)
- [Cross-Compilation](#cross-compilation)
- [Docker Builds](#docker-builds)
- [Platform Support](#platform-support)
- [Configuration](#configuration)
- [Workflows](#workflows)
- [Distribution](#distribution)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Advanced Topics](#advanced-topics)

## Quick Start

### Native Build (Host Platform Only)
```bash
# Clone repository
git clone https://github.com/YOUR_ORG/nushell-plugins.git
cd nushell-plugins

# Build all plugins for your platform
just build

# Or using the script directly
./scripts/run.sh build_all.nu
```

### Cross-Platform Build
```bash
# Build for all supported platforms
just build-cross-all

# Build for specific platform
just build-cross linux-amd64

# Build and create distribution packages
just release-cross
```

## Prerequisites

### Required Tools

1. **Rust Toolchain** (1.70.0+)
   ```bash
   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
   ```

2. **Nushell** (0.107.1)
   ```bash
   # Install via cargo
   cargo install nu

   # Or download from https://github.com/nushell/nushell/releases
   ```

3. **Just** (optional but recommended)
   ```bash
   cargo install just
   ```

4. **Git** with submodules
   ```bash
   git clone --recursive https://github.com/YOUR_ORG/nushell-plugins.git
   ```

### Optional Tools

- **Docker** - For Docker-based cross-compilation
- **Cross-compilation toolchains** - For native cross-compilation

## Build Methods

### 1. Native Compilation

Build plugins for your current platform using the standard Rust toolchain.

```bash
# Basic build
just build

# Verbose output
just build-verbose

# Parallel build (experimental)
just build-parallel

# Build specific plugins
./scripts/run.sh build_all.nu --plugins nu_plugin_clipboard,nu_plugin_image
```

**Pros:**
- Fast compilation
- Native debugging support
- Simple setup

**Cons:**
- Only builds for current platform
- Limited cross-compilation support

### 2. Cross-Compilation

Build plugins for different platforms using Rust's cross-compilation features.

```bash
# List available targets
just build-targets

# Build for specific target
just build-cross linux-amd64
just build-cross darwin-arm64
just build-cross windows-amd64

# Build for all targets
just build-cross-all

# Parallel cross-compilation
just build-cross-parallel
```

**Pros:**
- Multiple platforms from single machine
- Fast execution
- No Docker dependency

**Cons:**
- May require target-specific toolchains
- Some targets may not work on all hosts

### 3. Docker-Based Cross-Compilation

Use Docker containers with pre-configured cross-compilation environments.

```bash
# Build Docker image
just build-docker-image

# Build specific target with Docker
just build-docker linux-arm64

# Force Docker for all builds
./scripts/run.sh build_cross.nu --all-targets --docker
```

**Pros:**
- Consistent build environment
- All toolchains pre-installed
- Works on any Docker-capable host

**Cons:**
- Slower than native compilation
- Requires Docker
- Larger resource usage

## Cross-Compilation

### Supported Platforms

| Platform | Target Triple | Native | Docker | Notes |
|----------|---------------|--------|---------|-------|
| **Linux AMD64** | `x86_64-unknown-linux-gnu` | ✅ | ✅ | Most common Linux |
| **Linux ARM64** | `aarch64-unknown-linux-gnu` | ⚠️ | ✅ | Requires cross toolchain |
| **macOS Intel** | `x86_64-apple-darwin` | 🍎 | ❌ | macOS host only |
| **macOS Apple Silicon** | `aarch64-apple-darwin` | 🍎 | ❌ | macOS host only |
| **Windows AMD64** | `x86_64-pc-windows-msvc` | 🪟 | ✅ | Windows host or Docker |

**Legend:**
- ✅ Fully supported
- ⚠️ Requires additional setup
- 🍎 macOS host required
- 🪟 Windows host required
- ❌ Not supported

### Setting Up Cross-Compilation

#### Linux → Linux ARM64
```bash
# Install cross-compilation toolchain (Ubuntu/Debian)
sudo apt-get install gcc-aarch64-linux-gnu

# Add Rust target
rustup target add aarch64-unknown-linux-gnu

# Configure environment
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc

# Build
just build-cross linux-arm64
```

#### Any → Windows (Docker)
```bash
# Build Docker image with Windows toolchain
just build-docker-image

# Cross-compile to Windows
just build-docker windows-amd64
```

### Configuration Files

#### Build Targets (`etc/build_targets.toml`)

```toml
[targets.linux-amd64]
rust_target = "x86_64-unknown-linux-gnu"
platform_name = "linux-amd64"
archive_format = "tar.gz"
docker_required = false
native_build = true
description = "Linux x86_64 (64-bit Intel/AMD)"

[targets.linux-arm64]
rust_target = "aarch64-unknown-linux-gnu"
platform_name = "linux-arm64"
archive_format = "tar.gz"
docker_required = true
native_build = false
description = "Linux ARM64 (64-bit ARM)"
linker = "aarch64-linux-gnu-gcc"
```

#### Environment Variables
```bash
# Cross-compilation linkers
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
export AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar

# Cargo configuration
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
```

## Docker Builds

### Docker Image

The cross-compilation Docker image includes:
- **Rust toolchain** (1.75.0)
- **Cross-compilation targets** for all supported platforms
- **System toolchains** (GCC, MinGW, etc.)
- **Build tools** (cargo, rustfmt, clippy)

### Docker Commands

```bash
# Build Docker image
just build-docker-image

# Rebuild from scratch
just build-docker-image-fresh

# Show Docker environment info
just docker-info

# Build specific plugin with Docker
just build-docker-plugin nu_plugin_clipboard linux-arm64

# Clean up Docker artifacts
just docker-cleanup
```

### Docker Workflow

```bash
# Complete Docker-based workflow
just docker-flow

# This runs:
# 1. just validate-nushell
# 2. just build-docker-image
# 3. just build-cross-all --docker
# 4. just collect-all
# 5. just pack-all
```

### Manual Docker Usage

```bash
# Run interactive Docker container
docker run -it --rm \
  -v $(pwd):/workspace \
  -w /workspace \
  nushell-plugins-cross:latest \
  bash

# Build specific target in container
docker run --rm \
  -v $(pwd):/workspace \
  -w /workspace/nu_plugin_clipboard \
  nushell-plugins-cross:latest \
  cargo build --release --target aarch64-unknown-linux-gnu
```

## Platform Support

### Linux

**Supported Architectures:**
- x86_64 (AMD64) - Native and Docker
- ARM64 (AArch64) - Docker recommended
- ARM32 (ARMv7) - Docker only, disabled by default

**Dependencies:**
```bash
# Ubuntu/Debian
sudo apt-get install build-essential libssl-dev pkg-config

# Cross-compilation toolchains
sudo apt-get install gcc-aarch64-linux-gnu gcc-arm-linux-gnueabihf
```

### macOS

**Supported Architectures:**
- Intel (x86_64) - Native only
- Apple Silicon (ARM64) - Native only

**Dependencies:**
```bash
# Install Xcode command line tools
xcode-select --install

# Add Rust targets
rustup target add x86_64-apple-darwin aarch64-apple-darwin
```

**Cross-compilation:**
```bash
# On Apple Silicon, build for Intel
just build-cross darwin-amd64

# On Intel, build for Apple Silicon (may not work)
just build-cross darwin-arm64
```

### Windows

**Supported Architectures:**
- x86_64 (AMD64) - Native and Docker

**Native Dependencies:**
- Visual Studio Build Tools or Visual Studio Community
- Windows SDK

**Docker Alternative:**
```bash
# Use Docker for Windows builds on any platform
just build-docker windows-amd64
```

## Configuration

### Global Configuration

The main configuration file is `etc/build_targets.toml`:

```toml
[metadata]
version = "1.0.0"
description = "Cross-compilation targets for nushell plugins"

[defaults]
docker_image = "nushell-plugins-cross:latest"
strip_binaries = true
optimize_size = true

[targets.custom-target]
rust_target = "x86_64-unknown-linux-musl"
platform_name = "linux-amd64-musl"
archive_format = "tar.gz"
docker_required = false
description = "Linux x86_64 with musl libc"
enabled = true
```

### Environment Configuration

Create an `env` file for local overrides:

```bash
# env file
TARGET_PATH=distribution
INSTALL_BIN_PATH=/usr/local/bin
BIN_ARCHIVES_DIR_PATH=bin_archives
APP_NAME=nushell-plugins
```

### Plugin-Specific Configuration

Some plugins may require special build configurations:

```toml
# In plugin's Cargo.toml
[package.metadata.cross]
image = "ghcr.io/cross-rs/cross:aarch64-unknown-linux-gnu"

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
```

## Workflows

### Development Workflows

#### Standard Development
```bash
just dev-flow
# 1. Validate nushell version
# 2. Check upstream changes
# 3. Build for host platform
# 4. Run tests
# 5. Show status
```

#### Cross-Platform Development
```bash
just dev-flow-cross
# 1. Validate nushell version
# 2. Check upstream changes
# 3. Build for all platforms
# 4. Show status
```

#### Quality Assurance
```bash
just quality-flow
# 1. Validate nushell version
# 2. Format code
# 3. Run clippy linting
# 4. Run tests
```

### Release Workflows

#### Standard Release
```bash
just release-flow
# 1. Validate nushell version
# 2. Build for host platform
# 3. Collect binaries
# 4. Create packages
```

#### Cross-Platform Release
```bash
just release-flow-cross
# 1. Validate nushell version
# 2. Build for all platforms
# 3. Collect all binaries
# 4. Create packages with checksums
```

#### CI Simulation
```bash
just ci-flow
# Simulates exactly what GitHub Actions will run
```

### Custom Workflows

You can create custom workflows by combining individual commands:

```bash
# Custom workflow for testing
just validate-nushell
just build-cross linux-amd64
just build-cross darwin-arm64
just test
just collect-platform linux-amd64
just pack-platform linux-amd64
```

## Distribution

### Collection

Collect built binaries for distribution:

```bash
# Collect all platforms
just collect-all

# Collect specific platform
just collect-platform linux-amd64

# List what can be collected
just collect-platforms
```

### Packaging

Create distribution archives:

```bash
# Package all platforms
just pack-all

# Package with checksums
just pack-checksums

# Package specific platform
just pack-platform darwin-arm64

# List packaging options
just pack-platforms
```

### Directory Structure

After building and packaging:

```
distribution/
├── linux-amd64/
│   ├── nu_plugin_clipboard
│   ├── nu_plugin_image
│   ├── install_nu_plugins.nu
│   ├── LICENSE
│   └── README
├── darwin-arm64/
│   └── [same structure]
└── windows-amd64/
    ├── nu_plugin_clipboard.exe
    └── [same structure]

bin_archives/
├── linux-amd64-nushell-plugins.tar.gz
├── darwin-arm64-nushell-plugins.tar.gz
├── windows-amd64-nushell-plugins.zip
└── checksums.txt
```

### Checksums

All distribution packages include SHA256 checksums:

```bash
# Generate checksums
just pack-checksums

# Verify downloaded archive
sha256sum -c checksums.txt

# Manual verification
sha256sum linux-amd64-nushell-plugins.tar.gz
```

## Troubleshooting

### Common Issues

#### Version Mismatch
```bash
# Error: Nushell version mismatch detected
# Fix: Update versions automatically
just fix-nushell

# Or manually check and fix
./scripts/run.sh check_version.nu --fix
```

#### Missing Cross-Compilation Target
```bash
# Error: target 'aarch64-unknown-linux-gnu' not found
# Fix: Install the target
rustup target add aarch64-unknown-linux-gnu
```

#### Cross-Compilation Linker Error
```bash
# Error: linker 'aarch64-linux-gnu-gcc' not found
# Fix: Install cross-compilation toolchain
sudo apt-get install gcc-aarch64-linux-gnu

# Set environment variable
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
```

#### Docker Build Failures
```bash
# Error: Docker daemon not running
# Fix: Start Docker service
sudo systemctl start docker

# Error: Docker image not found
# Fix: Build the image
just build-docker-image

# Error: Permission denied in Docker
# Fix: Add user to docker group
sudo usermod -aG docker $USER
```

#### Build Failures

**Plugin-specific failures:**
```bash
# Debug specific plugin
cd nu_plugin_clipboard
cargo build --release --verbose

# Check plugin dependencies
cargo tree
```

**Cross-compilation failures:**
```bash
# Use Docker instead of native cross-compilation
just build-docker linux-arm64

# Check target support
rustup target list | grep installed
```

### Debug Mode

Enable verbose output for troubleshooting:

```bash
# Verbose build output
just build-verbose

# Verbose cross-compilation
./scripts/run.sh build_cross.nu --all-targets --verbose

# Debug Docker builds
./scripts/run.sh build_docker_cross.nu --verbose
```

### Log Files

Build logs are preserved for debugging:

```bash
# View recent build logs
ls -la target/*/build/*/out/

# Search for specific errors
grep -r "error" target/*/build/*/stderr
```

## FAQ

### General Questions

**Q: What platforms are supported?**
A: Linux (AMD64, ARM64), macOS (Intel, Apple Silicon), and Windows (AMD64). See the [Platform Support](#platform-support) section for details.

**Q: Do I need Docker for cross-compilation?**
A: Not always. Native cross-compilation works for many targets, but Docker provides a more consistent environment and supports more target combinations.

**Q: How long does cross-compilation take?**
A: Building all platforms takes 10-30 minutes depending on your hardware. Parallel builds (`just build-cross-parallel`) can significantly reduce this time.

**Q: Can I add new platforms?**
A: Yes! Edit `etc/build_targets.toml` to add new targets. See [Configuration](#configuration) for details.

### Build Questions

**Q: Why do some builds fail on my platform?**
A: Cross-compilation has limitations. macOS targets can only be built on macOS, and some Linux ARM64 builds require specific toolchains. Use Docker builds as a fallback.

**Q: How can I speed up builds?**
A: Use parallel builds (`--parallel`), enable incremental compilation, and use Docker layer caching. Consider building only the platforms you need.

**Q: Can I build just one plugin?**
A: Yes! Use `./scripts/run.sh build_all.nu --plugins nu_plugin_clipboard` or build manually in the plugin directory.

**Q: Why are Windows binaries so large?**
A: Windows binaries include the MSVC runtime. You can reduce size by using the GNU toolchain or enabling link-time optimization.

### Docker Questions

**Q: How much disk space does the Docker image use?**
A: The cross-compilation image is approximately 2-3 GB, including all toolchains and dependencies.

**Q: Can I use my own Docker image?**
A: Yes! Modify the `docker.image_tag` setting in `etc/build_targets.toml` to use a custom image.

**Q: How do I update the Docker image?**
A: Run `just build-docker-image-fresh` to rebuild from scratch with the latest dependencies.

### Distribution Questions

**Q: How do I install the plugins?**
A: Use the universal installer: `curl -L https://github.com/YOUR_ORG/nushell-plugins/releases/latest/download/install.sh | sh`

**Q: Can I distribute individual plugins?**
A: Yes! Each plugin binary is self-contained. Just copy the `nu_plugin_*` files to the target system.

**Q: What's the difference between tar.gz and zip archives?**
A: Unix-like systems (Linux, macOS) use tar.gz for better compression and permission preservation. Windows uses zip for compatibility.

### Troubleshooting Questions

**Q: Build fails with "permission denied" errors**
A: Check that you have write permissions to the target directory and that antivirus software isn't blocking the builds.

**Q: Cross-compilation fails with "unsupported target"**
A: Install the target with `rustup target add TARGET_NAME` or use Docker builds instead.

**Q: Docker builds are very slow**
A: Make sure Docker has sufficient resources allocated. Consider using Docker BuildKit for faster builds.

## Advanced Topics

### Custom Build Targets

Add support for new platforms by editing `etc/build_targets.toml`:

```toml
[targets.linux-musl]
rust_target = "x86_64-unknown-linux-musl"
platform_name = "linux-amd64-musl"
archive_format = "tar.gz"
docker_required = false
description = "Linux x86_64 with musl libc"
strip_binaries = true

[environment.linux-musl]
CC = "musl-gcc"
```

### Build Optimization

#### Link-Time Optimization (LTO)
```toml
# In Cargo.toml
[profile.release]
lto = true
codegen-units = 1
panic = "abort"
strip = "symbols"
```

#### Size Optimization
```toml
[profile.release]
opt-level = "z"  # Optimize for size
lto = true
strip = "symbols"
```

#### Build Scripts

Create custom build scripts for complex scenarios:

```bash
#!/bin/bash
# scripts/custom_build.sh

# Custom build with specific optimizations
export RUSTFLAGS="-C target-cpu=native"
cargo build --release --target x86_64-unknown-linux-gnu

# Strip debug symbols
strip target/x86_64-unknown-linux-gnu/release/nu_plugin_*
```

### Continuous Integration

The repository includes GitHub Actions workflows for:

- **Build & Test** (`.github/workflows/build.yml`)
- **Release** (`.github/workflows/release.yml`)
- **Nightly Builds** (`.github/workflows/nightly.yml`)

To set up in your own repository:

1. Copy the `.github/workflows/` directory
2. Update the repository references
3. Configure GitHub secrets if needed
4. Customize the build matrix for your needs

### Plugin Development

When developing new plugins:

1. **Use the template:**
   ```bash
   just make-plugin nu_plugin_yourname
   ```

2. **Follow the plugin structure:**
   ```
   nu_plugin_yourname/
   ├── Cargo.toml
   ├── src/
   │   ├── main.rs
   │   └── lib.rs
   └── README.md
   ```

3. **Test cross-compilation early:**
   ```bash
   just build-cross-all
   ```

4. **Add to the registry:**
   Update `etc/plugin_registry.toml` if the plugin has an upstream repository.

### Performance Tuning

#### Parallel Compilation
```bash
# Set number of parallel jobs
export CARGO_BUILD_JOBS=8

# Use parallel cross-compilation
just build-cross-parallel
```

#### Caching
```bash
# Use sccache for distributed compilation caching
cargo install sccache
export RUSTC_WRAPPER=sccache
```

#### Memory Usage
```bash
# Limit memory usage for large builds
export CARGO_BUILD_RUSTFLAGS="-C link-arg=-Wl,--no-keep-memory"
```

---

## Getting Help

- **Issues**: [GitHub Issues](https://github.com/YOUR_ORG/nushell-plugins/issues)
- **Discussions**: [GitHub Discussions](https://github.com/YOUR_ORG/nushell-plugins/discussions)
- **Documentation**: [Repository Wiki](https://github.com/YOUR_ORG/nushell-plugins/wiki)
- **Nushell Community**: [Discord](https://discord.gg/NtAbbGn) | [Reddit](https://www.reddit.com/r/Nushell/)

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on contributing to the build system and adding new platforms or features.

---

*This documentation is maintained by the nushell-plugins team. Last updated: 2024-09-20*