# Mac 上构建 Windows 程序完整指南

## 📋 概述

本指南介绍如何在 macOS 上使用 Cangjie 语言和 cjpm 工具链交叉编译 Codelin 项目，生成可在 Windows 系统上运行的二进制文件。

## 🔍 技术原理

### Cangjie 交叉编译支持

Cangjie 编译器基于 LLVM，支持交叉编译。通过 `cjpm build --target` 参数可以指定目标平台，编译器会自动使用对应的工具链和标准库。

### Windows 目标平台

Codelin 项目支持两种 Windows 目标平台：

1. **x86_64-unknown-windows-gnu** (GNU ABI)
   - 使用 GNU 工具链
   - 适合与 GNU 工具链兼容的环境

2. **x86_64-w64-mingw32** (MinGW-w64)
   - 使用 MinGW-w64 工具链
   - 更轻量，适合 Windows 原生环境
   - **推荐使用**

## 📦 前置条件

### 1. 环境变量

```bash
# 必需
export MAGIC_PATH=/path/to/magic

# 可选（如果使用 Cangjie SDK 自带的工具链）
export CANGJIE_HOME=/path/to/cangjie
```

### 2. Windows 标准库

确保已安装 Windows 版本的 `cangjie-stdx`：

```bash
# 检查标准库是否存在
ls -la $MAGIC_PATH/libs/cangjie-stdx-windows-x64-1.0.0.1/windows_x86_64_llvm/static/stdx
```

### 3. 交叉编译工具链

#### 选项 A: 使用 Homebrew 安装 MinGW-w64（推荐）

```bash
# 安装 MinGW-w64
brew install mingw-w64

# 验证安装
x86_64-w64-mingw32-gcc --version
```

#### 选项 B: 使用 Cangjie SDK 自带的工具链

如果 Cangjie SDK 已配置 Windows 交叉编译工具链，可以直接使用。

## 🚀 构建步骤

### 方法 1: 使用构建脚本（推荐）

```bash
# 使用默认目标 (x86_64-w64-mingw32)
bash scripts/build-windows.sh

# 或指定目标
bash scripts/build-windows.sh x86_64-unknown-windows-gnu
```

### 方法 2: 手动构建

```bash
# 1. 切换到项目根目录
cd /path/to/codelin

# 2. 备份并应用静态配置
cp scripts/cli-static.toml cjpm.toml

# 3. 清理构建目录
cjpm clean

# 4. 交叉编译
cjpm build --target=x86_64-w64-mingw32 -V

# 5. 查找生成的二进制文件
find target -name "*.exe" -o -name "codelin"
```

## 📁 输出位置

构建成功后，二进制文件位于：

```
binary/windows/codelin-x86_64-w64-mingw32.exe
```

或

```
target/x86_64-w64-mingw32/release/bin/codelin.exe
```

## 🔧 配置说明

### cjpm.toml 中的 Windows 配置

项目已在 `cjpm.toml` 和 `scripts/cli-static.toml` 中配置了 Windows 目标：

```toml
# MinGW-w64 目标
[target.x86_64-w64-mingw32]
  compile-option = "-lcrypt32"

[target.x86_64-w64-mingw32.bin-dependencies]
  path-option = ["${MAGIC_PATH}/libs/cangjie-stdx-windows-x64-1.0.0.1/windows_x86_64_llvm/static/stdx"]

# GNU ABI 目标
[target.x86_64-unknown-windows-gnu]
  compile-option = "--cfg \"ohos=false\""

[target.x86_64-unknown-windows-gnu.bin-dependencies]
  path-option = ["${MAGIC_PATH}/libs/cangjie-stdx-windows-x64-1.0.0.1/windows_x86_64_llvm/static/stdx"]
```

## ⚠️ 常见问题

### 问题 1: 找不到交叉编译工具链

**症状：**
```
error: linker `x86_64-w64-mingw32-gcc` not found
```

**解决方案：**
```bash
# 安装 MinGW-w64
brew install mingw-w64

# 或配置 Cangjie SDK 的工具链路径
export PATH=$CANGJIE_HOME/toolchain/bin:$PATH
```

### 问题 2: 找不到 Windows 标准库

**症状：**
```
error: cannot find library `stdx`
```

**解决方案：**
1. 检查 `MAGIC_PATH` 环境变量是否正确
2. 确认 Windows 标准库已安装：
   ```bash
   ls -la $MAGIC_PATH/libs/cangjie-stdx-windows-x64-*/
   ```
3. 如果不存在，需要下载并安装 Windows 版本的 `cangjie-stdx`

### 问题 3: FFI 库编译失败

**症状：**
```
error: failed to compile FFI library
```

**解决方案：**
1. 检查 FFI 源文件是否存在：
   ```bash
   ls -la ffi/*.c
   ```
2. 对于 Windows 目标，可能需要使用 MinGW 工具链编译 FFI：
   ```bash
   x86_64-w64-mingw32-gcc -c ffi/raw_input.c -o ffi/raw_input.o
   x86_64-w64-mingw32-ar rcs ffi/librawinput.a ffi/raw_input.o
   ```

### 问题 4: 静态链接失败

**症状：**
```
error: undefined reference to `...`
```

**解决方案：**
1. 确保使用静态配置（`cli-static.toml`）
2. 检查 `compile-option` 中是否包含 `--static-libs --static-std --static`
3. 确保所有依赖库都是静态链接的

## 🧪 验证构建结果

### 在 Mac 上验证

```bash
# 检查文件类型
file binary/windows/codelin-x86_64-w64-mingw32.exe

# 应该显示: PE32+ executable (console) x86-64, for MS Windows
```

### 在 Windows 上测试

1. 将 `.exe` 文件复制到 Windows 系统
2. 在 Windows 上运行：
   ```cmd
   codelin-x86_64-w64-mingw32.exe --help
   ```

## 📚 参考资源

### Cangjie 官方文档

- [Cangjie 交叉编译文档](https://docs.cangjie-lang.cn/docs/1.0.0/tools/source_zh_cn/tools/cjpm_manual_cjnative_community)
- [编译选项说明](https://docs.cangjie-lang.cn/docs/1.0.0/user_manual/source_zh_cn/Appendix/compile_options)

### 相关文件

- `scripts/build-windows.sh` - Windows 构建脚本
- `scripts/cli-static.toml` - 静态链接配置
- `scripts/BUILD_GUIDE.md` - 通用构建指南

## 🎯 最佳实践

1. **使用静态链接**：确保 Windows 程序不依赖外部 DLL
2. **选择 MinGW-w64 目标**：更轻量，兼容性更好
3. **验证工具链**：构建前检查交叉编译工具链是否可用
4. **保存构建日志**：便于排查问题
5. **测试 Windows 兼容性**：在真实 Windows 环境中测试

## 📝 构建脚本功能

`build-windows.sh` 脚本提供以下功能：

- ✅ 自动检查环境变量和依赖
- ✅ 验证交叉编译工具链
- ✅ 备份和恢复配置文件
- ✅ 清理 FFI 和构建目录
- ✅ 执行交叉编译并保存日志
- ✅ 自动查找和复制二进制文件
- ✅ 显示详细的构建信息

## 🔄 持续集成

可以在 CI/CD 流程中集成 Windows 构建：

```yaml
# GitHub Actions 示例
- name: Build Windows
  run: |
    export MAGIC_PATH=${{ env.MAGIC_PATH }}
    bash scripts/build-windows.sh
  env:
    MAGIC_PATH: ${{ secrets.MAGIC_PATH }}
```

## 📊 构建时间

典型构建时间（Mac M1）：
- 清理: ~5 秒
- 编译: ~2-5 分钟（取决于项目大小）
- 总计: ~3-6 分钟

