# 安装与可选依赖

> 触发词：pip、ensurepip、readelf、arm-none-eabi、winget
> 返回索引：[SKILL.md](../SKILL.md)

## 安装步骤

需要 Python 3.10+。

在使用本 Skill 之前，必须先安装 `mklink` Python 包。Agent 执行安装时必须把 shell `workdir` 设为本 `SKILL.md` 所在目录（也就是包含 `mklink/`、`references/`、`pyproject.toml` 的目录），或显式传入该目录路径；不要在用户项目根目录盲跑 `python -m pip install -e .`。

安装、`ensurepip`、`winget`、下载/解压工具链、修改 PATH、复制 exe 到用户 bin 都属于“改本机环境”。执行前必须先说明影响范围并得到用户确认。

```bash
# 1. 如果 Python 没有 pip，先引导安装
python -m ensurepip --upgrade

# 2. 从本 Skill 目录安装 mklink 包（editable 模式）
python -m pip install -e <skill-dir>

# 2b. 如果当前 workdir 已经是本 Skill 目录，也可以使用当前目录
python -m pip install -e .

# 3. 如果使用 Modbus 功能，确保安装 pymodbus（已在依赖中自动安装）
python -m pip install "pymodbus>=3.0"
```

安装完成后，`python -m mklink` 命令即可正常使用。


## GNU Arm 工具链（符号解析与 AXF 调试）

当用户要执行以下功能时，必须提供 GNU Arm 工具链中的 `arm-none-eabi-readelf`；HardFault 源码定位还需要 `arm-none-eabi-addr2line`：

- `python -m mklink symbols --source <firmware.axf>`
- `python -m mklink vofa <符号名>,... --visualize --source <firmware.axf>`
- `python -m mklink typeinfo --source <firmware.axf> --var <name>`
- `python -m mklink watch` / `superwatch`（使用 `--source <firmware.axf>` 时）
- `python -m mklink hardfault --source <firmware.axf> --sp <stack_pointer>`（需要 `arm-none-eabi-addr2line`）

先检查依赖是否已经可用：

```powershell
arm-none-eabi-readelf --version
arm-none-eabi-addr2line --version
```

若命令不存在，优先使用 winget 安装官方 GNU Arm Embedded Toolchain：

```powershell
winget install --id Arm.GnuArmEmbeddedToolchain -e --accept-package-agreements --accept-source-agreements
```

如果 winget 安装器被 UAC、GUI 或权限问题中断，使用无管理员权限的便携安装方式：

```powershell
$toolsDir = Join-Path $env:USERPROFILE ".local\tools"
$zipPath = Join-Path $toolsDir "arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi.zip"
New-Item -ItemType Directory -Force -Path $toolsDir | Out-Null

curl.exe -L "https://developer.arm.com/-/media/Files/downloads/gnu/14.2.rel1/binrel/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi.zip" -o $zipPath
tar -xf $zipPath -C $toolsDir

# 该 zip 解压后 bin 目录通常位于 $toolsDir\bin
$bin = Join-Path $toolsDir "bin"
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (($userPath -split ";") -notcontains $bin) {
  [Environment]::SetEnvironmentVariable("Path", "$userPath;$bin", "User")
}

# 让当前 PowerShell 立即可用
if (($env:Path -split ";") -notcontains $bin) {
  $env:Path = "$env:Path;$bin"
}
```

如果当前会话或 Python `subprocess.run(["arm-none-eabi-readelf", ...])` / `subprocess.run(["arm-none-eabi-addr2line", ...])` 仍找不到命令，可把真实 exe 复制到已在 PATH 中的用户 bin 目录：

```powershell
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.local\bin" | Out-Null
Copy-Item "$env:USERPROFILE\.local\tools\bin\arm-none-eabi-readelf.exe" "$env:USERPROFILE\.local\bin\arm-none-eabi-readelf.exe" -Force
Copy-Item "$env:USERPROFILE\.local\tools\bin\arm-none-eabi-addr2line.exe" "$env:USERPROFILE\.local\bin\arm-none-eabi-addr2line.exe" -Force
```

安装后必须验证：

```powershell
arm-none-eabi-readelf --version
arm-none-eabi-addr2line --version
python -c "import shutil, subprocess; print(shutil.which('arm-none-eabi-readelf')); print(shutil.which('arm-none-eabi-addr2line')); subprocess.run(['arm-none-eabi-readelf','--version'], check=True); subprocess.run(['arm-none-eabi-addr2line','--version'], check=True)"
python -m mklink symbols --source path/to/firmware.axf --filter "counter|sensor"
```


## GUI 依赖（Web GUI）

当用户需要以下功能时，需要安装 GUI 依赖：

- `python -m mklink serve` — 远程调试服务器（REST API + WebSocket JSON-RPC）
- `python -m mklink gui` — 启动 Web GUI（FastAPI 后端 + 预构建 Vue 静态资源）

### Python GUI 依赖

先检查是否已安装：

```powershell
python -c "import fastapi, uvicorn; print('GUI deps OK')"
```

若导入失败：

```powershell
python -m pip install -e "<skill-dir>[gui]"
```

当前包只包含预构建的 `gui/dist/` 静态资源，不包含前端源码、`package.json` 或 Tauri `src-tauri/` 工程。不要运行 `npm install`、`npx tauri dev` 或 Rust/Tauri 构建命令，除非用户另外提供完整前端源码。
