Metadata-Version: 2.4
Name: toPYD
Version: 0.4
Summary: 将Python源文件编译为 pyd/so 二进制扩展模块
Project-URL: Homepage, https://github.com/yourusername/your-package-name
Project-URL: Repository, https://github.com/yourusername/your-package-name
Author: GoodIdear
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.8
Requires-Dist: click>=8.0.0
Requires-Dist: cython>=3.0.0
Requires-Dist: pathspec>=0.12.1
Requires-Dist: pyinstaller>=6.15.0
Requires-Dist: setuptools>=70.0.0
Description-Content-Type: text/markdown

# toPYD - Python 代码编译为 pyd 工具

一个用于将 Python 源代码文件（.py/.pyx）批量编译为二进制扩展模块（.pyd/.so）的命令行工具，基于 Cython 实现。

## 功能特点

- 🚀 批量编译 Python 源文件为二进制扩展模块（.pyd 或 .so）
- 📁 支持自定义排除规则和 .gitignore 集成
- 🏗️ 保留原始目录结构输出编译结果
- 📦 自动提取所有源文件中的 import 语句并生成 `hidden_import.py` 文件（可用于 PyInstaller 等打包工具）
- 🧹 自动清理编译后的文件名（去除中间平台标识）
- 💻 提供友好的命令行界面

## 安装

### 使用 uv（推荐）

```bash
uv add topyd

或

pip install topyd
```

## 工具简介
`toPYD` 是一体化 Python 编译打包工具，分为两大核心能力：
1. `setup`：基于 Cython 将 `.py/.pyx` 源码编译为平台二进制文件（Windows `.pyd` / Linux/Mac `.so`），自动生成依赖导入清单 `hidden_import.py`；
2. `installer`：基于 PyInstaller 对编译后的二进制文件打包，自动复刻源码目录结构、支持透传全部 PyInstaller 原生参数，解决模块路径缺失、隐藏导入报错问题。

支持两种运行模式：
1. **CLI 命令行模式**（推荐）：安装后全局调用 `topyd`；
2. **脚本直接调用模式**：单独执行底层函数 `to_pyd()` / `build_exe()`，用于项目内自动化脚本。


## CLI 命令使用指南
### setup 命令（源码编译 PYD/SO）
#### 命令功能
批量编译 Python 源码为二进制扩展，支持指定文件/全局扫描、gitignore 过滤、自动导出依赖清单。
#### 完整参数
| 参数 | 简写 | 类型 | 默认值 | 说明 |
|------|------|------|--------|------|
| --files | -f | 多文件 | 无 | 指定单个/多个源码文件，可重复传参；与 `-a` 互斥 |
| --all | -a | 布尔开关 | False | 扫描 `source-root` 下全部 `.py/.pyx`；与 `-f` 互斥 |
| --exclude | -e | 多路径 | 无 | 排除目录/文件，语法同 gitignore，可多次传入 |
| --exclude-file | -ef | 字符串 | True | 排除规则文件；`True`/`t` 使用当前 `.gitignore`；`false/f` 关闭；传入文件路径自定义规则 |
| --source-root | -s | 路径 | `.` | 源码根目录 |
| --output-dir | -o | 路径 | `build_pyd` | PYD/SO 编译产物输出目录 |
| --c-files-dir | -c | 路径 | `build/c_files` | Cython 临时C源码存放目录 |
| --hidden-import | 无 | 布尔 | True | 全局扫描(-a)时自动生成 `hidden_import.py`；单独指定文件(-f)强制关闭 |
| --alone | 无 | 布尔 | False | 独立文件编译模式，适配特殊打包场景 |

#### 约束规则
1. `-f` 和 `-a` 必须二选一，不能同时不传或同时使用；
2. 仅使用 `-a` 全局扫描时，才会生成 `hidden_import.py` 依赖清单。

#### 使用示例
```bash
# 1. 全局编译项目全部py文件，读取gitignore过滤
topyd setup -a -s ./src -o ./dist_pyd

# 2. 指定单个文件编译，关闭gitignore
topyd setup -f main.py -f core/utils.py -ef false

# 3. 全局编译+自定义排除目录+自定义gitignore文件
topyd setup -a -e tests/ -e demo/ -ef ./.custom_ignore
```

### installer 命令（PyInstaller 打包）
#### 命令功能
读取编译后的 pyd/so 文件打包，自动复刻源码目录层级、自动加载隐藏导入，支持透传所有 PyInstaller 原生参数。
#### 参数说明
| 参数 | 简写 | 类型 | 默认值 | 说明                               |
|------|------|------|--------|----------------------------------|
| --main-file | -m | 必填路径 | 无 | 程序入口启动脚本，支持绝对/相对路径               |
| --work-root | -wr | 路径 | `build_pyd` | 指定PyInstaller打包工作目录              |
| --overwrite / --no-overwrite | 无 | 布尔 | True | 等价 PyInstaller `-y`，自动覆盖旧打包产物    |
| --clean / --no-clean | 无 | 布尔 | True | 等价 PyInstaller `--clean`，打包前清空缓存 |

- 兼容 pyinstaller 的其他命令,如-F -w

#### 使用示例
```bash
# 1. 基础打包，单文件无控制台窗口
topyd installer -m main.py -F -w

# 2. 自定义工作目录、关闭自动覆盖、禁用UPX压缩
topyd installer -m src/main.py -wr temp_build --no-overwrite --noupx

# 3. 保留控制台、自定义dist输出路径
topyd installer -m app.py -F --noconsole --distpath ./output
```

## 底层函数直接脚本调用（不使用CLI）
无需 Click 命令行，直接在 `.py` 脚本导入执行，适合自动化流水线。
### 4.1 to_pyd 编译函数调用
文件：`toPYD.py`
```python
from toPYD import to_pyd

if __name__ == "__main__":
    # 全局编译全部源码，生成hidden_import.py
    to_pyd(
        files=None,
        exclude=["tests/", "demo/"],
        exclude_file=True,
        source_root="./",
        pyd_output_dir="build_pyd",
        c_files_dir="build/c_files",
        write_hidden_import=True,
        alone=False
    )
```

### 4.2 build_exe 打包函数调用
文件：`installer.py`
```python
from toPYD import build_exe

if __name__ == "__main__":
    # 透传-F -w参数，打包入口main.py
    extra_pyi_args = ["-F", "-w"]
    build_exe(
        extra_args=extra_pyi_args,
        main_file="main.py",
        pyinstaller_work_root="build_pyd",
        overwrite=True,
        clean=True
    )
```

## 五、底层函数入参对照表
### 5.1 to_pyd() 参数映射
| CLI 参数 | 函数入参名 |
|----------|------------|
| -f --files | files |
| -a --all | 函数内判断开关 |
| -e --exclude | exclude |
| -ef --exclude-file | exclude_file |
| -s --source-root | source_root |
| -o --output-dir | pyd_output_dir |
| -c --c-files-dir | c_files_dir |
| --hidden-import | write_hidden_import |
| --alone | alone |

### 5.2 build_exe() 参数映射
| CLI 参数 | 函数入参名 |
|----------|------------|
| 分隔后透传参数 | extra_args |
| -m --main-file | main_file |
| -wr --work-root | pyinstaller_work_root |
| --overwrite | overwrite |
| --clean | clean |

## 六、核心特性说明
1. **目录自动复刻**
`installer` 会自动解析 `main-file` 路径：绝对路径自动转为工作目录相对路径，完整复制父级文件夹结构到 `work-root`，解决模块导入找不到路径问题。
2. **自动隐藏导入支持**
`setup -a` 全局编译生成 `hidden_import.py`，`build_exe` 自动解析文件内所有 `from xxx import`，批量生成 `--hidden-import` 参数，适配 pyd 二进制缺失依赖场景。
3. **全量 PyInstaller 参数兼容**
通过 `ctx.args` 获取分隔符后全部原始参数，无参数数量限制，支持 UPX、图标、附加二进制/资源文件等全部原生能力。
4. **双运行模式**
既可作为全局 CLI 工具快速使用，也可单独调用底层函数嵌入 CI/自动化打包脚本。

## 七、常见报错与解决方案
1. `必须提供 -f 或 -a 其中一个`
执行 `setup` 未传入 `-f` / `-a`，二选一传入即可。
2. `-f 和 -a 不能同时使用`
编译不能同时指定单文件+全局扫描，删除其中一个参数。
3. `Error: No such option: -F`
透传 PyInstaller 参数忘记添加 `--` 分隔符，正确格式：`topyd installer -m main.py -- -F -w`。
4. 打包运行提示模块缺失
重新执行 `setup -a` 生成完整 `hidden_import.py`，再执行打包命令。

## hidden_import.py 作用

该文件收集了所有被编译文件中的 import 语句，用于解决 PyInstaller 等打包工具无法检测 pyd 文件中隐式导入的问题。



## 注意事项

1. 编译过程中会自动去除平台相关标识，如将 `module.cp310-win_amd64.pyd` 重命名为 `module.pyd`
2. 支持 `.py` 和 `.pyx` 文件编译
3. 排除规则支持 Git 风格的通配符匹配
4. 编译生成的中间文件存储在指定的 `c_files_dir` 目录中
5. 如果遇到编译问题，可以检查源文件中是否包含不支持的语法或依赖

## 常见问题

### 遇到 Cython 错误
如果遇到 `Cython.xxxx.Errors.xxxxx: xxx.py` 报错，是Cython错误，一般来说是文件中文名称或者不符合python命名规范的文件名造成。

解决：1.单独编译这个文件 2.重命名文件后在编译


