Metadata-Version: 2.1
Name: handsdk
Version: 1.0.0
Summary: 手部控制模块 - 支持多种手部类型的统一控制接口
Home-page: https://gitee.com/stellarrobot/handsdk.git
Author: tanzhiqiang
Author-email: zhiqiangtan89@gmail.com
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Cython
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: pyserial>=3.5
Requires-Dist: numpy<3,>=1.19
Requires-Dist: typing-extensions>=4.6
Requires-Dist: scipy<2,>=1.10

<!--
 * @File name: 
 * @Descripttion: 
 * @Author: tanzhiqiang
 * @Email: zhiqiangtan89@gmail.com
 * @Version: 
 * @Date: 2026-03-05 18:09:53
 * @History: 
-->
# hand 模块打包工具

将 `hand` 包打包为 wheel，支持字节码保护（build_wheel）和 Cython 编译为 .pyd（build_pyd）。

**默认行为**：两个工具均默认移除 .py 源文件（build_wheel 保留 .pyc，build_pyd 保留 .pyd/.so）。

SLCAN **native** 后端依赖 `hand/can_utils/slcan/` 下的 `slcan_core.dll`（Windows）或 `libslcan_core.so` / `libslcan_core.dylib`。打包前若无该文件，请先运行 **build_slcan** 将 CMake 产物复制到该目录（或与 zlgcan 一样预置二进制后再打 wheel）。

---

## MkDocs API 文档

使用本目录下的 `mkdocs.yml`、`.mkdocs_src` 与 `requirements-mkdocs.txt`（MkDocs + Material + mkdocstrings）生成 API 静态站点，输出目录为 **`docs/api_site`**（相对于 `handsdk` 根目录）。

在 **`handsdk` 根目录**执行：

```bash
cd handsdk
python -m pip install -r tools/requirements-mkdocs.txt
python -m mkdocs build -f tools/mkdocs.yml
```

本地预览（可选）：

```bash
python -m mkdocs serve -f tools/mkdocs.yml
```

---

## build_slcan.py - 编译 slcan_core（CMake）

在 ``hand/can_utils/slcan/cpp`` 调用 CMake，Release 构建后由 CMake 将动态库复制到 ``slcan/``（与 ``slcan_core_ctypes`` 加载路径一致）。

### 前置要求

- CMake 3.16+
- C++ 工具链（Windows: Visual Studio Build Tools；Linux: gcc；macOS: Xcode CLI Tools）

### 使用

**Windows:**

```batch
python tools\build_slcan.py
python tools\build_slcan.py --clean
```

**Linux / macOS:**

```bash
python3 tools/build_slcan.py
python3 tools/build_slcan.py --clean
```

或 ``build_slcan.bat`` / ``build_slcan.sh``（内部调用上述脚本）。

---

## build_wheel.py - 字节码保护 (.pyc)

将 Python 编译为 .pyc 并移除 .py 源文件，实现基础保护。

### 使用

**Windows:**
```batch
python tools\build_wheel.py                    # 默认移除 .py，输出到 dist/dist_output
python tools\build_wheel.py --no-bytecode       # 保留 .py 源文件
```

**Linux/macOS:**
```bash
./tools/build_wheel.sh
# 或
python3 tools/build_wheel.py                    # 默认移除 .py，输出到 dist/dist_output
python3 tools/build_wheel.py --no-bytecode     # 保留 .py 源文件
```

### 参数

| 参数 | 说明 |
|------|------|
| `-o`, `--output` | 输出目录 |
| `--no-bytecode` | 保留 .py 源文件（**默认移除 .py**，仅保留 .pyc） |
| `--no-example` | 不复制 example |
| `--no-docs` | 不复制 docs |

---

## build_pyd.py - Cython 编译 (.pyd)

使用 Cython 将 Python 编译为 .pyd (Windows) / .so (Linux) 原生扩展，保护强度高于 .pyc。

### 前置要求

- `pip install Cython`
- C 编译器：Windows 需 Visual Studio Build Tools；Linux 需 gcc/build-essential

### 使用

**Windows:**
```batch
python tools\build_pyd.py -o dist/dist_output_pyd   # 默认移除 .py，仅保留 .pyd
python tools\build_pyd.py --no-strip-source         # 保留 .py 源文件
```

**Linux/macOS:**
```bash
./tools/build_pyd.sh
# 或
python3 tools/build_pyd.py -o dist/dist_output_pyd   # 默认移除 .py，仅保留 .so
python3 tools/build_pyd.py --no-strip-source        # 保留 .py 源文件
```

### 参数

| 参数 | 说明 |
|------|------|
| `-o`, `--output` | 输出目录 |
| `--no-strip-source` | 保留 .py 源文件（**默认移除 .py**，仅保留 .pyd/.so） |
| `--no-example` | 不复制 example |
| `--no-docs` | 不复制 docs |

---

## 输出结构

```
dist/dist_output/
├── VERSION.json          # 版本信息
├── packages/
│   ├── hand-1.0.0-py3-none-any.whl
│   └── requirements.txt
├── docs/                 # 文档（可选）
└── example/              # 示例代码（可选）
```

## 使用方法

### Windows

```batch
# 双击或命令行运行
build_wheel.bat

# 或直接调用 Python 脚本
python tools\build_wheel.py                    # 默认移除 .py，输出到 dist/dist_output
python tools\build_wheel.py --no-bytecode -o dist/dist_output_source   # 保留 .py
```

### Linux / macOS

```bash
chmod +x tools/build_wheel.sh
./tools/build_wheel.sh

# 或直接调用
python3 tools/build_wheel.py                    # 默认移除 .py，输出到 dist/dist_output
python3 tools/build_wheel.py --no-bytecode -o dist/dist_output_source   # 保留 .py
```

### build_wheel 命令行参数

| 参数 | 说明 |
|------|------|
| `-o`, `--output` | 输出目录（默认：dist/dist_output） |
| `--no-bytecode` | 保留 .py 源码（**默认移除 .py**，仅保留 .pyc） |
| `--no-example` | 不复制 example 目录 |
| `--no-docs` | 不复制 docs 目录 |

## 字节码保护说明

- **默认（字节码模式）**：wheel 中仅保留 .pyc，移除 .py 源文件，实现基础保护
  - 注意：针对构建时的 Python 版本（如 3.12），其他版本需重新构建
- **`--no-bytecode`**：生成包含 .py 源码的 wheel

## 安装生成的 wheel

### 安装

```bash
# 进入输出目录（dist/dist_output 或 dist/dist_output_pyd）
cd dist/dist_output/packages   # 或 dist/dist_output_pyd/packages

# 安装 wheel（根据实际文件名调整）
pip install hand-1.0.0-py3-none-any.whl           # build_wheel 输出
pip install hand-1.0.0-cp312-cp312-win_amd64.whl # build_pyd 输出（Windows）
pip install hand-1.0.0-cp312-cp312-linux_x86_64.whl # build_pyd 输出（Linux）

# 或使用相对路径
pip install dist/dist_output/packages/hand-1.0.0-py3-none-any.whl
```

### 安装依赖（可选）

若需单独安装依赖：

```bash
pip install -r dist/dist_output/packages/requirements.txt
```

### 安装到用户目录（无需管理员权限）

```bash
pip install --user dist/dist_output/packages/hand-*.whl
```

### 验证安装

```bash
python -c "import hand; print(hand.__version__)"
```

---

## 卸载

```bash
pip uninstall hand
```

若提示确认，输入 `y` 回车。若已忘记是否安装，可先查看：

```bash
pip show hand
pip list | findstr hand   # Windows
pip list | grep hand      # Linux/macOS
```


```
# 1) 仅检查发布文件
python tools/publish_pypi.py --check

# 2) 上传到 TestPyPI（默认仓库就是 testpypi）
python tools/publish_pypi.py

# 3) 正式发布到 PyPI（需要显式确认）
python tools/publish_pypi.py --repository pypi --yes

# 4) 如果版本已存在，跳过已存在文件
python tools/publish_pypi.py --repository pypi --yes --skip-existing

```
