{
  "canonical_name": "simonw/go-to-wheel",
  "compilation_id": "pack_02f465ddf577456ca86fc91258015eed",
  "created_at": "2026-05-15T06:34:02.231230+00:00",
  "created_by": "project-pack-compiler",
  "feedback": {
    "carrier_selection_notes": [
      "viable_asset_types=skill, recipe, host_instruction, eval, preflight",
      "recommended_asset_types=skill, recipe, host_instruction, eval, preflight"
    ],
    "evidence_delta": {
      "confirmed_claims": [
        "identity_anchor_present",
        "capability_and_host_targets_present",
        "install_path_declared_or_better"
      ],
      "missing_required_fields": [],
      "must_verify_forwarded": [
        "Run or inspect `pip install go-to-wheel` in an isolated environment.",
        "Confirm the project exposes the claimed capability to at least one target host."
      ],
      "quickstart_execution_scope": "allowlisted_sandbox_smoke",
      "sandbox_command": "pip install go-to-wheel",
      "sandbox_container_image": "python:3.12-slim",
      "sandbox_execution_backend": "docker",
      "sandbox_planner_decision": "llm_execute_isolated_install",
      "sandbox_validation_id": "sbx_f4f172b2f33f47ac906ae987bd2e2a0e"
    },
    "feedback_event_type": "project_pack_compilation_feedback",
    "learning_candidate_reasons": [],
    "template_gaps": []
  },
  "identity": {
    "canonical_id": "project_04c7c99d230620fedb9909997c475aa9",
    "canonical_name": "simonw/go-to-wheel",
    "homepage_url": null,
    "license": "unknown",
    "repo_url": "https://github.com/simonw/go-to-wheel",
    "slug": "go-to-wheel",
    "source_packet_id": "phit_0077971de1814c1c8661ac9e17450fbb",
    "source_validation_id": "dval_b7241181c1994477a8167e0e79e3c2a9"
  },
  "merchandising": {
    "best_for": "需要软件开发与交付能力，并使用 local_cli的用户",
    "github_forks": null,
    "github_stars": null,
    "one_liner_en": "[![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/)",
    "one_liner_zh": "[![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/)",
    "primary_category": {
      "category_id": "software-development",
      "confidence": "medium",
      "name_en": "Software Development",
      "name_zh": "软件开发与交付",
      "reason": "matched_keywords:git, cli"
    },
    "target_user": "使用 local_cli 等宿主 AI 的用户",
    "title_en": "go-to-wheel",
    "title_zh": "go-to-wheel 能力包",
    "visible_tags": [
      {
        "label_en": "AI Agent Framework",
        "label_zh": "AI Agent 框架",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "product_domain-ai-agent-framework",
        "type": "product_domain"
      },
      {
        "label_en": "Open Source Capability Building",
        "label_zh": "开源能力构建",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "user_job-open-source-capability-building",
        "type": "user_job"
      },
      {
        "label_en": "Workflow Automation",
        "label_zh": "流程自动化",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "core_capability-workflow-automation",
        "type": "core_capability"
      },
      {
        "label_en": "Automated Workflow",
        "label_zh": "自动化工作流",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "workflow_pattern-automated-workflow",
        "type": "workflow_pattern"
      },
      {
        "label_en": "Local-first",
        "label_zh": "本地优先",
        "source": "repo_evidence_project_characteristics",
        "tag_id": "selection_signal-local-first",
        "type": "selection_signal"
      }
    ]
  },
  "packet_id": "phit_0077971de1814c1c8661ac9e17450fbb",
  "page_model": {
    "artifacts": {
      "artifact_slug": "go-to-wheel",
      "files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json",
        "REPO_INSPECTION.md",
        "CAPABILITY_CONTRACT.json",
        "EVIDENCE_INDEX.json",
        "CLAIM_GRAPH.json"
      ],
      "required_files": [
        "PROJECT_PACK.json",
        "QUICK_START.md",
        "PROMPT_PREVIEW.md",
        "HUMAN_MANUAL.md",
        "AI_CONTEXT_PACK.md",
        "BOUNDARY_RISK_CARD.md",
        "PITFALL_LOG.md",
        "REPO_INSPECTION.json"
      ]
    },
    "detail": {
      "capability_source": "Project Hit Packet + DownstreamValidationResult",
      "commands": [
        {
          "command": "pip install go-to-wheel",
          "label": "Python / pip · 官方安装入口",
          "source": "https://github.com/simonw/go-to-wheel#readme",
          "verified": true
        }
      ],
      "display_tags": [
        "AI Agent 框架",
        "开源能力构建",
        "流程自动化",
        "自动化工作流",
        "本地优先"
      ],
      "eyebrow": "软件开发与交付",
      "glance": [
        {
          "body": "判断自己是不是目标用户。",
          "label": "最适合谁",
          "value": "需要软件开发与交付能力，并使用 local_cli的用户"
        },
        {
          "body": "先理解能力边界，再决定是否继续。",
          "label": "核心价值",
          "value": "[![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/)"
        },
        {
          "body": "未完成验证前保持审慎。",
          "label": "继续前",
          "value": "publish to Doramagic.ai project surfaces"
        }
      ],
      "guardrail_source": "Boundary & Risk Card",
      "guardrails": [
        {
          "body": "Prompt Preview 只展示流程，不证明项目已安装或运行。",
          "label": "Check 1",
          "value": "不要把试用当真实运行"
        },
        {
          "body": "local_cli",
          "label": "Check 2",
          "value": "确认宿主兼容"
        },
        {
          "body": "publish to Doramagic.ai project surfaces",
          "label": "Check 3",
          "value": "先隔离验证"
        }
      ],
      "mode": "skill, recipe, host_instruction, eval, preflight",
      "pitfall_log": {
        "items": [
          {
            "body": "README/documentation is current enough for a first validation pass.",
            "category": "能力坑",
            "evidence": [
              "capability.assumptions | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | README/documentation is current enough for a first validation pass."
            ],
            "severity": "medium",
            "suggested_check": "将假设转成下游验证清单。",
            "title": "能力判断依赖假设",
            "user_impact": "假设不成立时，用户拿不到承诺的能力。"
          },
          {
            "body": "未记录 last_activity_observed。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | last_activity_observed missing"
            ],
            "severity": "medium",
            "suggested_check": "补 GitHub 最近 commit、release、issue/PR 响应信号。",
            "title": "维护活跃度未知",
            "user_impact": "新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "downstream_validation.risk_items | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "进入安全/权限治理复核队列。",
            "title": "下游验证发现风险项",
            "user_impact": "下游已经要求复核，不能在页面中弱化。"
          },
          {
            "body": "no_demo",
            "category": "安全/权限坑",
            "evidence": [
              "risks.scoring_risks | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium"
            ],
            "severity": "medium",
            "suggested_check": "把风险写入边界卡，并确认是否需要人工复核。",
            "title": "存在评分风险",
            "user_impact": "风险会影响是否适合普通用户安装。"
          },
          {
            "body": "issue_or_pr_quality=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | issue_or_pr_quality=unknown"
            ],
            "severity": "low",
            "suggested_check": "抽样最近 issue/PR，判断是否长期无人处理。",
            "title": "issue/PR 响应质量未知",
            "user_impact": "用户无法判断遇到问题后是否有人维护。"
          },
          {
            "body": "release_recency=unknown。",
            "category": "维护坑",
            "evidence": [
              "evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | release_recency=unknown"
            ],
            "severity": "low",
            "suggested_check": "确认最近 release/tag 和 README 安装命令是否一致。",
            "title": "发布节奏不明确",
            "user_impact": "安装命令和文档可能落后于代码，用户踩坑概率升高。"
          }
        ],
        "source": "ProjectPitfallLog + ProjectHitPacket + validation + community signals",
        "summary": "发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。",
        "title": "踩坑日志"
      },
      "snapshot": {
        "contributors": null,
        "forks": null,
        "license": "unknown",
        "note": "站点快照，非实时质量证明；用于开工前背景判断。",
        "stars": null
      },
      "source_url": "https://github.com/simonw/go-to-wheel",
      "steps": [
        {
          "body": "不安装项目，先体验能力节奏。",
          "code": "preview",
          "title": "先试 Prompt"
        },
        {
          "body": "理解输入、输出、失败模式和边界。",
          "code": "manual",
          "title": "读说明书"
        },
        {
          "body": "把上下文交给宿主 AI 继续工作。",
          "code": "context",
          "title": "带给 AI"
        },
        {
          "body": "进入主力环境前先完成安装入口与风险边界验证。",
          "code": "verify",
          "title": "沙箱验证"
        }
      ],
      "subtitle": "[![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/)",
      "title": "go-to-wheel 能力包",
      "trial_prompt": "# go-to-wheel - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 go-to-wheel 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: [![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/) 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-1：项目简介。围绕“项目简介”模拟一次用户任务，不展示安装或运行结果。\n2. page-2：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n3. page-3：支持的平台。围绕“支持的平台”模拟一次用户任务，不展示安装或运行结果。\n4. page-5：Go 交叉编译流程。围绕“Go 交叉编译流程”模拟一次用户任务，不展示安装或运行结果。\n5. page-6：Wheel 生成机制。围绕“Wheel 生成机制”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-1\n输入：用户提供的“项目简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-2\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-3\n输入：用户提供的“支持的平台”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-5\n输入：用户提供的“Go 交叉编译流程”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-6\n输入：用户提供的“Wheel 生成机制”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-1：Step 1 必须围绕“项目简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-2：Step 2 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-3：Step 3 必须围绕“支持的平台”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-5：Step 4 必须围绕“Go 交叉编译流程”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-6：Step 5 必须围绕“Wheel 生成机制”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://news.ycombinator.com/item?id=48109677\n- https://github.com/simonw/go-to-wheel#readme\n- README.md\n- spec.md\n- go_to_wheel/__init__.py\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 go-to-wheel 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "voices": [
        {
          "body": "当前没有项目级社区来源；不会把未抓取讨论包装成社会证明。",
          "items": [],
          "status": "待发现 Agent 补证",
          "title": "社区讨论"
        }
      ]
    },
    "homepage_card": {
      "category": "软件开发与交付",
      "desc": "[![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/)",
      "effort": "安装已验证",
      "forks": null,
      "icon": "code",
      "name": "go-to-wheel 能力包",
      "risk": "需复核",
      "slug": "go-to-wheel",
      "stars": null,
      "tags": [
        "AI Agent 框架",
        "开源能力构建",
        "流程自动化",
        "自动化工作流",
        "本地优先"
      ],
      "thumb": "gray",
      "type": "Skill Pack"
    },
    "manual": {
      "markdown": "# https://github.com/simonw/go-to-wheel 项目说明书\n\n生成时间：2026-05-14 22:44:46 UTC\n\n## 目录\n\n- [项目简介](#page-1)\n- [系统架构](#page-2)\n- [支持的平台](#page-3)\n- [元数据配置](#page-4)\n- [Go 交叉编译流程](#page-5)\n- [Wheel 生成机制](#page-6)\n- [快速开始](#page-7)\n- [高级用法与示例](#page-8)\n- [开发环境搭建](#page-9)\n- [相关项目与参考](#page-10)\n\n<a id='page-1'></a>\n\n## 项目简介\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 项目简介\n\n## 项目概述\n\n`go-to-wheel` 是一个将 Go 语言命令行程序编译为 Python wheel 包的工具。该工具填补了 Go/Python 生态系统中的一个空白——在 Rust 生态中有 `maturin --bindings bin` 这样的工具，但 Go 生态此前缺乏类似的便捷方案。\n\n项目的主要目标是将 Go 模块目录作为输入，跨平台编译生成多个架构的可执行文件，并将每个编译结果打包成带有正确平台标签的 Python wheel 包，从而可以通过 `pip` 或 `pipx` 进行安装，使 Go 二进制程序直接出现在系统 PATH 中。\n\n资料来源：[README.md:1-10]()\n\n## 核心功能特性\n\n### 多平台交叉编译\n\n`go-to-wheel` 支持一次性为多个目标平台构建 Go 二进制文件，默认涵盖以下平台：\n\n| 平台标识 | GOOS | GOARCH | Wheel 平台标签 |\n|---------|------|--------|---------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:26-33]()\n\n### 静态二进制编译\n\n项目使用 `CGO_ENABLED=0` 环境变量确保生成的 Go 二进制文件为静态链接形式，这避免了不同系统 libc 版本之间的兼容性问题。\n\n编译时默认使用 `-ldflags=\"-s -w\"` 链接标志，用于剥离调试信息以减小二进制文件体积。\n\n资料来源：[spec.md:80-90]()\n\n### Python 包装器机制\n\n生成的 wheel 包不直接将二进制文件放入 `.data/scripts/` 目录，而是采用 Python 包装器模式。`__init__.py` 文件提供了 `main()` 函数，通过 `console_scripts` 入口点调用该函数。\n\n这种设计有以下优势：\n\n- **跨平台一致性**：在所有平台上行为一致\n- **更好的错误提示**：当二进制文件缺失或不兼容时能提供友好的错误信息\n- **未来扩展性**：可以添加 Python 端的特性，如版本检查、更新通知等\n- **pipx 兼容性**：与 `pipx install` 无缝配合工作\n\n资料来源：[spec.md:60-75]()\n\n## 工作流程\n\n`go-to-wheel` 的完整工作流程如下：\n\n```mermaid\ngraph TD\n    A[输入 Go 模块目录] --> B[验证输入]\n    B --> C{go.mod 存在?}\n    C -->|是| D[跨平台编译 Go 二进制]\n    C -->|否| E[抛出错误: 非 Go 模块]\n    D --> F[为每个平台创建 wheel]\n    F --> G[生成 METADATA]\n    G --> H[生成 WHEEL]\n    H --> I[生成 entry_points.txt]\n    I --> J[生成 RECORD]\n    J --> K[打包为 .whl 文件]\n    K --> L[输出到目标目录]\n```\n\n### 详细构建步骤\n\n**步骤一：输入验证**\n\n1. 验证 Go 目录存在\n2. 验证目录包含 `go.mod` 文件（确认为 Go 模块）\n3. 验证 Go 已安装且可访问\n4. 从目录名或 `--name` 选项解析包名\n\n资料来源：[spec.md:95-105]()\n\n**步骤二：跨平台编译**\n\n对于每个目标平台，执行以下编译命令：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md:110-120]()\n\n**步骤三：构建 Wheel 包**\n\n对于每个编译好的二进制文件：\n\n1. 创建临时目录结构\n2. 将二进制文件复制到 `{package_name}/bin/` 目录\n3. 生成 `__init__.py` 和 `__main__.py`\n4. 生成 `METADATA`、`WHEEL` 和 `entry_points.txt`\n5. 计算 `RECORD` 中的 SHA256 哈希值\n6. 打包为带有正确文件名的 wheel 文件\n\n资料来源：[spec.md:122-135]()\n\n**步骤四：输出**\n\n1. 将 wheel 文件移动到输出目录\n2. 打印已构建 wheel 的摘要信息\n3. 返回成功/失败状态\n\n资料来源：[spec.md:137-142]()\n\n## Wheel 包结构\n\n生成的 wheel 包遵循 PEP 427 格式，目录结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md:35-55]()\n\n### METADATA 文件格式\n\n```\nMetadata-Version: 2.1\nName: {package_name}\nVersion: {version}\nSummary: {description}\nLicense: {license}\nAuthor: {author}\nAuthor-email: {author_email}\nHome-page: {url}\nRequires-Python: {requires_python}\n```\n\n资料来源：[spec.md:145-158]()\n\n### WHEEL 文件格式\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel {go_to_wheel_version}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n```\n\n资料来源：[spec.md:160-167]()\n\n## 命令行接口\n\n### 基本用法\n\n```bash\ngo-to-wheel path/to/go-folder\n```\n\n### 命令行选项\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--name NAME` | Python 包名称 | 目录 basename |\n| `--version VERSION` | 包版本号 | 0.1.0 |\n| `--output-dir DIR` | wheel 输出目录 | ./dist |\n| `--entry-point NAME` | CLI 命令名称 | 与包名称相同 |\n| `--platforms PLATFORMS` | 目标平台列表（逗号分隔） | 所有支持的平台 |\n| `--go-binary PATH` | Go 二进制文件路径 | go |\n| `--description TEXT` | 包描述 | \"Go binary packaged as Python wheel\" |\n| `--requires-python VERSION` | Python 版本要求 | >=3.10 |\n| `--license LICENSE` | 许可证标识符 | None |\n| `--author AUTHOR` | 作者姓名 | None |\n| `--author-email EMAIL` | 作者邮箱 | None |\n| `--url URL` | 项目主页 | None |\n| `--readme PATH` | README markdown 文件路径 | None |\n| `--ldflags FLAGS` | 额外的 Go 链接器标志 | None |\n| `--set-version-var VAR` | 通过 -X 设置版本的 Go 变量 | None |\n\n资料来源：[README.md:50-75]()\n\n### 使用示例\n\n**基础用法：**\n\n```bash\ngo-to-wheel ./mytool\n```\n\n**指定包名称：**\n\n```bash\ngo-to-wheel ./mytool --name my-python-tool\n```\n\n**仅构建特定平台：**\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n**嵌入版本信息到 Go 二进制：**\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n这会将 `-X main.version=2.0.0` 传递给 Go 链接器，使编译后的二进制文件能获知自身版本号，而无需在 Go 源代码中硬编码。\n\n资料来源：[README.md:76-95]()\n\n**完整 PyPI 元数据：**\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\"\n```\n\n## 依赖要求\n\n`go-to-wheel` 工具本身仅需以下依赖：\n\n| 依赖 | 版本要求 | 说明 |\n|------|---------|------|\n| Python | >= 3.10 | 工具运行时环境 |\n| Go | >= 1.16 | 用于 `go mod` 支持的构建环境 |\n\n项目使用 Python 标准库实现，不依赖任何外部 Python 包。\n\n资料来源：[spec.md:215-225]()\n\n## 安装方式\n\n```bash\npip install go-to-wheel\n# 或\npipx install go-to-wheel\n```\n\n安装后需要确保 Go 已安装且位于系统 PATH 中。\n\n资料来源：[README.md:28-35]()\n\n## 输出示例\n\n```\n$ go-to-wheel ./myapp --name myapp-bin\ngo-to-wheel v0.1.0\nBuilding from ./myapp\n\nBuilding for linux-amd64... done\nBuilding for linux-arm64... done\nBuilding for linux-amd64-musl... done\nBuilding for linux-arm64-musl... done\nBuilding for darwin-amd64... done\nBuilding for darwin-arm64... done\nBuilding for windows-amd64... done\nBuilding for windows-arm64... done\n\nBuilt 8 wheel(s):\n  ./dist/myapp-bin-0.1.0-py3-none-manylinux_2_17_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-manylinux_2_17_aarch64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-musllinux_1_2_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-musllinux_1_2_aarch64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-macosx_10_9_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-macosx_11_0_arm64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-win_amd64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-win_arm64.whl\n```\n\n## 相关项目\n\n`go-to-wheel` 的设计灵感来源于 Rust 生态中的类似工具：\n\n- **[maturin](https://github.com/PyO3/maturin)** - Rust 等效工具，为 `go-to-wheel` 提供了设计参考\n- **[pip-binary-factory](https://github.com/Bing-su/pip-binary-factory)** - 预编译二进制打包模板\n\n资料来源：[README.md:130-135]()\n\n## 包名称验证规则\n\n项目对包名称有以下验证要求：\n\n| 验证项 | 处理方式 |\n|--------|---------|\n| 大小写问题 | 自动转换为小写 |\n| 首字符非字母/数字 | 报错退出 |\n| PEP 503 违规 | 报错退出，说明命名规则 |\n\n包名称必须符合 PEP 503 规范：\n\n- 仅使用小写字母、数字、连字符、下划线和句点\n- 必须以字母或数字开头\n\n导入名称（用于 Python 包目录）遵循 PEP 8 规范，将连字符替换为下划线。\n\n资料来源：[spec.md:195-210]()\n\n---\n\n<a id='page-2'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [Go 交叉编译流程](#page-5), [Wheel 生成机制](#page-6)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 系统架构\n\ngo-to-wheel 是一个将 Go CLI 程序编译为 Python wheel 包的工具。其核心设计围绕三个主要阶段：命令行解析与验证、跨平台编译、以及 wheel 包生成。资料来源：[go_to_wheel/__init__.py:1-50]()\n\n## 整体架构概述\n\ngo-to-wheel 采用模块化设计，核心逻辑集中于单一 Python 文件中，无需外部依赖即可完成全部功能。工具通过以下流程将 Go 模块转换为可分发的 Python wheel：\n\n```mermaid\ngraph TD\n    A[Go 模块目录] --> B[输入验证]\n    B --> C{遍历目标平台}\n    C -->|每个平台| D[跨平台编译 Go 二进制]\n    D --> E[创建 wheel 目录结构]\n    E --> F[生成 Python 包装器]\n    F --> G[生成 wheel 元数据]\n    G --> H[打包为 .whl 文件]\n    H --> I[输出到目标目录]\n    C -->|所有平台完成| I\n```\n\n资料来源：[README.md]()\n\n## 核心组件\n\n### 平台映射系统\n\n平台映射系统定义了 Go 目标平台与 Python wheel 平台标签之间的对应关系。该映射存储在 `PLATFORM_MAPPINGS` 字典中，支持 8 种目标平台配置。\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | linux | amd64 | manylinux_2_17_x86_64 |\n| `linux-arm64` | linux | arm64 | manylinux_2_17_aarch64 |\n| `linux-amd64-musl` | linux | amd64 | musllinux_1_2_x86_64 |\n| `linux-arm64-musl` | linux | arm64 | musllinux_1_2_aarch64 |\n| `darwin-amd64` | darwin | amd64 | macosx_10_9_x86_64 |\n| `darwin-arm64` | darwin | arm64 | macosx_11_0_arm64 |\n| `windows-amd64` | windows | amd64 | win_amd64 |\n| `windows-arm64` | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:20-27]()\n\n### 默认平台列表\n\n`DEFAULT_PLATFORMS` 列表定义了工具的默认构建目标，包含所有 8 种平台配置：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:29-36]()\n\n## 构建流程详解\n\n### 阶段一：输入验证与准备\n\n`build_wheels()` 函数是核心构建入口，负责执行以下验证步骤：\n\n1. **路径验证**：确认 Go 模块目录存在\n2. **模块验证**：检查 `go.mod` 文件是否存在于目录中\n3. **README 处理**：如果指定了 README 文件，则读取其内容作为 PyPI 长描述\n4. **默认值设置**：当未指定包名时，使用目录名作为包名\n\n```python\ngo_path = Path(go_dir).resolve()\n\nif not go_path.exists():\n    raise FileNotFoundError(f\"Go directory not found: {go_dir}\")\n\nif not (go_path / \"go.mod\").exists():\n    raise ValueError(f\"Not a Go module: {go_dir} (no go.mod file found)\")\n```\n\n资料来源：[go_to_wheel/__init__.py:112-120]()\n\n### 阶段二：跨平台编译\n\n对于每个目标平台，工具通过设置环境变量执行 Go 交叉编译：\n\n```mermaid\ngraph LR\n    A[设置 GOOS] --> B[设置 GOARCH]\n    B --> C[CGO_ENABLED=0]\n    C --> D[go build -ldflags]\n    D --> E[输出二进制文件]\n```\n\n编译参数配置：\n- `CGO_ENABLED=0`：禁用 C 互操作，确保生成静态二进制文件\n- `-ldflags=\"-s -w\"`：剥离调试信息以减小二进制体积\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md]()\n\n### 阶段三：Wheel 包结构生成\n\n生成符合 PEP 427 和 PEP 376 标准的 wheel 包结构：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md]()\n\n### 阶段四：元数据生成\n\n工具包含四个核心元数据生成函数：\n\n| 函数名 | 用途 | 输出文件 |\n|-------|------|---------|\n| `generate_metadata()` | 生成 PyPI 元数据 | METADATA |\n| `generate_wheel_metadata()` | 生成 wheel 规范 | WHEEL |\n| `generate_entry_points()` | 定义控制台入口点 | entry_points.txt |\n| `generate_record()` | 记录文件校验和 | RECORD |\n\n资料来源：[go_to_wheel/__init__.py:85-115]()\n\n### 阶段五：打包与输出\n\n使用 Python 标准库 `zipfile` 模块将目录结构打包为 `.whl` 文件：\n\n```python\nwith zipfile.ZipFile(wheel_path, \"w\", zipfile.ZIP_DEFLATED) as whl:\n    for file_path, content in files.items():\n        if \"/bin/\" in file_path:\n            info = zipfile.ZipInfo(file_path)\n            info.external_attr = (stat.S_IRWXU | stat.S_IRGRP | \n                                  stat.S_IXGRP | stat.S_IROTH | \n                                  stat.S_IXOTH) << 16\n            whl.writestr(info, content)\n        else:\n            whl.writestr(file_path, content)\n```\n\n对于二进制文件，设置可执行权限（Unix 模式 0755）；其他文件使用默认权限。\n\n资料来源：[go_to_wheel/__init__.py:175-185]()\n\n## Python 包装器机制\n\n### `__init__.py` 包装逻辑\n\n生成的 `__init__.py` 文件包含两个关键函数：\n\n```python\ndef get_binary_path():\n    \"\"\"Return the path to the bundled binary.\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # On Windows, use subprocess to properly handle signals\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # On Unix, exec replaces the process\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n- Windows 平台使用 `subprocess.call()` 处理信号\n- Unix 平台使用 `os.execvp()` 替换进程，实现零开销调用\n\n资料来源：[spec.md]()\n\n### 入口点机制\n\n通过 `entry_points.txt` 定义控制台脚本入口：\n\n```\n[console_scripts]\n{entry_point} = {package_name}:main\n```\n\n这种设计确保：\n- 跨平台一致性行为\n- pipx 兼容性\n- 可扩展性（未来可添加版本检查等 Python 端功能）\n\n资料来源：[spec.md]()\n\n## 命令行接口设计\n\n```mermaid\ngraph TD\n    A[go-to-wheel CLI] --> B[argparse 解析器]\n    B --> C[验证 Go 模块]\n    C --> D[调用 build_wheels]\n    D --> E{遍历平台}\n    E -->|每个平台| F[编译 Go 二进制]\n    F --> G[生成 wheel]\n    E -->|完成| H[输出结果摘要]\n```\n\n### 支持的命令行选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|-----|------|--------|------|\n| `--name` | 字符串 | 目录名 | Python 包名称 |\n| `--version` | 字符串 | 0.1.0 | 包版本号 |\n| `--output-dir` | 字符串 | ./dist | 输出目录 |\n| `--entry-point` | 字符串 | 同包名 | CLI 命令名称 |\n| `--platforms` | 列表 | 全部平台 | 目标平台列表 |\n| `--go-binary` | 字符串 | go | Go 二进制路径 |\n| `--description` | 字符串 | 见源码 | 包描述 |\n| `--requires-python` | 字符串 | >=3.10 | Python 版本要求 |\n| `--ldflags` | 字符串 | None | 额外链接器标志 |\n| `--set-version-var` | 字符串 | None | Go 版本变量 |\n\n资料来源：[go_to_wheel/__init__.py:50-130]()\n\n## 依赖关系\n\n```mermaid\ngraph TD\n    A[go-to-wheel] --> B[Python 标准库]\n    B --> C[argparse]\n    B --> D[zipfile]\n    B --> E[csv]\n    B --> F[hashlib]\n    B --> G[subprocess]\n    B --> H[pathlib]\n```\n\n工具本身不依赖任何外部 Python 包，仅使用标准库完成全部功能。\n\n| 依赖模块 | 用途 |\n|---------|------|\n| argparse | 命令行参数解析 |\n| zipfile | 创建 wheel 压缩包 |\n| csv | 生成 RECORD 文件 |\n| hashlib | 计算文件 SHA256 校验和 |\n| subprocess | 执行 Go 编译命令 |\n| pathlib | 路径操作 |\n\n资料来源：[go_to_wheel/__init__.py:1-20]()\n\n## 设计决策\n\n### 纯 Python 包装器 vs .data/scripts\n\n工具选择使用 Python 包装器（`console_scripts` 入口点）而非直接将二进制文件放入 `.data/scripts/`，原因如下：\n\n1. **一致性**：跨平台行为统一\n2. **错误处理**：可提供友好的错误提示\n3. **可扩展性**：便于添加 Python 端功能\n4. **pipx 兼容**：与 pipx 无缝集成\n\n### CGO_ENABLED=0\n\n禁用 CGO 是确保跨平台兼容性的关键决策，避免 libc 版本差异带来的兼容性问题。\n\n### 静态链接\n\n通过设置 `CGO_ENABLED=0`，Go 编译器生成静态二进制文件，减少运行时依赖。\n\n## 技术规格总结\n\n| 规格项 | 值 |\n|-------|-----|\n| Python 版本要求 | >=3.10 |\n| Go 版本要求 | >=1.16 |\n| 默认平台数 | 8 |\n| 外部依赖数 | 0 |\n| wheel 格式标准 | PEP 427, PEP 376 |\n| 元数据格式 | PEP 566 |\n\n资料来源：[spec.md](), [README.md]()\n\n---\n\n<a id='page-3'></a>\n\n## 支持的平台\n\n### 相关页面\n\n相关主题：[Go 交叉编译流程](#page-5), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 支持的平台\n\n## 概述\n\n`go-to-wheel` 工具支持将 Go CLI 程序交叉编译为多个目标平台的 Python wheel 安装包。该工具内置了完整的平台支持矩阵，通过 `PLATFORM_MAPPINGS` 和 `DEFAULT_PLATFORMS` 两个核心数据结构来管理不同操作系统和架构的编译目标。\n\n## 平台映射机制\n\n### 核心数据结构\n\n`go-to-wheel` 使用 `PLATFORM_MAPPINGS` 字典建立平台标识符与实际编译参数的一对一映射关系：\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | linux | amd64 | manylinux_2_17_x86_64 |\n| `linux-arm64` | linux | arm64 | manylinux_2_17_aarch64 |\n| `linux-amd64-musl` | linux | amd64 | musllinux_1_2_x86_64 |\n| `linux-arm64-musl` | linux | arm64 | musllinux_1_2_aarch64 |\n| `darwin-amd64` | darwin | amd64 | macosx_10_9_x86_64 |\n| `darwin-arm64` | darwin | arm64 | macosx_11_0_arm64 |\n| `windows-amd64` | windows | amd64 | win_amd64 |\n| `windows-arm64` | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:24-32]()\n\n### 默认构建平台\n\n默认情况下，`go-to-wheel` 会为以下 8 个平台构建 wheel：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:36-45]()\n\n## 平台分类说明\n\n### Linux 平台 (glibc)\n\n基于 glibc 的 Linux 发行版（如 Ubuntu、Debian、Fedora、CentOS 等）使用标准的 manylinux 标签：\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `linux-amd64` | x86_64 | 主流 64 位 Linux |\n| `linux-arm64` | aarch64 | ARM 64 位 Linux (AWS Graviton, Apple Silicon Mac Linux 环境等) |\n\n### Linux 平台 (musl)\n\n基于 musl libc 的轻量级 Linux 发行版（如 Alpine Linux）使用 musllinux 标签：\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `linux-amd64-musl` | x86_64 | Alpine 等 musl 发行版 |\n| `linux-arm64-musl` | aarch64 | ARM 架构 Alpine 等 |\n\n### macOS 平台\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `darwin-amd64` | x86_64 | Intel Mac |\n| `darwin-arm64` | arm64 | Apple Silicon Mac (M1/M2/M3 等) |\n\n### Windows 平台\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `windows-amd64` | amd64 | 64 位 Windows |\n| `windows-arm64` | arm64 | Windows on ARM |\n\n## 编译流程\n\n平台支持的实现涉及以下编译步骤：\n\n```mermaid\ngraph TD\n    A[指定平台列表] --> B{遍历每个平台}\n    B --> C[获取 GOOS/GOARCH]\n    C --> D[CGO_ENABLED=0 交叉编译]\n    D --> E[生成 wheel 元数据]\n    E --> F[打包为 .whl 文件]\n    F --> G[移动到输出目录]\n    G --> H{还有更多平台?}\n    H -->|是| B\n    H -->|否| I[完成]\n```\n\n交叉编译命令使用环境变量控制目标平台：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 自定义平台选择\n\n### 指定特定平台\n\n用户可以通过 `--platforms` 参数选择构建特定平台：\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n### 平台参数解析\n\n平台解析逻辑将逗号分隔的字符串转换为列表：\n\n```python\nplatforms = None\nif args.platforms:\n    platforms = [p.strip() for p in args.platforms.split(\",\")]\n```\n\n资料来源：[go_to_wheel/__init__.py:75-78]()\n\n## Wheel 文件命名规范\n\n生成的 wheel 文件遵循 PEP 427 规范，命名格式为：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n```\n\n例如：\n\n| 平台标识符 | 生成的 wheel 文件名 |\n|-----------|-------------------|\n| linux-amd64 | `mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl` |\n| linux-arm64 | `mytool-1.0.0-py3-none-manylinux_2_17_aarch64.whl` |\n| darwin-arm64 | `mytool-1.0.0-py3-none-macosx_11_0_arm64.whl` |\n| windows-amd64 | `mytool-1.0.0-py3-none-win_amd64.whl` |\n\n## 静态编译保证\n\n所有平台的编译都使用 `CGO_ENABLED=0` 标志，确保生成静态链接的二进制文件。这一设计决策确保了：\n\n- 避免 libc 版本兼容性问题\n- 二进制文件具有完全的便携性\n- 不依赖目标系统的动态库\n\n## 安装兼容性\n\n### pipx 安装\n\n生成的 wheel 可通过 pipx 安装，直接将 Go 二进制程序添加到用户 PATH：\n\n```bash\npipx install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n### pip 直接安装\n\n同样支持标准 pip 安装：\n\n```bash\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n## 依赖要求\n\n| 组件 | 版本要求 |\n|------|---------|\n| Go | >= 1.16 |\n| Python | >= 3.10 |\n\n## 总结\n\n`go-to-wheel` 的平台支持系统通过清晰的数据结构定义和自动化的交叉编译流程，为 Go CLI 程序提供了广泛的 Python wheel 分发能力。目前支持 8 个主流平台，覆盖了 Linux (glibc/musl)、macOS 和 Windows 的主要架构变体。\n\n---\n\n<a id='page-4'></a>\n\n## 元数据配置\n\n### 相关页面\n\n相关主题：[Wheel 生成机制](#page-6), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n</details>\n\n# 元数据配置\n\n## 概述\n\n元数据配置是 go-to-wheel 项目的核心功能模块，负责为生成的 Python wheel 包生成符合 PEP 规范的标准元数据文件。该模块处理从命令行参数到 wheel 包元数据字段的完整映射与转换过程。\n\ngo-to-wheel 将编译好的 Go 二进制文件打包为 Python wheel 包时，需要生成符合 Python 打包生态系统标准的元数据文件，包括 METADATA、WHEEL、entry_points.txt 和 RECORD。这些文件共同定义了包的名称、版本、依赖、入口点等关键信息。\n\n## 核心文件结构\n\nwheel 包遵循 PEP 427 标准格式，其内部文件结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n元数据配置模块主要负责生成 `dist-info` 目录下的四个核心文件。资料来源：[spec.md]()\n\n## 元数据类型详解\n\n### METADATA 文件\n\nMETADATA 文件遵循 PEP 566 规范，定义包的描述性信息。其生成逻辑位于 `generate_metadata()` 函数中：\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str = \"Go binary packaged as Python wheel\",\n    *,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    requires_python: str = \">=3.10\",\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的文件内容格式：\n\n```\nMetadata-Version: 2.1\nName: {package_name}\nVersion: {version}\nSummary: {description}\nAuthor: {author}\nAuthor-email: {author_email}\nLicense: {license}\nHome-page: {url}\nRequires-Python: {requires_python}\nDescription-Content-Type: text/markdown\n\n{readme_content}\n```\n\n| 字段 | 说明 | 来源参数 |\n|------|------|---------|\n| Metadata-Version | 元数据版本，固定为 2.1 | 固定值 |\n| Name | 包名称 | `name` 参数 |\n| Version | 包版本 | `version` 参数 |\n| Summary | 包描述 | `description` 参数 |\n| Author | 作者姓名 | `author` 参数 |\n| Author-email | 作者邮箱 | `author_email` 参数 |\n| License | 许可证标识符 | `license_` 参数 |\n| Home-page | 项目主页 URL | `url` 参数 |\n| Requires-Python | Python 版本要求 | `requires_python` 参数 |\n| Description-Content-Type | README 内容类型 | 仅当提供 readme_content 时添加 |\n\n资料来源：[go_to_wheel/__init__.py:180-216]()\n\n### WHEEL 文件\n\nWHEEL 文件遵循 PEP 427 规范，定义 wheel 包的分发属性：\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel {version}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n```\n\n| 字段 | 说明 | 值 |\n|------|------|-----|\n| Wheel-Version | wheel 格式版本 | 固定为 1.0 |\n| Generator | 生成工具标识 | `go-to-wheel {__version__}` |\n| Root-Is-Purelib | 是否为纯 Python 包 | 固定为 `false`（Go 二进制为本地扩展） |\n| Tag | wheel 平台标签 | `py3-none-{platform_tag}` |\n\n资料来源：[go_to_wheel/__init__.py:218-225]()\n\n### entry_points.txt 文件\n\nentry_points.txt 定义控制台入口点，使安装后的包可以在 PATH 中直接调用：\n\n```\n[console_scripts]\n{entry_point} = {package_name}:main\n```\n\n| 字段 | 说明 | 来源参数 |\n|------|------|---------|\n| [console_scripts] | 入口点类型 | 固定部分 |\n| {entry_point} | CLI 命令名称 | `entry_point` 参数，默认为包名 |\n| {package_name} | Python 模块名 | 规范化后的包名 |\n| main | 调用的函数名 | 固定为 `main` |\n\n资料来源：[go_to_wheel/__init__.py:227-232]()\n\n### RECORD 文件\n\nRECORD 文件遵循 PEP 376 规范，记录包内所有文件的路径、哈希值和大小：\n\n```\n{path},{sha256_hash},{size}\n```\n\n该文件为 CSV 格式，每行代表一个文件，文件列表以空行结束。RECORD 文件本身不包含哈希值（留空）。资料来源：[go_to_wheel/__init__.py:234-245]()\n\n## 命令行参数映射\n\ngo-to-wheel 通过 argparse 解析命令行参数，并将这些参数传递给 `build_wheels()` 函数生成元数据：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    description: str = \"Go binary packaged as Python wheel\",\n    requires_python: str = \">=3.10\",\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme: str | None = None,\n    ldflags: str | None = None,\n    set_version_var: str | None = None,\n) -> list[str]:\n```\n\n参数与元数据字段的对应关系：\n\n| CLI 参数 | 类型 | 默认值 | METADATA 字段 |\n|---------|------|--------|--------------|\n| `--name` | str | 目录 basename | Name |\n| `--version` | str | \"0.1.0\" | Version |\n| `--description` | str | \"Go binary packaged as Python wheel\" | Summary |\n| `--author` | str | None | Author |\n| `--author-email` | str | None | Author-email |\n| `--license` | str | None | License |\n| `--url` | str | None | Home-page |\n| `--requires-python` | str | \">=3.10\" | Requires-Python |\n| `--readme` | str | None | Description-Content-Type + 内容 |\n| `--entry-point` | str | 与 name 相同 | 控制台脚本名 |\n\n资料来源：[go_to_wheel/__init__.py:35-96]()\n\n## 默认值与自动推断\n\n### 包名自动推断\n\n```python\nif name is None:\n    name = go_path.name\n```\n\n当未指定 `--name` 参数时，系统自动使用 Go 模块目录的基础名称作为包名。资料来源：[go_to_wheel/__init__.py:250-251]()\n\n### 入口点自动推断\n\n```python\nif entry_point is None:\n    entry_point = name\n```\n\n当未指定 `--entry-point` 参数时，CLI 命令名默认与包名相同。资料来源：[go_to_wheel/__init__.py:253-254]()\n\n### README 文件读取\n\n```python\nreadme_content: str | None = None\nif readme:\n    readme_path = Path(readme)\n    if not readme_path.exists():\n        raise FileNotFoundError(f\"README file not found: {readme}\")\n    readme_content = readme_path.read_text(encoding=\"utf-8\")\n```\n\nREADME 文件路径通过 `--readme` 参数指定，系统读取文件内容并将其嵌入 METADATA 的 Description 字段。资料来源：[go_to_wheel/__init__.py:237-245]()\n\n## 平台标签映射\n\ngo-to-wheel 定义了完整的目标平台到 wheel 标签的映射关系：\n\n```python\nPLATFORM_MAPPINGS: dict[str, tuple[str, str, str]] = {\n    \"linux-amd64\": (\"linux\", \"amd64\", \"manylinux_2_17_x86_64\"),\n    \"linux-arm64\": (\"linux\", \"arm64\", \"manylinux_2_17_aarch64\"),\n    \"linux-amd64-musl\": (\"linux\", \"amd64\", \"musllinux_1_2_x86_64\"),\n    \"linux-arm64-musl\": (\"linux\", \"arm64\", \"musllinux_1_2_aarch64\"),\n    \"darwin-amd64\": (\"darwin\", \"amd64\", \"macosx_10_9_x86_64\"),\n    \"darwin-arm64\": (\"darwin\", \"arm64\", \"macosx_11_0_arm64\"),\n    \"windows-amd64\": (\"windows\", \"amd64\", \"win_amd64\"),\n    \"windows-arm64\": (\"windows\", \"arm64\", \"win_arm64\"),\n}\n\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|---------|------|--------|-----------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:14-27]()\n\n## 元数据生成流程\n\n元数据的生成发生在 wheel 构建过程中，整体流程如下：\n\n```mermaid\ngraph TD\n    A[接收 build_wheels 参数] --> B{验证 Go 模块目录}\n    B -->|go.mod 存在| C[读取 README 文件]\n    B -->|go.mod 不存在| Z[抛出 ValueError]\n    C --> D[设置默认值]\n    D --> E[处理 ldflags]\n    E --> F[遍历目标平台]\n    F --> G[编译 Go 二进制]\n    G --> H[创建临时目录结构]\n    H --> I[生成 Python 包装模块]\n    I --> J[生成元数据文件]\n    J --> K[计算文件哈希]\n    K --> L[生成 RECORD]\n    L --> M[打包为 ZIP]\n    M --> N[移动到输出目录]\n    N --> O[返回 wheel 路径列表]\n```\n\n元数据生成的关键步骤包括：\n\n1. **Python 包装模块生成**：创建 `__init__.py` 和 `__main__.py`，其中包含执行二进制文件的逻辑\n2. **METADATA 文件生成**：调用 `generate_metadata()` 创建包描述信息\n3. **WHEEL 文件生成**：调用 `generate_wheel_metadata()` 创建分发属性\n4. **entry_points.txt 生成**：调用 `generate_entry_points()` 创建控制台入口点\n5. **RECORD 文件生成**：收集所有文件，计算 SHA256 哈希，生成记录文件\n\n资料来源：[go_to_wheel/__init__.py:195-330]()\n\n## ldflags 与版本变量\n\ngo-to-wheel 支持通过 `--set-version-var` 参数将包版本嵌入 Go 二进制文件：\n\n```python\ncombined_ldflags_parts: list[str] = []\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n\ncombined_ldflags = \"-s -w \" + \" \".join(combined_ldflags_parts)\n```\n\n| 参数 | 说明 | 示例 |\n|------|------|-----|\n| `--set-version-var` | Go 变量路径，值自动使用 `--version` | `main.version` |\n| `--ldflags` | 附加的 Go 链接器标志 | `-X main.commit=abc123` |\n\n最终传递给 Go 编译器的 ldflags 格式为：\n\n```\n-s -w -X main.version=2.0.0 -X main.commit=abc123\n```\n\n其中 `-s -w` 为默认参数，用于剥离调试信息减少二进制体积。资料来源：[go_to_wheel/__init__.py:260-268]()\n\n## Python 包装模块\n\n元数据配置不仅包括 dist-info 目录下的文件，还包括 Python 包本身的代码。这些文件构成 Go 二进制与 Python 系统的桥梁：\n\n### `__init__.py`\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport sys\nimport subprocess\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"Return the path to the bundled binary.\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n### `__main__.py`\n\n```python\nfrom . import main\nmain()\n```\n\n包装模块采用 `console_scripts` 入口点机制而非 `.data/scripts/`，原因包括：\n- 跨平台行为一致\n- 可提供更友好的错误信息\n- 支持 pipx 无缝集成\n- 便于添加 Python 端功能\n\n资料来源：[spec.md]()\n\n## 完整元数据示例\n\n使用所有元数据选项构建 wheel：\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n生成的 METADATA 文件：\n\n```\nMetadata-Version: 2.1\nName: mytool-bin\nVersion: 2.0.0\nSummary: My awesome tool\nAuthor: Jane Doe\nAuthor-email: jane@example.com\nLicense: MIT\nHome-page: https://github.com/jane/mytool\nRequires-Python: >=3.10\nDescription-Content-Type: text/markdown\n\n{Redme 内容}\n```\n\n生成的 WHEEL 文件（以 linux-amd64 为例）：\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel 0.1.0\nRoot-Is-Purelib: false\nTag: py3-none-manylinux_2_17_x86_64\n```\n\n资料来源：[README.md]()\n\n## 总结\n\n元数据配置模块是 go-to-wheel 项目实现 Go 程序 Python 分发的核心组件。通过标准化地生成符合 PEP 规范的元数据文件，该模块确保生成的 wheel 包能够被 pip、pipx 等 Python 包管理工具正确识别和处理。模块设计充分利用 Python 标准库，无需额外依赖，同时通过命令行参数提供了灵活的配置能力。\n\n---\n\n<a id='page-5'></a>\n\n## Go 交叉编译流程\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [支持的平台](#page-3), [Wheel 生成机制](#page-6)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# Go 交叉编译流程\n\n## 概述\n\nGo 交叉编译流程是 go-to-wheel 工具的核心功能，负责将 Go 语言编写的 CLI 程序编译为支持多个操作系统和架构的二进制文件。该流程通过设置 Go 的环境变量（`GOOS`、`GOARCH`、`CGO_ENABLED`）实现跨平台编译，生成静态链接的二进制文件，为后续打包为 Python wheel 提供基础。\n\ngo-to-wheel 的交叉编译设计目标是：\n- 一次构建，多平台输出\n- 生成静态链接二进制（无 libc 依赖问题）\n- 自动处理平台差异（如 Windows 的 .exe 扩展名）\n- 支持通过 ldflags 注入版本信息\n\n## 支持的平台映射\n\ngo-to-wheel 内置了完整的目标平台映射表，将用户友好的平台标识符映射到 Go 编译所需的操作系统、架构以及最终的 wheel 平台标签。\n\n### 平台映射表\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | `linux` | `amd64` | `manylinux_2_17_x86_64` |\n| `linux-arm64` | `linux` | `arm64` | `manylinux_2_17_aarch64` |\n| `linux-amd64-musl` | `linux` | `amd64` | `musllinux_1_2_x86_64` |\n| `linux-arm64-musl` | `linux` | `arm64` | `musllinux_1_2_aarch64` |\n| `darwin-amd64` | `darwin` | `amd64` | `macosx_10_9_x86_64` |\n| `darwin-arm64` | `darwin` | `arm64` | `macosx_11_0_arm64` |\n| `windows-amd64` | `windows` | `amd64` | `win_amd64` |\n| `windows-arm64` | `windows` | `arm64` | `win_arm64` |\n\n资料来源：[go_to_wheel/__init__.py:18-27](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n### 默认编译平台\n\n默认情况下，go-to-wheel 会为以下 8 个平台构建二进制文件：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:29-38](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n这一策略覆盖了主流的 Linux 发行版（glibc 和 musl 两种 libc）、macOS（Intel 和 Apple Silicon）以及 Windows（x64 和 ARM64）用户群体。\n\n## 交叉编译流程架构\n\n### 流程概览\n\n```mermaid\ngraph TD\n    A[用户调用 go-to-wheel] --> B[解析命令行参数]\n    B --> C{指定平台列表?}\n    C -->|是| D[使用用户指定平台]\n    C -->|否| E[使用 DEFAULT_PLATFORMS]\n    D --> F[遍历目标平台列表]\n    E --> F\n    F --> G{每个平台}\n    G --> H[从 PLATFORM_MAPPINGS 获取 GOOS/GOARCH]\n    H --> I[构建 Go 交叉编译命令]\n    I --> J[执行 go build]\n    J --> K[验证二进制文件生成]\n    K --> L[创建 Python 包结构]\n    L --> M[生成 wheel 元数据]\n    M --> N[打包为 .whl 文件]\n    N --> O{还有更多平台?}\n    O -->|是| G\n    O -->|否| P[输出所有 wheel 文件路径]\n```\n\n### 核心编译函数\n\n`build_wheels()` 函数是整个流程的入口点，负责协调交叉编译和 wheel 打包的各个环节：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    description: str = \"Go binary packaged as Python wheel\",\n    requires_python: str = \">=3.10\",\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme: str | None = None,\n    ldflags: str | None = None,\n    set_version_var: str | None = None,\n) -> list[str]:\n```\n\n资料来源：[go_to_wheel/__init__.py:131-157](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n## 编译命令详解\n\n### 基础编译命令\n\n对于每个目标平台，go-to-wheel 执行以下格式的 Go 编译命令：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n### 环境变量说明\n\n| 环境变量 | 值 | 作用 |\n|---------|-----|------|\n| `GOOS` | 目标操作系统 | 指定编译目标平台 |\n| `GOARCH` | 目标架构 | 指定 CPU 架构 |\n| `CGO_ENABLED` | `0` | 禁用 CGO，确保生成静态链接二进制 |\n\n### 编译参数说明\n\n| 参数 | 值 | 作用 |\n|-----|-----|------|\n| `-ldflags=\"-s -w\"` | 链接器标志 | `-s` 剥离符号表，`-w` 移除 DWARF 调试信息，减小二进制体积 |\n| `-o` | 输出路径 | 指定编译产物的位置 |\n\n### ldflags 扩展机制\n\ngo-to-wheel 支持通过 `--ldflags` 参数追加额外的链接器标志，允许用户嵌入版本信息等自定义数据：\n\n```python\n# 构建组合 ldflags：先设置版本变量，再追加用户 ldflags\ncombined_ldflags_parts: list[str] = []\n\n# 添加 -X 标志设置版本变量\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\n\n# 追加用户提供的 ldflags\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n\n# 最终 ldflags 格式: -s -w -X main.version=1.0.0 -X main.commit=abc123\ncombined_ldflags = \" \".join(combined_ldflags_parts)\n```\n\n资料来源：[go_to_wheel/__init__.py:180-195](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n这使得最终的链接器调用变为：\n\n```bash\n-ldflags=\"-s -w -X main.version=2.0.0\"\n```\n\n其中 `-X` 标志允许在编译时设置 Go 代码中的字符串变量值，这是 Go 项目中嵌入版本信息的标准做法。\n\n## 平台特定处理\n\n### Windows 平台\n\nWindows 平台的 Go 编译会自动添加 `.exe` 扩展名。go-to-wheel 在查找编译输出时使用以下逻辑：\n\n```python\n# Windows 平台检查\nis_windows = goos == \"windows\"\noutput_name = binary_name + \".exe\" if is_windows else binary_name\noutput_path = temp_dir / output_name\n```\n\n### Linux musl 平台\n\n对于 musl 基础镜像的 Linux 发行版（如 Alpine Linux），go-to-wheel 通过设置 `CGO_ENABLED=0` 确保生成的二进制不依赖 glibc，这是实现 musl 兼容性的关键。\n\n## 交叉编译流程详细步骤\n\n### 步骤 1：输入验证\n\n```mermaid\ngraph LR\n    A[go_dir 参数] --> B{目录存在?}\n    B -->|否| C[抛出 FileNotFoundError]\n    B -->|是| D{go.mod 存在?}\n    D -->|否| E[抛出 ValueError: Not a Go module]\n    D -->|是| F[继续处理]\n```\n\n### 步骤 2：参数解析与默认值\n\n```python\ngo_path = Path(go_dir).resolve()\n\n# 设置包名默认为目录名\nif name is None:\n    name = go_path.name\n\n# 设置入口点默认为包名\nif entry_point is None:\n    entry_point = name\n\n# 设置平台列表默认为所有支持的平台\nif platforms is None:\n    platforms = DEFAULT_PLATFORMS\n```\n\n### 步骤 3：平台迭代编译\n\n对于平台列表中的每个平台：\n\n1. 从 `PLATFORM_MAPPINGS` 获取 `goos`、`goarch`、`platform_tag`\n2. 构建 `subprocess.run()` 调用\n3. 设置环境变量 `GOOS`、`GOARCH`、`CGO_ENABLED`\n4. 执行 `go build` 命令\n5. 验证二进制文件是否成功生成\n\n### 步骤 4：二进制文件组织\n\n编译完成后，每个平台的二进制文件被组织到统一的目录结构中：\n\n```\n{package_name}/\n├── __init__.py\n├── __main__.py\n└── bin/\n    └── {binary_name}[.exe]    ← 编译生成的二进制文件\n```\n\n## 错误处理与验证\n\n### 编译错误处理\n\n如果 `go build` 命令执行失败，subprocess 会抛出异常，流程终止并向用户报告错误：\n\n```python\nresult = subprocess.run(\n    [go_binary, \"build\", \"-ldflags=\" + ldflags, \"-o\", str(output_path), \".\"],\n    cwd=go_path,\n    env=env,\n    capture_output=True,\n    text=True,\n)\n\nif result.returncode != 0:\n    raise RuntimeError(f\"Go build failed: {result.stderr}\")\n```\n\n### 包名验证规则\n\n根据 PEP 503，包名必须满足以下规则：\n\n| 规则 | 说明 |\n|-----|------|\n| 可用字符 | 小写字母、数字、连字符、下划线、句点 |\n| 首字符 | 必须以字母或数字开头 |\n| 规范化 | 连字符和下划线统一转换为连字符用于 wheel 文件名 |\n\n包目录使用 PEP 8 风格的导入名，即连字符替换为下划线：\n\n```python\n# 例如: my-tool → my_tool/\nimport_name = name.replace(\"-\", \"_\")\n```\n\n## 与 wheel 打包的集成\n\n### 数据流向\n\n```mermaid\ngraph LR\n    A[Go 源码] --> B[go build 交叉编译]\n    B --> C[各平台二进制文件]\n    C --> D[Python 包结构组装]\n    D --> E[wheel 元数据生成]\n    E --> F[.whl 文件打包]\n    F --> G[Python wheel 分发]\n```\n\n### wheel 生成流程\n\n交叉编译完成后，每个二进制文件会经历以下流程：\n\n1. **创建临时目录结构**：按照 wheel 规范创建目录层级\n2. **复制二进制文件**：将编译产物放入 `{package_name}/bin/` 目录\n3. **生成 Python 包装器**：创建 `__init__.py` 和 `__main__.py`\n4. **生成元数据文件**：创建 `METADATA`、`WHEEL`、`RECORD`、`entry_points.txt`\n5. **打包为 zip**：使用 `zipfile` 创建 `.whl` 文件\n\n### wheel 文件命名规范\n\n生成的 wheel 文件遵循 PEP 427 命名规范：\n\n```\n{name}-{version}-py3-none-{platform_tag}.whl\n```\n\n示例：\n- `mytool-0.1.0-py3-none-manylinux_2_17_x86_64.whl`\n- `mytool-0.1.0-py3-none-macosx_11_0_arm64.whl`\n- `mytool-0.1.0-py3-none-win_amd64.whl`\n\n## 命令行接口\n\n### 使用方式\n\n```bash\ngo-to-wheel path/to/go-folder [options]\n```\n\n### 交叉编译相关参数\n\n| 参数 | 说明 | 默认值 |\n|-----|------|--------|\n| `--platforms PLATFORMS` | 逗号分隔的目标平台列表 | 所有支持的平台 |\n| `--go-binary PATH` | Go 二进制文件路径 | `go`（从 PATH 环境变量查找） |\n| `--ldflags FLAGS` | 额外的 Go 链接器标志 | `None` |\n| `--set-version-var VAR` | 设置版本变量的 Go 变量名 | `None` |\n| `--version VERSION` | 包版本号 | `0.1.0` |\n\n### 使用示例\n\n构建特定平台的 wheel：\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n嵌入版本信息：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n自定义链接器标志：\n\n```bash\ngo-to-wheel ./mytool --ldflags \"-X main.commit=abc123\"\n```\n\n## 技术要点总结\n\n### 为什么使用 CGO_ENABLED=0\n\n禁用 CGO 是实现静态链接和跨发行版兼容性的关键：\n\n- **静态链接**：生成的二进制文件不依赖系统 libc\n- **无需交叉编译工具链**：Go 的交叉编译原生支持纯 Go 代码\n- **部署简化**：单个二进制文件即可运行，无需安装运行时依赖\n\n### ldflags 的最佳实践\n\n在 Go 项目中使用 `--set-version-var` 功能时，Go 源码应包含版本变量声明：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if len(os.Args) > 1 && os.Args[1] == \"--version\" {\n        fmt.Println(version)\n    }\n}\n```\n\n这样编译后的二进制文件可以通过 `--version` 参数显示正确的版本号。\n\n### 输出目录结构\n\n编译完成后，wheel 文件默认输出到 `./dist` 目录，用户可以通过 `--output-dir` 参数自定义输出位置。\n\n---\n\n<a id='page-6'></a>\n\n## Wheel 生成机制\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [Go 交叉编译流程](#page-5), [元数据配置](#page-4)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# Wheel 生成机制\n\n`go-to-wheel` 的核心功能是将 Go 语言编译的二进制程序封装为符合 Python PEP 427 标准的 wheel 安装包。本页面详细说明 wheel 生成的技术机制、文件结构和工作流程。\n\n## 概述\n\nWheel 生成机制是 `go-to-wheel` 将 Go 二进制程序转换为可分发 Python 包的核心模块。该机制包含三个主要阶段：\n\n1. **跨平台编译** - 使用 Go 工具链为不同操作系统和架构编译静态二进制文件\n2. **包结构构建** - 创建符合 PEP 427 规范的 wheel 目录结构\n3. **元数据生成** - 生成 METADATA、WHEEL、entry_points.txt 和 RECORD 文件\n\n资料来源：[spec.md]()\n\n## 平台映射表\n\ngo-to-wheel 支持的编译平台与 wheel 标签之间的映射关系定义在 `PLATFORM_MAPPINGS` 字典中：\n\n```python\nPLATFORM_MAPPINGS: dict[str, tuple[str, str, str]] = {\n    \"linux-amd64\": (\"linux\", \"amd64\", \"manylinux_2_17_x86_64\"),\n    \"linux-arm64\": (\"linux\", \"arm64\", \"manylinux_2_17_aarch64\"),\n    \"linux-amd64-musl\": (\"linux\", \"amd64\", \"musllinux_1_2_x86_64\"),\n    \"linux-arm64-musl\": (\"linux\", \"arm64\", \"musllinux_1_2_aarch64\"),\n    \"darwin-amd64\": (\"darwin\", \"amd64\", \"macosx_10_9_x86_64\"),\n    \"darwin-arm64\": (\"darwin\", \"arm64\", \"macosx_11_0_arm64\"),\n    \"windows-amd64\": (\"windows\", \"amd64\", \"win_amd64\"),\n    \"windows-arm64\": (\"windows\", \"arm64\", \"win_arm64\"),\n}\n```\n\n每个映射包含三个元素：`GOOS`（操作系统）、`GOARCH`（架构）和 wheel 标签。\n\n资料来源：[go_to_wheel/__init__.py:15-25](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L15-L25)\n\n## 默认平台列表\n\n`DEFAULT_PLATFORMS` 定义了未指定平台时的默认编译目标：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n这意味着默认情况下，go-to-wheel 会为 Linux（glibc 和 musl 两种 libc）、macOS 和 Windows 各平台生成 wheels。\n\n资料来源：[go_to_wheel/__init__.py:27-34](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L27-L34)\n\n## 核心函数\n\n### build_wheels 函数\n\n`build_wheels()` 是入口函数，负责协调整个 wheel 生成流程：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    # ... 其他参数\n) -> list[str]:\n```\n\n该函数执行以下验证步骤：\n1. 检查 Go 目录是否存在\n2. 验证 `go.mod` 文件存在\n3. 读取 README 文件（如提供）\n4. 解析平台列表并设置默认值\n5. 组合 ldflags 参数\n\n资料来源：[go_to_wheel/__init__.py:131-220](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L131-L220)\n\n### build_single_wheel 函数\n\n`build_single_wheel()` 负责为单个平台构建 wheel 文件：\n\n```python\ndef build_single_wheel(\n    binary_content: bytes,\n    platform: str,\n    # ... 其他参数\n) -> str:\n```\n\n该函数的核心流程：\n1. 计算平台标签和包名称\n2. 创建临时目录结构\n3. 生成所有必需的文件\n4. 打包为 ZIP 文件\n5. 设置二进制文件的可执行权限\n\n资料来源：[go_to_wheel/__init__.py:65-128](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L65-L128)\n\n## Wheel 文件结构\n\n生成的 wheel 文件遵循 PEP 427 规范，其内部结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {import_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {import_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n关键点：\n- 包目录使用 **import_name**（将连字符替换为下划线）\n- 二进制文件位于 `bin/` 子目录\n- `dist-info/` 目录包含所有元数据文件\n- `Root-Is-Purelib: false` 表示这是平台特定包\n\n资料来源：[spec.md]()\n\n## 元数据生成\n\n### METADATA 文件\n\n`generate_metadata()` 函数生成符合 PEP 566 标准的 METADATA 文件：\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str,\n    requires_python: str,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的内容示例：\n\n```\nMetadata-Version: 2.1\nName: mytool\nVersion: 1.0.0\nSummary: My awesome tool\nRequires-Python: >=3.10\nDescription-Content-Type: text/markdown\n\n# My Tool\n\n...\n```\n\n资料来源：[go_to_wheel/__init__.py:240-280](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L240-L280)\n\n### WHEEL 文件\n\n`generate_wheel_metadata()` 函数生成 WHEEL 元数据：\n\n```python\ndef generate_wheel_metadata(platform_tag: str) -> str:\n    return f\"\"\"Wheel-Version: 1.0\nGenerator: go-to-wheel {__version__}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n\"\"\"\n```\n\n`Root-Is-Purelib: false` 表示该 wheel 包含平台特定的二进制文件。\n\n资料来源：[go_to_wheel/__init__.py:282-288](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L282-L288)\n\n### entry_points.txt\n\n`generate_entry_points()` 函数生成 console_scripts 入口点配置：\n\n```python\ndef generate_entry_points(entry_point: str, import_name: str) -> str:\n    return f\"\"\"[console_scripts]\n{entry_point} = {import_name}:main\n\"\"\"\n```\n\n这使得安装后可以直接通过命令行调用 `entry_point` 命令来执行 Go 程序。\n\n资料来源：[go_to_wheel/__init__.py:290-294](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L290-L294)\n\n### RECORD 文件\n\n`generate_record()` 函数生成 RECORD 文件，这是 PEP 376 规范要求的文件清单：\n\n```python\ndef generate_record(files: dict[str, bytes]) -> str:\n    output = io.StringIO()\n    writer = csv.writer(output)\n    \n    for path, content in files.items():\n        if path.endswith(\"RECORD\"):\n            writer.writerow([path, \"\", \"\"])\n        else:\n            hash_value = hashlib.sha256(content).digest()\n            hash_b64 = base64.urlsafe_b64encode(hash_value).rstrip(b\"=\").decode(\"ascii\")\n            size = len(content)\n            writer.writerow([path, f\"sha256={hash_b64}\", size])\n    \n    return output.getvalue()\n```\n\nRECORD 文件使用 CSV 格式，每行包含：文件路径、SHA256 哈希值和文件大小。\n\n资料来源：[go_to_wheel/__init__.py:296-308](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L296-L308)\n\n## Python 包装器\n\n生成的 `__init__.py` 包含 Go 二进制程序的调用逻辑：\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport sys\nimport subprocess\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"返回打包的二进制文件路径。\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"执行打包的二进制文件。\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows: 使用 subprocess.call 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix: 使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n关键设计决策：\n- Windows 使用 `subprocess.call` 以正确处理信号\n- Unix 使用 `os.execvp` 替换当前进程，获得原生的信号处理行为\n\n资料来源：[spec.md]()\n\n## 构建流程图\n\n```mermaid\ngraph TD\n    A[build_wheels 入口] --> B{验证 Go 目录和 go.mod}\n    B -->|通过| C[读取 README 文件]\n    B -->|失败| Z[抛出异常]\n    C --> D[设置默认值]\n    D --> E{遍历目标平台列表}\n    E -->|还有平台| F[调用 go build 编译]\n    F --> G[调用 build_single_wheel]\n    G --> H[生成包文件结构]\n    H --> I[生成元数据文件]\n    I --> J[打包为 ZIP]\n    J --> K[保存到输出目录]\n    K --> E\n    E -->|完成| L[返回 wheel 文件列表]\n```\n\n## 二进制编译过程\n\n对于每个目标平台，go-to-wheel 使用以下命令进行交叉编译：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n编译参数说明：\n- `CGO_ENABLED=0`：禁用 CGO，生成静态链接的二进制文件\n- `-ldflags=\"-s -w\"`：剥离符号表和调试信息，减小文件体积\n- Windows 平台自动添加 `.exe` 扩展名\n\n资料来源：[spec.md]()\n\n## ldflags 合并机制\n\n`build_wheels` 函数支持通过 `--set-version-var` 和 `--ldflags` 参数自定义 Go 链接器标志：\n\n```python\n# 构建组合 ldflags: set_version_var 优先于用户 ldflags\ncombined_ldflags_parts: list[str] = []\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n```\n\n这允许：\n1. 通过 `--set-version-var main.version` 自动注入版本号\n2. 通过 `--ldflags` 添加自定义标志（如 git commit hash）\n\n资料来源：[go_to_wheel/__init__.py:193-200](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L193-L200)\n\n## 包名称规范\n\ngo-to-wheel 对包名称有以下处理规则：\n\n| 输入 | import_name | 分发名称 |\n|------|-------------|---------|\n| `mytool` | `mytool` | `mytool` |\n| `my-tool` | `my_tool` | `mytool` |\n| `my.tool` | `my_tool` | `mytool` |\n\n- **分发名称**：用于 wheel 文件名和 pip 安装\n- **import_name**：用于 Python 包目录（PEP 8 规范）\n- 两者通过名称规范化（将连字符和点号替换为下划线）相互转换\n\n资料来源：[spec.md]()\n\n## 可执行权限处理\n\n在创建 ZIP 文件时，go-to-wheel 为二进制文件设置 Unix 权限：\n\n```python\nif \"/bin/\" in file_path:\n    info = zipfile.ZipInfo(file_path)\n    info.external_attr = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) << 16\n    whl.writestr(info, content)\nelse:\n    whl.writestr(file_path, content)\n```\n\n这确保打包的二进制文件在解压后具有可执行权限（rwxr-xr-x）。\n\n资料来源：[go_to_wheel/__init__.py:113-119](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L113-L119)\n\n## 依赖关系\n\ngo-to-wheel 本身无外部 Python 依赖，仅使用 Python 标准库：\n\n- `argparse` - 命令行参数解析\n- `csv` - RECORD 文件生成\n- `hashlib` - SHA256 哈希计算\n- `zipfile` - wheel 打包\n- `subprocess` - Go 编译调用\n\n资料来源：[go_to_wheel/__init__.py:1-14](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L1-L14)\n\n---\n\n<a id='page-7'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [高级用法与示例](#page-8), [开发环境搭建](#page-9)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 快速开始\n\n`go-to-wheel` 是一款将 Go 语言编写的命令行工具编译并打包为 Python Wheel 分发包的工具。本文档介绍如何快速上手使用该工具。\n\n## 前置要求\n\n### 系统依赖\n\n| 依赖项 | 版本要求 | 说明 |\n|--------|----------|------|\n| Python | >= 3.10 | 运行环境 |\n| Go | >= 1.16 | 用于编译 Go 模块 |\n\nGo 编译器需要安装并位于 PATH 环境变量中。\n\n### 环境检查\n\n```bash\n# 验证 Python 版本\npython --version\n\n# 验证 Go 已安装\ngo version\n```\n\n## 安装方式\n\n`go-to-wheel` 支持多种安装方式：\n\n```bash\n# 通过 pip 安装\npip install go-to-wheel\n\n# 通过 pipx 安装（推荐）\npipx install go-to-wheel\n```\n\n资料来源：[README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 基础用法\n\n### 最简命令\n\n使用默认配置为 Go 模块构建所有平台的 Wheel：\n\n```bash\ngo-to-wheel path/to/go-module\n```\n\n这会自动创建以下平台的 Wheel 文件到 `./dist` 目录：\n\n- Linux (glibc): amd64, arm64\n- Linux (musl): amd64, arm64\n- macOS: Intel (amd64), Apple Silicon (arm64)\n- Windows: amd64, arm64\n\n### 构建流程\n\n```mermaid\ngraph TD\n    A[go-to-wheel 命令] --> B[验证 Go 模块]\n    B --> C[交叉编译 Go 二进制]\n    C --> D[创建 Python 包结构]\n    D --> E[生成 Wheel 元数据]\n    E --> F[打包为 .whl 文件]\n    F --> G[输出到 ./dist 目录]\n```\n\n资料来源：[spec.md - Build Process](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n## 常用命令示例\n\n### 示例一：基本构建\n\n```bash\ngo-to-wheel ./mytool\n```\n\n生成的 Wheel 文件命名格式为：\n```\n{mytool}-{version}-py3-none-{platform_tag}.whl\n```\n\n### 示例二：自定义包名\n\n```bash\ngo-to-wheel ./mytool --name my-python-tool\n```\n\n这将生成名为 `my_python_tool` 的 Python 包。\n\n### 示例三：指定版本\n\n```bash\ngo-to-wheel ./mytool --version 1.2.3\n```\n\n### 示例四：指定输出目录\n\n```bash\ngo-to-wheel ./mytool --output-dir ./wheels\n```\n\n### 示例五：仅构建特定平台\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n支持的平台标识符：\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|----------|------|--------|------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[README.md - Supported platforms](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 完整元数据配置\n\n为 PyPI 发布准备完整的 Wheel 包：\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n### 可用元数据选项\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--name` | Python 包名 | 目录名 |\n| `--version` | 包版本 | 0.1.0 |\n| `--description` | 包描述 | \"Go binary packaged as Python wheel\" |\n| `--license` | 许可证标识符 | 无 |\n| `--author` | 作者姓名 | 无 |\n| `--author-email` | 作者邮箱 | 无 |\n| `--url` | 项目 URL | 无 |\n| `--readme` | README 文件路径 | 无 |\n| `--requires-python` | Python 版本要求 | >=3.10 |\n\n资料来源：[go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n## 嵌入版本信息\n\n### 方式一：使用 --set-version-var\n\n`go-to-wheel` 可以自动将版本号嵌入到 Go 二进制文件中。首先在 Go 代码中声明一个 version 变量：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if os.Args[1] == \"--version\" {\n        fmt.Println(version) // 构建后将输出 \"2.0.0\"\n    }\n}\n```\n\n然后使用 `--set-version-var` 参数：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n这会传递 `-X main.version=2.0.0` 给 Go 链接器。\n\n### 方式二：使用 --ldflags\n\n传递任意 Go 链接器标志：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 \\\n  --ldflags \"-X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n标志会被追加到默认的 `-s -w`，最终链接器调用为：\n```\n-ldflags=\"-s -w -X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n资料来源：[README.md - Examples](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 安装生成的 Wheel\n\n### 使用 pip 安装\n\n```bash\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n### 使用 uv 测试\n\n```bash\nuv run --with ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl mytool --help\n```\n\n### 使用 pipx 安装为全局命令\n\n```bash\npipx install ./dist/mytool-1.0.0-py3-none-*.whl\n```\n\n安装后，Go 二进制文件会自动添加到 PATH，可以直接运行：\n\n```bash\nmytool --help\n```\n\n## 内部构建机制\n\n### 编译参数\n\n`go-to-wheel` 使用以下参数构建 Go 二进制文件：\n\n| 参数 | 值 | 作用 |\n|------|-----|------|\n| CGO_ENABLED | 0 | 禁用 CGO，确保静态链接 |\n| -ldflags | -s -w | 剥离调试信息，减小体积 |\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md - Cross-Compile](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### Wheel 包结构\n\n生成的 Wheel 包含以下文件结构：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n### Python 包装器\n\n`__init__.py` 包含一个包装函数，负责执行打包的二进制文件：\n\n```python\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows 上使用 subprocess 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix 上使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n资料来源：[spec.md - Package Structure](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n## 开发调试\n\n### 本地开发安装\n\n```bash\ngit clone https://github.com/simonw/go-to-wheel\ncd go-to-wheel\n```\n\n### 运行测试\n\n```bash\nuv run pytest\n```\n\n## 故障排除\n\n### 常见问题\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| \"Go directory not found\" | 指定路径不存在 | 确认路径正确 |\n| \"no go.mod file found\" | 目录不是 Go 模块 | 确认目录下有 go.mod |\n| \"Go compilation failed\" | Go 编译错误 | 检查 Go 代码语法 |\n| 安装后命令找不到 | PATH 未刷新 | 重新打开终端或 source 相关配置 |\n\n### 调试模式\n\n如需查看详细构建过程，可检查命令输出。`go-to-wheel` 会打印正在构建的平台信息：\n\n```\n$ go-to-wheel ./myapp --name myapp-bin\n\nlinux_amd64.whl\n  ✓ myapp_bin-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n  ✓ myapp_bin-1.0.0-py3-none-manylinux_2_17_aarch64.whl\n  ...\n\nDone! Built 8 wheels in ./dist\n```\n\n## 下一步\n\n- 查看完整[使用文档](README.md)了解更多高级用法\n- 参考 [spec.md](spec.md) 了解技术规格\n- 探索类似项目 [maturin](https://github.com/PyO3/maturin)（Rust 等价工具）\n\n---\n\n<a id='page-8'></a>\n\n## 高级用法与示例\n\n### 相关页面\n\n相关主题：[快速开始](#page-7), [Go 交叉编译流程](#page-5), [元数据配置](#page-4)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 高级用法与示例\n\n## 概览\n\n`go-to-wheel` 是一款将 Go CLI 程序编译为 Python wheel 分发包的命令行工具。在掌握基础用法后，本页将深入介绍其高级特性，包括跨平台精细化控制、版本信息嵌入、完整 PyPI 元数据配置等高级功能，帮助开发者将该工具集成到生产级发布流程中。\n\n资料来源：[README.md:1-50](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n## 核心参数详解\n\n### 完整参数对照表\n\n| 参数 | 说明 | 默认值 |\n|------|------|--------|\n| `--name` | Python 包名称 | 目录basename |\n| `--version` | 包版本号 | `0.1.0` |\n| `--output-dir` | 构建产物输出目录 | `./dist` |\n| `--entry-point` | CLI 命令名称 | 与包名相同 |\n| `--platforms` | 目标平台列表（逗号分隔） | 全部支持平台 |\n| `--go-binary` | Go 二进制文件路径 | `go` |\n| `--description` | 包描述 | `\"Go binary packaged as Python wheel\"` |\n| `--license` | 许可证标识符 | None |\n| `--author` | 作者姓名 | None |\n| `--author-email` | 作者邮箱 | None |\n| `--url` | 项目主页 | None |\n| `--requires-python` | Python 版本要求 | `>=3.10` |\n| `--readme` | README markdown 文件路径 | None |\n| `--set-version-var` | Go 变量名，用于嵌入版本 | None |\n| `--ldflags` | 额外 Go 链接器标志 | None |\n\n资料来源：[README.md:60-90](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n## 跨平台构建控制\n\n### 架构流程\n\n```mermaid\ngraph TD\n    A[go-to-wheel 命令] --> B[解析 --platforms 参数]\n    B --> C{平台列表为空?}\n    C -->|是| D[使用 DEFAULT_PLATFORMS]\n    C -->|否| E[解析用户指定平台]\n    D --> F[循环遍历目标平台]\n    E --> F\n    F --> G[GOOS/GOARCH 环境变量]\n    G --> H[CGO_ENABLED=0 静态编译]\n    H --> I[生成 wheel 文件]\n    I --> J[输出到 --output-dir]\n    J --> K[打印构建摘要]\n```\n\n### 支持的平台与 Wheel 标签映射\n\n| 平台标识 | GOOS | GOARCH | Wheel Tag |\n|----------|------|--------|-----------|\n| `linux-amd64` | linux | amd64 | `manylinux_2_17_x86_64` |\n| `linux-arm64` | linux | arm64 | `manylinux_2_17_aarch64` |\n| `linux-amd64-musl` | linux | amd64 | `musllinux_1_2_x86_64` |\n| `linux-arm64-musl` | linux | arm64 | `musllinux_1_2_aarch64` |\n| `darwin-amd64` | darwin | amd64 | `macosx_10_9_x86_64` |\n| `darwin-arm64` | darwin | arm64 | `macosx_11_0_arm64` |\n| `windows-amd64` | windows | amd64 | `win_amd64` |\n| `windows-arm64` | windows | arm64 | `win_arm64` |\n\n资料来源：[README.md:95-120](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n### 选择性构建特定平台\n\n```bash\n# 仅构建 Linux amd64 和 macOS ARM64\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n\n# 仅构建 Windows 版本\ngo-to-wheel ./mytool --platforms windows-amd64,windows-arm64\n```\n\n这种选择性构建能力允许开发者根据目标部署环境优化 CI/CD 流程，减少不必要的构建时间和存储空间。\n\n---\n\n## 版本嵌入与链接器标志\n\n### 编译参数合并逻辑\n\n`go-to-wheel` 在构建时会自动合并链接器标志，遵循以下优先级：\n\n1. 默认标志：`-s -w`（去除符号表和调试信息）\n2. 版本变量标志：`-X {var}={version}`（如果指定了 `--set-version-var`）\n3. 用户自定义标志：`--ldflags` 中的值\n\n资料来源：[go_to_wheel/__init__.py:180-200](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n```mermaid\ngraph LR\n    A[默认 ldflags<br/>-s -w] --> C[最终 ldflags]\n    B[--ldflags] --> C\n    D[--set-version-var] -->|先处理| B\n```\n\n### 使用 `--set-version-var` 自动嵌入版本\n\n当 Go 源代码中定义了 `version` 变量时，可通过此参数自动注入版本信息：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n对应的 Go 代码示例：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if len(os.Args) > 1 && os.Args[1] == \"--version\" {\n        fmt.Println(version)\n    }\n    // 其他逻辑...\n}\n```\n\n编译后，执行 `mytool --version` 将输出 `2.0.0`。\n\n资料来源：[README.md:35-55](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n### 高级链接器标志使用\n\n通过 `--ldflags` 传递任意链接器标志：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 \\\n  --ldflags \"-X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n完整链接器调用变为：\n```\n-ldflags=\"-s -w -X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n---\n\n## 完整 PyPI 发布元数据配置\n\n### 最小发布配置\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n### 生成的文件结构\n\n每个 wheel 包内部遵循 PEP 427 标准结构：\n\n```\n{mytool_bin-2.0.0-py3-none-manylinux_2_17_x86_64.whl}/\n├── mytool_bin/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── mytool_bin\n├── mytool_bin-2.0.0.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md:80-130](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### METADATA 文件内容生成\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    requires_python: str = \">=3.10\",\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的 METADATA 文件遵循 PEP 566 标准，包含所有必需字段。\n\n资料来源：[go_to_wheel/__init__.py:50-90](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 内部封装机制\n\n### Python 包装器工作原理\n\n生成的 `__init__.py` 文件包含以下核心功能：\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport stat\nimport subprocess\nimport sys\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"返回捆绑二进制文件的路径\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"执行捆绑的二进制文件\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows: 使用 subprocess 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix: 使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n资料来源：[spec.md:100-140](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### 跨平台执行策略\n\n```mermaid\ngraph TD\n    A[pip install wheel] --> B[执行 entry_points.txt]\n    B --> C[调用 mypackage:main]\n    C --> D{检测 sys.platform}\n    D -->|win32| E[subprocess.call]\n    D -->|Unix| F[os.execvp]\n    E --> G[启动 Go 二进制]\n    F --> G\n```\n\n这种设计确保了在所有平台上都能获得一致的命令行体验，同时保持了 `pipx` 的完全兼容性。\n\n资料来源：[spec.md:140-150](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n---\n\n## 构建流程详解\n\n### 完整编译流程\n\n```mermaid\nflowchart TD\n    A[验证 go.mod 存在] --> B{--readme 参数?}\n    B -->|是| C[读取 README 内容]\n    B -->|否| D[继续]\n    C --> E[解析平台列表]\n    D --> E\n    E --> F{平台列表为空?}\n    F -->|是| G[使用 DEFAULT_PLATFORMS]\n    F -->|否| H[使用指定平台]\n    G --> I[遍历每个平台]\n    H --> I\n    I --> J[设置环境变量<br/>GOOS, GOARCH, CGO_ENABLED=0]\n    J --> K[go build 编译]\n    K --> L{编译成功?}\n    L -->|否| M[抛出 RuntimeError]\n    L -->|是| N[创建 wheel 目录结构]\n    N --> O[生成 __init__.py, __main__.py]\n    O --> P[生成 METADATA, WHEEL, entry_points.txt]\n    P --> Q[计算 RECORD 哈希]\n    Q --> R[压缩为 .whl 文件]\n    R --> S{还有更多平台?}\n    S -->|是| I\n    S -->|否| T[输出摘要]\n```\n\n资料来源：[spec.md:150-200](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### 编译命令构造\n\n```python\nenv = os.environ.copy()\nenv[\"GOOS\"] = goos\nenv[\"GOARCH\"] = goarch\nenv[\"CGO_ENABLED\"] = \"0\"\n\nldflags_value = \"-s -w\"\nif ldflags:\n    ldflags_value += \" \" + ldflags\n\ncmd = [\n    go_binary,\n    \"build\",\n    f\"-ldflags={ldflags_value}\",\n    \"-o\",\n    output_path,\n    \".\",\n]\n```\n\n关键编译参数说明：\n- `CGO_ENABLED=0`：禁用 C 绑定，确保生成静态二进制文件\n- `-ldflags=\"-s -w\"`：去除调试信息，减小二进制体积\n- Windows 平台自动添加 `.exe` 扩展名\n\n资料来源：[go_to_wheel/__init__.py:210-240](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 常见使用场景\n\n### 场景一：GitHub Actions CI/CD 集成\n\n```yaml\n- name: Build Python wheels\n  run: |\n    go-to-wheel ./cmd/mytool \\\n      --name mytool \\\n      --version ${{ github.ref_name }} \\\n      --set-version-var main.version \\\n      --author \"${{ github.event.sender.login }}\" \\\n      --url \"https://github.com/${{ github.repository }}\" \\\n      --readme README.md\n  env:\n    GO_BINARY: /usr/local/bin/go\n```\n\n### 场景二：多入口点包管理\n\n对于生成多个可执行文件的 Go 模块：\n\n```bash\n# 构建主工具\ngo-to-wheel ./cmd/cli --name mycli --entry-point mycli\n\n# 构建辅助工具\ngo-to-wheel ./cmd/helper --name mycli-helper --entry-point mycli-helper\n```\n\n### 场景三：自定义 Go 编译器路径\n\n```bash\n# 使用项目本地 Go 安装\ngo-to-wheel ./mytool --go-binary /opt/go/bin/go\n\n# 使用 Docker 容器内的 Go\ndocker run --rm -v $(pwd):/workspace golang:1.21 \\\n  go-to-wheel /workspace/mytool --go-binary go\n```\n\n### 场景四：musl 静态链接（Alpine Linux 兼容）\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64-musl,linux-arm64-musl\n```\n\n生成的 wheel 使用 `musllinux` 标签，适用于 Alpine Linux 等使用 musl libc 的发行版。\n\n---\n\n## 依赖与要求\n\n### 构建环境要求\n\n| 组件 | 最低版本 | 说明 |\n|------|----------|------|\n| Python | >= 3.10 | 运行时环境 |\n| Go | >= 1.16 | 编译目标代码 |\n\n### 工具本身依赖\n\n`go-to-wheel` 零外部 Python 依赖，完全使用标准库实现：\n\n- `argparse`：命令行参数解析\n- `csv`：RECORD 文件生成\n- `hashlib`：SHA256 哈希计算\n- `os`/`pathlib`：文件系统操作\n- `stat`：文件权限处理\n- `subprocess`：Go 编译调用\n- `zipfile`：wheel 打包\n\n资料来源：[spec.md:250-260](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n---\n\n## 故障排除\n\n### 常见错误及解决方案\n\n| 错误信息 | 原因 | 解决方案 |\n|----------|------|----------|\n| `FileNotFoundError: go directory not found` | 指定路径不存在 | 检查 `--name` 参数后的路径 |\n| `ValueError: Not a Go module` | 目录缺少 `go.mod` | 确保在 Go 模块根目录执行 |\n| `RuntimeError: Go compilation failed` | Go 编译错误 | 检查 Go 代码语法或 `CGO_ENABLED=0` 兼容性 |\n| `Error: No wheels were built` | 无有效目标平台 | 验证 `--platforms` 参数是否有效 |\n\n资料来源：[go_to_wheel/__init__.py:260-290](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 验证构建结果\n\n### 查看 wheel 内容\n\n```bash\n# 解压查看结构\nunzip -l dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n\n# 提取并检查二进制\nunzip -p dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl \\\n  mytool/bin/mytool | file -\n```\n\n### 测试安装\n\n```bash\n# 使用 uv 测试安装\nuv run --with ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl mytool --help\n\n# 使用 pip 安装\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n\n# 使用 pipx 安装（推荐用于命令行工具）\npipx install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n资料来源：[README.md:125-145](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n<a id='page-9'></a>\n\n## 开发环境搭建\n\n### 相关页面\n\n相关主题：[相关项目与参考](#page-10), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [pyproject.toml](https://github.com/simonw/go-to-wheel/blob/main/pyproject.toml)\n- [tests/test_cli.py](https://github.com/simonw/go-to-wheel/blob/main/tests/test_cli.py)\n</details>\n\n# 开发环境搭建\n\n## 概述\n\n`go-to-wheel` 是一个用于将 Go CLI 程序编译为 Python wheel 的工具。本页面详细介绍如何搭建该项目的开发环境，包括环境准备、源码获取、依赖安装以及测试验证等完整流程。\n\n该工具的核心功能是通过 Go 交叉编译生成多平台二进制文件，并将其打包为符合 PEP 427 规范的 Python wheel，实现通过 `pip` 或 `pipx` 分发 Go 程序的目的。资料来源：[README.md](https://github.com/simonw/go-to-wheel)\n\n## 前置条件\n\n### 系统要求\n\n| 组件 | 最低版本 | 说明 |\n|------|----------|------|\n| Python | >= 3.10 | 项目使用结构化模式匹配等新特性 |\n| Go | >= 1.16 | 支持 `go mod` 模块化构建 |\n| Git | 任意版本 | 用于克隆源码仓库 |\n\n### 环境检查\n\n在开始搭建开发环境前，请确保目标系统已安装上述必要组件。可以通过以下命令验证：\n\n```bash\n# 检查 Python 版本\npython --version\n\n# 检查 Go 版本\ngo version\n\n# 检查 Git 版本\ngit --version\n```\n\n## 获取源码\n\n### 克隆仓库\n\n使用 Git 将项目源码克隆到本地：\n\n```bash\ngit clone https://github.com/simonw/go-to-wheel\ncd go-to-wheel\n```\n\n克隆完成后，目录结构应包含以下核心文件和目录：\n\n```\ngo-to-wheel/\n├── go_to_wheel/          # 主模块目录\n│   └── __init__.py       # 核心功能实现\n├── tests/                # 测试目录\n│   └── test_cli.py       # CLI 测试用例\n├── README.md             # 项目说明文档\n├── SPEC.md               # 详细规格说明\n└── pyproject.toml        # 项目配置\n```\n\n资料来源：[README.md - Development](https://github.com/simonw/go-to-wheel)\n\n## 依赖管理\n\n### 项目配置\n\n项目使用 `pyproject.toml` 管理依赖和构建配置。核心依赖声明如下：\n\n```toml\n[project]\nrequires-python = \">=3.10\"\ndependencies = []\n```\n\n值得注意的是，`go-to-wheel` 本身不依赖任何外部 Python 包，仅使用 Python 标准库完成所有功能。资料来源：[spec.md - Dependencies](https://github.com/simonw/go-to-wheel)\n\n### 安装开发依赖\n\n推荐使用 `uv` 作为 Python 包管理工具。若未安装，可通过以下方式安装：\n\n```bash\n# 安装 uv\npip install uv\n```\n\n安装项目及其开发依赖：\n\n```bash\n# 使用 uv 安装项目为可编辑模式\nuv pip install -e .\n\n# 或直接使用 uv run 运行命令（无需预先安装）\nuv run pytest\n```\n\n## 项目结构解析\n\n### 核心模块\n\n`go_to_wheel/__init__.py` 是项目的主模块，包含以下关键组件：\n\n| 组件 | 功能 |\n|------|------|\n| `PLATFORM_MAPPINGS` | Go 平台标识到 wheel 平台标签的映射表 |\n| `DEFAULT_PLATFORMS` | 默认构建的所有目标平台列表 |\n| `build_wheels()` | 核心构建函数，生成 wheel 包 |\n| `generate_metadata()` | 生成 wheel METADATA 文件 |\n| `generate_wheel_file()` | 生成 WHEEL 规范文件 |\n| `generate_entry_points()` | 生成 entry_points.txt |\n| `generate_record()` | 生成 RECORD 文件 |\n\n资料来源：[go_to_wheel/__init__.py:1-50](https://github.com/simonw/go-to-wheel)\n\n### 平台支持矩阵\n\n项目默认支持以下 8 个目标平台：\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|----------|------|--------|------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:30-40](https://github.com/simonw/go-to-wheel)\n\n## 运行测试\n\n### 测试执行\n\n使用 `uv` 运行完整的测试套件：\n\n```bash\nuv run pytest\n```\n\n测试覆盖以下核心功能：\n\n- 命令行参数解析\n- Go 目录验证逻辑\n- wheel 包生成流程\n- 元数据文件生成\n- 多平台构建支持\n\n资料来源：[README.md - Development](https://github.com/simonw/go-to-wheel)\n\n### 本地构建验证\n\n搭建完成后，可通过以下命令验证工具是否正常工作：\n\n```bash\n# 查看帮助信息\ngo-to-wheel --help\n\n# 或使用 uv 运行\nuv run go-to-wheel --help\n```\n\n## 构建流程架构\n\n```mermaid\ngraph TD\n    A[输入 Go 模块目录] --> B[验证 go.mod 存在]\n    B --> C{检查平台列表}\n    C -->|未指定| D[使用默认平台]\n    C -->|指定平台| E[解析平台参数]\n    D --> F[交叉编译 Go 二进制]\n    E --> F\n    F --> G[创建临时目录结构]\n    G --> H[生成 Python 包装代码]\n    H --> I[生成元数据文件]\n    I --> J[计算 RECORD 哈希]\n    J --> K[打包为 wheel]\n    K --> L[输出到 dist 目录]\n```\n\n## CLI 参数配置\n\n项目通过 argparse 定义命令行接口，关键参数如下：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `--name` | 字符串 | 目录名 | Python 包名称 |\n| `--version` | 字符串 | 0.1.0 | 包版本号 |\n| `--output-dir` | 字符串 | ./dist | 输出目录 |\n| `--platforms` | 字符串 | 全部平台 | 目标平台列表 |\n| `--go-binary` | 字符串 | go | Go 二进制路径 |\n| `--ldflags` | 字符串 | None | 链接器标志 |\n\n资料来源：[go_to_wheel/__init__.py:100-150](https://github.com/simonw/go-to-wheel)\n\n## 常见问题\n\n### Go 未找到\n\n**问题**：运行时报错 `go: command not found`\n\n**解决**：确保 Go 已安装且添加到系统 PATH 环境变量中。验证方法：\n\n```bash\nwhich go\ngo version\n```\n\n### Python 版本不兼容\n\n**问题**：报 `SyntaxError` 或功能异常\n\n**解决**：项目要求 Python >= 3.10，请升级 Python 版本：\n\n```bash\npython --version  # 确认版本\n```\n\n### 构建失败\n\n**问题**：wheel 构建过程中出错\n\n**解决**：\n\n1. 确认 Go 模块目录包含 `go.mod` 文件\n2. 检查目标平台的 Go 工具链是否可用\n3. 使用 `--go-binary` 指定 Go 二进制路径\n\n资料来源：[spec.md - Package Name Validation](https://github.com/simonw/go-to-wheel)\n\n## 后续步骤\n\n开发环境搭建完成后，可进行以下操作：\n\n1. **构建示例 wheel**：尝试构建一个简单的 Go 工具\n\n   ```bash\n   go-to-wheel ./path/to/go-module\n   ```\n\n2. **本地安装测试**：安装生成的 wheel 并验证功能\n\n   ```bash\n   pip install ./dist/*.whl\n   ```\n\n3. **参与开发**：阅读 `SPEC.md` 了解项目详细规格，提交 Pull Request\n\n## 参考链接\n\n- [项目 GitHub 仓库](https://github.com/simonw/go-to-wheel)\n- [Python wheel 规范 (PEP 427)](https://peps.python.org/pep-0427/)\n- [Go 交叉编译文档](https://go.dev/wiki/WindowsCrossCompiling)\n\n---\n\n<a id='page-10'></a>\n\n## 相关项目与参考\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [系统架构](#page-2)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 相关项目与参考\n\n## 概述\n\n`go-to-wheel` 项目在设计和实现过程中参考了多个相关领域的开源项目和技术方案。理解这些相关项目有助于开发者把握该工具在生态系统中的定位，以及它与其他类似工具的关系和区别。\n\n本页面详细介绍 `go-to-wheel` 所参考的技术方案、灵感来源以及功能相似的替代工具，帮助用户根据具体场景选择合适的工具。\n\n## 灵感来源：maturin\n\n### 项目简介\n\n[maturin](https://github.com/PyO3/maturin) 是一个将 Rust 程序打包为 Python wheels 的工具，由 PyO3 团队开发和维护。它是目前 Rust 语言生态中最为成熟的「将原生语言程序转化为 Python 可分发包」解决方案。\n\n`go-to-wheel` 的设计理念直接受到了 maturin 的启发。正如 README.md 中所述：\n\n> maturin 是 Rust 的等效工具，启发了这个工具\n\n资料来源：[README.md:1]()\n\n### 核心功能对比\n\n| 特性 | maturin | go-to-wheel |\n|------|---------|-------------|\n| 源语言 | Rust | Go |\n| 绑定方式 | PyO3 绑定 + 直接 exec | 仅 exec 封装 |\n| 跨平台支持 | ✅ | ✅ |\n| CGO 支持 | 允许 | 禁用 (CGO_ENABLED=0) |\n| 依赖库 | PyO3, setuptools-rust | 仅标准库 |\n| 入口点类型 | console_scripts, pypi scripts | console_scripts |\n\n资料来源：[README.md:1](), [spec.md:1]()\n\n### 设计理念传承\n\nmaturin 的核心设计原则被 `go-to-wheel` 继承：\n\n1. **简化分发**：用户只需一条命令即可将原生程序转化为可通过 pip 安装的 wheel 包\n2. **跨平台兼容**：自动为多个目标平台编译二进制文件\n3. **最小依赖**：编译后的 wheel 包尽量减少运行时依赖\n4. **PEP 标准**：严格遵循 Python 打包规范 (PEP 427, PEP 566)\n\n资料来源：[spec.md:1]()\n\n## 模板项目：pip-binary-factory\n\n### 项目简介\n\n[pip-binary-factory](https://github.com/Bing-su/pip-binary-factory) 是一个用于打包预编译二进制文件的 Python 模板项目。它提供了将各种语言的预编译二进制文件封装为 PyPI 可分发包的参考实现。\n\nREADME.md 中将其描述为「用于打包预编译二进制文件的模板」：\n\n> pip-binary-factory - 用于打包预编译二进制文件的模板\n\n资料来源：[README.md:1]()\n\n### 与 go-to-wheel 的关系\n\n`go-to-wheel` 与 pip-binary-factory 解决的是不同层次的问题：\n\n```mermaid\ngraph TD\n    A[预编译二进制分发] --> B[pip-binary-factory]\n    A --> C[源代码编译分发]\n    C --> D[go-to-wheel]\n    B --> E[已有二进制文件]\n    D --> F[需要编译的 Go 源码]\n    \n    style B fill:#e1f5fe\n    style D fill:#fff3e0\n```\n\n| 维度 | pip-binary-factory | go-to-wheel |\n|------|-------------------|-------------|\n| 输入 | 预编译的二进制文件 | Go 源代码 |\n| 编译过程 | 无需编译 | 集成跨平台编译 |\n| 适用场景 | 已有二进制或第三方编译产物 | 需要从源码构建的场景 |\n| 工作流程 | 模板填充 + 打包 | 编译 + 打包一体化 |\n\n资料来源：[README.md:1]()\n\n## 技术背景：Python 打包生态\n\n### 相关 PEP 标准\n\n`go-to-wheel` 严格遵循以下 Python 打包标准：\n\n```mermaid\ngraph LR\n    A[go-to-wheel] --> B[PEP 427]\n    A --> C[PEP 376]\n    A --> D[PEP 566]\n    \n    B --> E[Wheel 格式规范]\n    C --> F[RECORD 文件规范]\n    D --> G[元数据格式]\n```\n\n| PEP 编号 | 名称 | go-to-wheel 实现 |\n|----------|------|------------------|\n| PEP 427 | Wheel Binary Package Format | 生成符合规范的 .whl 文件 |\n| PEP 376 | Database of Installed Python Distributions | 实现 RECORD 文件和 dist-info 目录 |\n| PEP 566 | Metadata Version 2.1 | 生成符合 2.1 版本的 METADATA |\n\n资料来源：[spec.md:1](), [go_to_wheel/__init__.py:1]()\n\n### 核心元数据文件\n\n`go-to-wheel` 生成的 wheel 包包含以下标准文件：\n\n```\n{package_name}-{version}.dist-info/\n├── METADATA        # 包元数据 (PEP 566)\n├── WHEEL           # Wheel 标记 (PEP 427)\n├── RECORD          # 文件哈希记录 (PEP 376)\n└── entry_points.txt  # 入口点定义\n```\n\n资料来源：[spec.md:1]()\n\n## 替代工具方案\n\n### 现有方案对比\n\n在 Go 程序 Python 分发领域，存在以下几种替代方案：\n\n| 方案 | 优点 | 缺点 |\n|------|------|------|\n| 手动编译 + pip install | 完全可控 | 需用户配置 Go 环境 |\n| Docker 镜像分发 | 隔离性好 | 部署复杂，不符合 Python 生态习惯 |\n| go-to-wheel | 一站式解决方案 | 仅支持 Go 语言 |\n| 预编译 wheels | 用户无编译等待 | 维护成本高 |\n\n资料来源：[README.md:1]()\n\n### go-to-wheel 的独特价值\n\n`go-to-wheel` 填补了 Go 生态在 Python 打包领域的关键空白：\n\n```mermaid\ngraph TD\n    A[Go 开发者] --> B{如何分发 CLI 工具?}\n    B --> C[手动编译]\n    B --> D[Docker]\n    B --> E[go-to-wheel]\n    \n    C --> F[用户体验差]\n    D --> G[不符合 Python 习惯]\n    E --> H[✅ Python 原生分发]\n    \n    style E fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n## 参考文献\n\n### 相关链接\n\n| 项目 | 仓库地址 | 说明 |\n|------|----------|------|\n| maturin | https://github.com/PyO3/maturin | Rust 程序的 Python wheel 打包工具 |\n| pip-binary-factory | https://github.com/Bing-su/pip-binary-factory | 预编译二进制打包模板 |\n\n### 延伸阅读\n\n- [Distributing Go binaries like sqlite-scanner through PyPI using go-to-wheel](https://simonwillison.net/2026/Feb/4/distributing-go-binaries/) - 项目作者关于 go-to-wheel 设计背景的博客文章\n\n资料来源：[README.md:1]()\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：simonw/go-to-wheel\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | release_recency=unknown\n\n<!-- canonical_name: simonw/go-to-wheel; human_manual_source: deepwiki_human_wiki -->\n",
      "markdown_key": "go-to-wheel",
      "pages": "draft",
      "source_refs": [
        {
          "evidence_id": "hn_item:48109677",
          "kind": "hn",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://news.ycombinator.com/item?id=48109677"
        },
        {
          "evidence_id": "art_0ebc1ca4318444e4a3baf98f272af635",
          "kind": "docs",
          "supports_claim_ids": [
            "claim_identity",
            "claim_distribution",
            "claim_capability"
          ],
          "url": "https://github.com/simonw/go-to-wheel#readme"
        }
      ],
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "go-to-wheel 说明书",
      "toc": [
        "https://github.com/simonw/go-to-wheel 项目说明书",
        "目录",
        "项目简介",
        "项目概述",
        "核心功能特性",
        "工作流程",
        "Wheel 包结构",
        "命令行接口",
        "Doramagic 踩坑日志"
      ]
    }
  },
  "quality_gate": {
    "blocking_gaps": [],
    "category_confidence": "medium",
    "compile_status": "ready_for_review",
    "five_assets_present": true,
    "install_sandbox_verified": true,
    "missing_evidence": [],
    "next_action": "publish to Doramagic.ai project surfaces",
    "prompt_preview_boundary_ok": true,
    "publish_status": "publishable",
    "quick_start_verified": true,
    "repo_clone_verified": true,
    "repo_commit": "eb9c343a6bd3c4da4c7bcb4a6106c8fd67cc10a8",
    "repo_inspection_error": null,
    "repo_inspection_files": [
      "pyproject.toml",
      "README.md"
    ],
    "repo_inspection_verified": true,
    "review_reasons": [
      "community_discussion_evidence_below_public_threshold"
    ],
    "tag_count_ok": true,
    "unsupported_claims": []
  },
  "schema_version": "0.1",
  "user_assets": {
    "ai_context_pack": {
      "asset_id": "ai_context_pack",
      "filename": "AI_CONTEXT_PACK.md",
      "markdown": "# go-to-wheel - Doramagic AI Context Pack\n\n> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。\n\n## 充分原则\n\n- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。\n- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。\n\n## 给宿主 AI 的使用方式\n\n你正在读取 Doramagic 为 go-to-wheel 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。\n\n## Claim 消费规则\n\n- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。\n- **事实最低状态**：`supported`\n- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。\n- `weak`：只能作为低置信度线索，必须要求用户继续核实。\n- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。\n- `unverified`：不得作为事实使用，应明确说证据不足。\n- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。\n\n## 它最适合谁\n\n- **想在安装前理解开源项目价值和边界的用户**：当前证据主要来自项目文档。 证据：`README.md` Claim：`clm_0002` supported 0.86\n\n## 它能做什么\n\n- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n## 怎么开始\n\n- `pip install go-to-wheel` 证据：`README.md` Claim：`clm_0003` supported 0.86\n- `pipx install go-to-wheel` 证据：`README.md` Claim：`clm_0004` supported 0.86\n- `pip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl` 证据：`README.md` Claim：`clm_0005` supported 0.86\n- `git clone https://github.com/simonw/go-to-wheel` 证据：`README.md` Claim：`clm_0006` supported 0.86\n\n## 继续前判断卡\n\n- **当前建议**：仅建议沙盒试装\n- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。\n\n### 30 秒判断\n\n- **现在怎么做**：仅建议沙盒试装\n- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装\n- **先别相信**：真实输出质量不能在安装前相信。\n- **继续会触碰**：命令执行、本地环境或项目文件、宿主 AI 上下文\n\n### 现在可以相信\n\n- **适合人群线索：想在安装前理解开源项目价值和边界的用户**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86\n- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86\n\n### 现在还不能相信\n\n- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。\n- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。\n- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。\n- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。\n- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。\n- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。\n- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`\n\n### 继续会触碰什么\n\n- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`\n- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`\n- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。\n\n### 最小安全下一步\n\n- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）\n- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）\n- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）\n\n### 退出方式\n\n- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。\n- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。\n- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。\n\n## 哪些只能预览\n\n- 解释项目适合谁和能做什么\n- 基于项目文档演示典型对话流程\n- 帮助用户判断是否值得安装或继续研究\n\n## 哪些必须安装后验证\n\n- 真实安装 Skill、插件或 CLI\n- 执行脚本、修改本地文件或访问外部服务\n- 验证真实输出质量、性能和兼容性\n\n## 边界与风险判断卡\n\n- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0007` inferred 0.45\n- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0008` supported 0.86\n- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。\n- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。\n- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。\n\n## 开工前工作上下文\n\n### 加载顺序\n\n- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。\n- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。\n- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。\n- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。\n- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。\n\n### 任务路由\n\n- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86\n\n### 上下文规模\n\n- 文件总数：14\n- 重要文件覆盖：7/14\n- 证据索引条目：6\n- 角色 / Skill 条目：2\n\n### 证据不足时的处理\n\n- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。\n- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。\n- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。\n- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。\n\n## Prompt Recipes\n\n### 适配判断\n\n- 目标：判断这个项目是否适合用户当前任务。\n- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。\n\n```text\n请基于 go-to-wheel 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。\n```\n\n### 安装前体验\n\n- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。\n- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。\n\n```text\n请把 go-to-wheel 当作安装前体验资产，而不是已安装工具或真实运行环境。\n\n请严格输出四段：\n1. 先问我 3 个必要问题。\n2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。\n3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。\n4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。\n\n硬性边界：\n- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。\n- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。\n- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。\n- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。\n- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。\n- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。\n\n```\n\n### 角色 / Skill 选择\n\n- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。\n- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。\n\n```text\n请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。\n```\n\n### 风险预检\n\n- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。\n- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。\n\n```text\n请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。\n```\n\n### 宿主 AI 开工指令\n\n- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。\n- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。\n\n```text\n请基于 go-to-wheel 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。\n```\n\n\n## 角色 / Skill 索引\n\n- 共索引 2 个角色 / Skill / 项目文档条目。\n\n- **go-to-wheel**（project_doc）：! PyPI https://img.shields.io/pypi/v/go-to-wheel.svg https://pypi.org/project/go-to-wheel/ ! Changelog https://img.shields.io/github/v/release/simonw/go-to-wheel?include prereleases&label=changelog https://github.com/simonw/go-to-wheel/releases ! Tests https://github.com/simonw/go-to-wheel/workflows/Test/badge.svg https://github.com/simonw/go-to-wheel/actions?query=workflow%3ATest ! License https://img.shields.io/ba… 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`\n- **go-to-wheel Specification**（project_doc）：A Python tool that compiles Go CLI programs for multiple architectures and bundles each as a Python wheel with executable entry points. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`spec.md`\n\n## 证据索引\n\n- 共索引 6 条证据。\n\n- **go-to-wheel**（documentation）：! PyPI https://img.shields.io/pypi/v/go-to-wheel.svg https://pypi.org/project/go-to-wheel/ ! Changelog https://img.shields.io/github/v/release/simonw/go-to-wheel?include prereleases&label=changelog https://github.com/simonw/go-to-wheel/releases ! Tests https://github.com/simonw/go-to-wheel/workflows/Test/badge.svg https://github.com/simonw/go-to-wheel/actions?query=workflow%3ATest ! License https://img.shields.io/badge/license-Apache%202.0-blue.svg https://github.com/simonw/go-to-wheel/blob/main/LICENSE 证据：`README.md`\n- **License**（source_file）：Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ 证据：`LICENSE`\n- **go-to-wheel Specification**（documentation）：A Python tool that compiles Go CLI programs for multiple architectures and bundles each as a Python wheel with executable entry points. 证据：`spec.md`\n- **.gitignore**（source_file）：.python-version uv.lock pycache / .pyc .pytest cache/ .venv/ dist/ .egg-info/ 证据：`.gitignore`\n- **Platform mappings: goos, goarch - wheel platform tag**（source_file）：\"\"\"go-to-wheel: Compile Go CLI programs into Python wheels.\"\"\" 证据：`go_to_wheel/__init__.py`\n- **Pyproject**（source_file）：project name = \"go-to-wheel\" version = \"0.2\" description = \"Compile Go CLI programs into Python wheels\" readme = \"README.md\" requires-python = \" =3.10\" license = \"Apache-2.0\" authors = { name = \"Simon Willison\" } dependencies = 证据：`pyproject.toml`\n\n## 宿主 AI 必须遵守的规则\n\n- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `LICENSE`, `spec.md`\n- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `LICENSE`, `spec.md`\n\n## 用户开工前应该回答的问题\n\n- 你准备在哪个宿主 AI 或本地环境中使用它？\n- 你只是想先体验工作流，还是准备真实安装？\n- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？\n\n## 验收标准\n\n- 所有能力声明都能回指到 evidence_refs 中的文件路径。\n- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。\n- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。\n\n---\n\n## Doramagic Context Augmentation\n\n下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。\n\n## Human Manual 骨架\n\n使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。\n\n宿主 AI 硬性规则：\n- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。\n- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。\n- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。\n\n- **项目简介**：importance `high`\n  - source_paths: README.md, spec.md\n- **系统架构**：importance `high`\n  - source_paths: go_to_wheel/__init__.py\n- **支持的平台**：importance `high`\n  - source_paths: go_to_wheel/__init__.py\n- **元数据配置**：importance `medium`\n  - source_paths: go_to_wheel/__init__.py\n- **Go 交叉编译流程**：importance `high`\n  - source_paths: go_to_wheel/__init__.py\n- **Wheel 生成机制**：importance `high`\n  - source_paths: go_to_wheel/__init__.py\n- **快速开始**：importance `high`\n  - source_paths: README.md, pyproject.toml\n- **高级用法与示例**：importance `medium`\n  - source_paths: README.md\n\n## Repo Inspection Evidence / 源码检查证据\n\n- repo_clone_verified: true\n- repo_inspection_verified: true\n- repo_commit: `eb9c343a6bd3c4da4c7bcb4a6106c8fd67cc10a8`\n- inspected_files: `pyproject.toml`, `README.md`\n\n宿主 AI 硬性规则：\n- 没有 repo_clone_verified=true 时，不得声称已经读过源码。\n- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。\n- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。\n\n## Doramagic Pitfall Constraints / 踩坑约束\n\n这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。\n\n### Constraint 1: 能力判断依赖假设\n\n- Trigger: README/documentation is current enough for a first validation pass.\n- Host AI rule: 将假设转成下游验证清单。\n- Why it matters: 假设不成立时，用户拿不到承诺的能力。\n- Evidence: capability.assumptions | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | README/documentation is current enough for a first validation pass.\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 2: 维护活跃度未知\n\n- Trigger: 未记录 last_activity_observed。\n- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。\n- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- Evidence: evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | last_activity_observed missing\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 3: 下游验证发现风险项\n\n- Trigger: no_demo\n- Host AI rule: 进入安全/权限治理复核队列。\n- Why it matters: 下游已经要求复核，不能在页面中弱化。\n- Evidence: downstream_validation.risk_items | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 4: 存在评分风险\n\n- Trigger: no_demo\n- Host AI rule: 把风险写入边界卡，并确认是否需要人工复核。\n- Why it matters: 风险会影响是否适合普通用户安装。\n- Evidence: risks.scoring_risks | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 5: issue/PR 响应质量未知\n\n- Trigger: issue_or_pr_quality=unknown。\n- Host AI rule: 抽样最近 issue/PR，判断是否长期无人处理。\n- Why it matters: 用户无法判断遇到问题后是否有人维护。\n- Evidence: evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | issue_or_pr_quality=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n\n### Constraint 6: 发布节奏不明确\n\n- Trigger: release_recency=unknown。\n- Host AI rule: 确认最近 release/tag 和 README 安装命令是否一致。\n- Why it matters: 安装命令和文档可能落后于代码，用户踩坑概率升高。\n- Evidence: evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | release_recency=unknown\n- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。\n",
      "summary": "给宿主 AI 的上下文和工作边界。",
      "title": "AI Context Pack / 带给我的 AI"
    },
    "boundary_risk_card": {
      "asset_id": "boundary_risk_card",
      "filename": "BOUNDARY_RISK_CARD.md",
      "markdown": "# Boundary & Risk Card / 安装前决策卡\n\n项目：simonw/go-to-wheel\n\n## Doramagic 试用结论\n\n当前结论：可以进入发布前推荐检查；首次使用仍应从最小权限、临时目录和可回滚配置开始。\n\n## 用户现在可以做\n\n- 可以先阅读 Human Manual，理解项目目的和主要工作流。\n- 可以复制 Prompt Preview 做安装前体验；这只验证交互感，不代表真实运行。\n- 可以把官方 Quick Start 命令放到隔离环境中验证，不要直接进主力环境。\n\n## 现在不要做\n\n- 不要把 Prompt Preview 当成项目实际运行结果。\n- 不要把 metadata-only validation 当成沙箱安装验证。\n- 不要把未验证能力写成“已支持、已跑通、可放心安装”。\n- 不要在首次试用时交出生产数据、私人文件、真实密钥或主力配置目录。\n\n## 安装前检查\n\n- 宿主 AI 是否匹配：local_cli\n- 官方安装入口状态：已发现官方入口\n- 是否在临时目录、临时宿主或容器中验证：必须是\n- 是否能回滚配置改动：必须能\n- 是否需要 API Key、网络访问、读写文件或修改宿主配置：未确认前按高风险处理\n- 是否记录了安装命令、实际输出和失败日志：必须记录\n\n## 当前阻塞项\n\n- review_required: community_discussion_evidence_below_public_threshold\n\n## 项目专属踩坑\n\n- 能力判断依赖假设（medium）：假设不成立时，用户拿不到承诺的能力。 建议检查：将假设转成下游验证清单。\n- 维护活跃度未知（medium）：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 下游验证发现风险项（medium）：下游已经要求复核，不能在页面中弱化。 建议检查：进入安全/权限治理复核队列。\n- 存在评分风险（medium）：风险会影响是否适合普通用户安装。 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- issue/PR 响应质量未知（low）：用户无法判断遇到问题后是否有人维护。 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n\n## 风险与权限提示\n\n- no_demo: medium\n\n## 证据缺口\n\n- 暂未发现结构化证据缺口。\n",
      "summary": "安装、权限、验证和推荐前风险。",
      "title": "Boundary & Risk Card / 边界与风险卡"
    },
    "human_manual": {
      "asset_id": "human_manual",
      "filename": "HUMAN_MANUAL.md",
      "markdown": "# https://github.com/simonw/go-to-wheel 项目说明书\n\n生成时间：2026-05-14 22:44:46 UTC\n\n## 目录\n\n- [项目简介](#page-1)\n- [系统架构](#page-2)\n- [支持的平台](#page-3)\n- [元数据配置](#page-4)\n- [Go 交叉编译流程](#page-5)\n- [Wheel 生成机制](#page-6)\n- [快速开始](#page-7)\n- [高级用法与示例](#page-8)\n- [开发环境搭建](#page-9)\n- [相关项目与参考](#page-10)\n\n<a id='page-1'></a>\n\n## 项目简介\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 项目简介\n\n## 项目概述\n\n`go-to-wheel` 是一个将 Go 语言命令行程序编译为 Python wheel 包的工具。该工具填补了 Go/Python 生态系统中的一个空白——在 Rust 生态中有 `maturin --bindings bin` 这样的工具，但 Go 生态此前缺乏类似的便捷方案。\n\n项目的主要目标是将 Go 模块目录作为输入，跨平台编译生成多个架构的可执行文件，并将每个编译结果打包成带有正确平台标签的 Python wheel 包，从而可以通过 `pip` 或 `pipx` 进行安装，使 Go 二进制程序直接出现在系统 PATH 中。\n\n资料来源：[README.md:1-10]()\n\n## 核心功能特性\n\n### 多平台交叉编译\n\n`go-to-wheel` 支持一次性为多个目标平台构建 Go 二进制文件，默认涵盖以下平台：\n\n| 平台标识 | GOOS | GOARCH | Wheel 平台标签 |\n|---------|------|--------|---------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:26-33]()\n\n### 静态二进制编译\n\n项目使用 `CGO_ENABLED=0` 环境变量确保生成的 Go 二进制文件为静态链接形式，这避免了不同系统 libc 版本之间的兼容性问题。\n\n编译时默认使用 `-ldflags=\"-s -w\"` 链接标志，用于剥离调试信息以减小二进制文件体积。\n\n资料来源：[spec.md:80-90]()\n\n### Python 包装器机制\n\n生成的 wheel 包不直接将二进制文件放入 `.data/scripts/` 目录，而是采用 Python 包装器模式。`__init__.py` 文件提供了 `main()` 函数，通过 `console_scripts` 入口点调用该函数。\n\n这种设计有以下优势：\n\n- **跨平台一致性**：在所有平台上行为一致\n- **更好的错误提示**：当二进制文件缺失或不兼容时能提供友好的错误信息\n- **未来扩展性**：可以添加 Python 端的特性，如版本检查、更新通知等\n- **pipx 兼容性**：与 `pipx install` 无缝配合工作\n\n资料来源：[spec.md:60-75]()\n\n## 工作流程\n\n`go-to-wheel` 的完整工作流程如下：\n\n```mermaid\ngraph TD\n    A[输入 Go 模块目录] --> B[验证输入]\n    B --> C{go.mod 存在?}\n    C -->|是| D[跨平台编译 Go 二进制]\n    C -->|否| E[抛出错误: 非 Go 模块]\n    D --> F[为每个平台创建 wheel]\n    F --> G[生成 METADATA]\n    G --> H[生成 WHEEL]\n    H --> I[生成 entry_points.txt]\n    I --> J[生成 RECORD]\n    J --> K[打包为 .whl 文件]\n    K --> L[输出到目标目录]\n```\n\n### 详细构建步骤\n\n**步骤一：输入验证**\n\n1. 验证 Go 目录存在\n2. 验证目录包含 `go.mod` 文件（确认为 Go 模块）\n3. 验证 Go 已安装且可访问\n4. 从目录名或 `--name` 选项解析包名\n\n资料来源：[spec.md:95-105]()\n\n**步骤二：跨平台编译**\n\n对于每个目标平台，执行以下编译命令：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md:110-120]()\n\n**步骤三：构建 Wheel 包**\n\n对于每个编译好的二进制文件：\n\n1. 创建临时目录结构\n2. 将二进制文件复制到 `{package_name}/bin/` 目录\n3. 生成 `__init__.py` 和 `__main__.py`\n4. 生成 `METADATA`、`WHEEL` 和 `entry_points.txt`\n5. 计算 `RECORD` 中的 SHA256 哈希值\n6. 打包为带有正确文件名的 wheel 文件\n\n资料来源：[spec.md:122-135]()\n\n**步骤四：输出**\n\n1. 将 wheel 文件移动到输出目录\n2. 打印已构建 wheel 的摘要信息\n3. 返回成功/失败状态\n\n资料来源：[spec.md:137-142]()\n\n## Wheel 包结构\n\n生成的 wheel 包遵循 PEP 427 格式，目录结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md:35-55]()\n\n### METADATA 文件格式\n\n```\nMetadata-Version: 2.1\nName: {package_name}\nVersion: {version}\nSummary: {description}\nLicense: {license}\nAuthor: {author}\nAuthor-email: {author_email}\nHome-page: {url}\nRequires-Python: {requires_python}\n```\n\n资料来源：[spec.md:145-158]()\n\n### WHEEL 文件格式\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel {go_to_wheel_version}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n```\n\n资料来源：[spec.md:160-167]()\n\n## 命令行接口\n\n### 基本用法\n\n```bash\ngo-to-wheel path/to/go-folder\n```\n\n### 命令行选项\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--name NAME` | Python 包名称 | 目录 basename |\n| `--version VERSION` | 包版本号 | 0.1.0 |\n| `--output-dir DIR` | wheel 输出目录 | ./dist |\n| `--entry-point NAME` | CLI 命令名称 | 与包名称相同 |\n| `--platforms PLATFORMS` | 目标平台列表（逗号分隔） | 所有支持的平台 |\n| `--go-binary PATH` | Go 二进制文件路径 | go |\n| `--description TEXT` | 包描述 | \"Go binary packaged as Python wheel\" |\n| `--requires-python VERSION` | Python 版本要求 | >=3.10 |\n| `--license LICENSE` | 许可证标识符 | None |\n| `--author AUTHOR` | 作者姓名 | None |\n| `--author-email EMAIL` | 作者邮箱 | None |\n| `--url URL` | 项目主页 | None |\n| `--readme PATH` | README markdown 文件路径 | None |\n| `--ldflags FLAGS` | 额外的 Go 链接器标志 | None |\n| `--set-version-var VAR` | 通过 -X 设置版本的 Go 变量 | None |\n\n资料来源：[README.md:50-75]()\n\n### 使用示例\n\n**基础用法：**\n\n```bash\ngo-to-wheel ./mytool\n```\n\n**指定包名称：**\n\n```bash\ngo-to-wheel ./mytool --name my-python-tool\n```\n\n**仅构建特定平台：**\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n**嵌入版本信息到 Go 二进制：**\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n这会将 `-X main.version=2.0.0` 传递给 Go 链接器，使编译后的二进制文件能获知自身版本号，而无需在 Go 源代码中硬编码。\n\n资料来源：[README.md:76-95]()\n\n**完整 PyPI 元数据：**\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\"\n```\n\n## 依赖要求\n\n`go-to-wheel` 工具本身仅需以下依赖：\n\n| 依赖 | 版本要求 | 说明 |\n|------|---------|------|\n| Python | >= 3.10 | 工具运行时环境 |\n| Go | >= 1.16 | 用于 `go mod` 支持的构建环境 |\n\n项目使用 Python 标准库实现，不依赖任何外部 Python 包。\n\n资料来源：[spec.md:215-225]()\n\n## 安装方式\n\n```bash\npip install go-to-wheel\n# 或\npipx install go-to-wheel\n```\n\n安装后需要确保 Go 已安装且位于系统 PATH 中。\n\n资料来源：[README.md:28-35]()\n\n## 输出示例\n\n```\n$ go-to-wheel ./myapp --name myapp-bin\ngo-to-wheel v0.1.0\nBuilding from ./myapp\n\nBuilding for linux-amd64... done\nBuilding for linux-arm64... done\nBuilding for linux-amd64-musl... done\nBuilding for linux-arm64-musl... done\nBuilding for darwin-amd64... done\nBuilding for darwin-arm64... done\nBuilding for windows-amd64... done\nBuilding for windows-arm64... done\n\nBuilt 8 wheel(s):\n  ./dist/myapp-bin-0.1.0-py3-none-manylinux_2_17_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-manylinux_2_17_aarch64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-musllinux_1_2_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-musllinux_1_2_aarch64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-macosx_10_9_x86_64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-macosx_11_0_arm64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-win_amd64.whl\n  ./dist/myapp-bin-0.1.0-py3-none-win_arm64.whl\n```\n\n## 相关项目\n\n`go-to-wheel` 的设计灵感来源于 Rust 生态中的类似工具：\n\n- **[maturin](https://github.com/PyO3/maturin)** - Rust 等效工具，为 `go-to-wheel` 提供了设计参考\n- **[pip-binary-factory](https://github.com/Bing-su/pip-binary-factory)** - 预编译二进制打包模板\n\n资料来源：[README.md:130-135]()\n\n## 包名称验证规则\n\n项目对包名称有以下验证要求：\n\n| 验证项 | 处理方式 |\n|--------|---------|\n| 大小写问题 | 自动转换为小写 |\n| 首字符非字母/数字 | 报错退出 |\n| PEP 503 违规 | 报错退出，说明命名规则 |\n\n包名称必须符合 PEP 503 规范：\n\n- 仅使用小写字母、数字、连字符、下划线和句点\n- 必须以字母或数字开头\n\n导入名称（用于 Python 包目录）遵循 PEP 8 规范，将连字符替换为下划线。\n\n资料来源：[spec.md:195-210]()\n\n---\n\n<a id='page-2'></a>\n\n## 系统架构\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [Go 交叉编译流程](#page-5), [Wheel 生成机制](#page-6)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 系统架构\n\ngo-to-wheel 是一个将 Go CLI 程序编译为 Python wheel 包的工具。其核心设计围绕三个主要阶段：命令行解析与验证、跨平台编译、以及 wheel 包生成。资料来源：[go_to_wheel/__init__.py:1-50]()\n\n## 整体架构概述\n\ngo-to-wheel 采用模块化设计，核心逻辑集中于单一 Python 文件中，无需外部依赖即可完成全部功能。工具通过以下流程将 Go 模块转换为可分发的 Python wheel：\n\n```mermaid\ngraph TD\n    A[Go 模块目录] --> B[输入验证]\n    B --> C{遍历目标平台}\n    C -->|每个平台| D[跨平台编译 Go 二进制]\n    D --> E[创建 wheel 目录结构]\n    E --> F[生成 Python 包装器]\n    F --> G[生成 wheel 元数据]\n    G --> H[打包为 .whl 文件]\n    H --> I[输出到目标目录]\n    C -->|所有平台完成| I\n```\n\n资料来源：[README.md]()\n\n## 核心组件\n\n### 平台映射系统\n\n平台映射系统定义了 Go 目标平台与 Python wheel 平台标签之间的对应关系。该映射存储在 `PLATFORM_MAPPINGS` 字典中，支持 8 种目标平台配置。\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | linux | amd64 | manylinux_2_17_x86_64 |\n| `linux-arm64` | linux | arm64 | manylinux_2_17_aarch64 |\n| `linux-amd64-musl` | linux | amd64 | musllinux_1_2_x86_64 |\n| `linux-arm64-musl` | linux | arm64 | musllinux_1_2_aarch64 |\n| `darwin-amd64` | darwin | amd64 | macosx_10_9_x86_64 |\n| `darwin-arm64` | darwin | arm64 | macosx_11_0_arm64 |\n| `windows-amd64` | windows | amd64 | win_amd64 |\n| `windows-arm64` | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:20-27]()\n\n### 默认平台列表\n\n`DEFAULT_PLATFORMS` 列表定义了工具的默认构建目标，包含所有 8 种平台配置：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:29-36]()\n\n## 构建流程详解\n\n### 阶段一：输入验证与准备\n\n`build_wheels()` 函数是核心构建入口，负责执行以下验证步骤：\n\n1. **路径验证**：确认 Go 模块目录存在\n2. **模块验证**：检查 `go.mod` 文件是否存在于目录中\n3. **README 处理**：如果指定了 README 文件，则读取其内容作为 PyPI 长描述\n4. **默认值设置**：当未指定包名时，使用目录名作为包名\n\n```python\ngo_path = Path(go_dir).resolve()\n\nif not go_path.exists():\n    raise FileNotFoundError(f\"Go directory not found: {go_dir}\")\n\nif not (go_path / \"go.mod\").exists():\n    raise ValueError(f\"Not a Go module: {go_dir} (no go.mod file found)\")\n```\n\n资料来源：[go_to_wheel/__init__.py:112-120]()\n\n### 阶段二：跨平台编译\n\n对于每个目标平台，工具通过设置环境变量执行 Go 交叉编译：\n\n```mermaid\ngraph LR\n    A[设置 GOOS] --> B[设置 GOARCH]\n    B --> C[CGO_ENABLED=0]\n    C --> D[go build -ldflags]\n    D --> E[输出二进制文件]\n```\n\n编译参数配置：\n- `CGO_ENABLED=0`：禁用 C 互操作，确保生成静态二进制文件\n- `-ldflags=\"-s -w\"`：剥离调试信息以减小二进制体积\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md]()\n\n### 阶段三：Wheel 包结构生成\n\n生成符合 PEP 427 和 PEP 376 标准的 wheel 包结构：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md]()\n\n### 阶段四：元数据生成\n\n工具包含四个核心元数据生成函数：\n\n| 函数名 | 用途 | 输出文件 |\n|-------|------|---------|\n| `generate_metadata()` | 生成 PyPI 元数据 | METADATA |\n| `generate_wheel_metadata()` | 生成 wheel 规范 | WHEEL |\n| `generate_entry_points()` | 定义控制台入口点 | entry_points.txt |\n| `generate_record()` | 记录文件校验和 | RECORD |\n\n资料来源：[go_to_wheel/__init__.py:85-115]()\n\n### 阶段五：打包与输出\n\n使用 Python 标准库 `zipfile` 模块将目录结构打包为 `.whl` 文件：\n\n```python\nwith zipfile.ZipFile(wheel_path, \"w\", zipfile.ZIP_DEFLATED) as whl:\n    for file_path, content in files.items():\n        if \"/bin/\" in file_path:\n            info = zipfile.ZipInfo(file_path)\n            info.external_attr = (stat.S_IRWXU | stat.S_IRGRP | \n                                  stat.S_IXGRP | stat.S_IROTH | \n                                  stat.S_IXOTH) << 16\n            whl.writestr(info, content)\n        else:\n            whl.writestr(file_path, content)\n```\n\n对于二进制文件，设置可执行权限（Unix 模式 0755）；其他文件使用默认权限。\n\n资料来源：[go_to_wheel/__init__.py:175-185]()\n\n## Python 包装器机制\n\n### `__init__.py` 包装逻辑\n\n生成的 `__init__.py` 文件包含两个关键函数：\n\n```python\ndef get_binary_path():\n    \"\"\"Return the path to the bundled binary.\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # On Windows, use subprocess to properly handle signals\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # On Unix, exec replaces the process\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n- Windows 平台使用 `subprocess.call()` 处理信号\n- Unix 平台使用 `os.execvp()` 替换进程，实现零开销调用\n\n资料来源：[spec.md]()\n\n### 入口点机制\n\n通过 `entry_points.txt` 定义控制台脚本入口：\n\n```\n[console_scripts]\n{entry_point} = {package_name}:main\n```\n\n这种设计确保：\n- 跨平台一致性行为\n- pipx 兼容性\n- 可扩展性（未来可添加版本检查等 Python 端功能）\n\n资料来源：[spec.md]()\n\n## 命令行接口设计\n\n```mermaid\ngraph TD\n    A[go-to-wheel CLI] --> B[argparse 解析器]\n    B --> C[验证 Go 模块]\n    C --> D[调用 build_wheels]\n    D --> E{遍历平台}\n    E -->|每个平台| F[编译 Go 二进制]\n    F --> G[生成 wheel]\n    E -->|完成| H[输出结果摘要]\n```\n\n### 支持的命令行选项\n\n| 选项 | 类型 | 默认值 | 说明 |\n|-----|------|--------|------|\n| `--name` | 字符串 | 目录名 | Python 包名称 |\n| `--version` | 字符串 | 0.1.0 | 包版本号 |\n| `--output-dir` | 字符串 | ./dist | 输出目录 |\n| `--entry-point` | 字符串 | 同包名 | CLI 命令名称 |\n| `--platforms` | 列表 | 全部平台 | 目标平台列表 |\n| `--go-binary` | 字符串 | go | Go 二进制路径 |\n| `--description` | 字符串 | 见源码 | 包描述 |\n| `--requires-python` | 字符串 | >=3.10 | Python 版本要求 |\n| `--ldflags` | 字符串 | None | 额外链接器标志 |\n| `--set-version-var` | 字符串 | None | Go 版本变量 |\n\n资料来源：[go_to_wheel/__init__.py:50-130]()\n\n## 依赖关系\n\n```mermaid\ngraph TD\n    A[go-to-wheel] --> B[Python 标准库]\n    B --> C[argparse]\n    B --> D[zipfile]\n    B --> E[csv]\n    B --> F[hashlib]\n    B --> G[subprocess]\n    B --> H[pathlib]\n```\n\n工具本身不依赖任何外部 Python 包，仅使用标准库完成全部功能。\n\n| 依赖模块 | 用途 |\n|---------|------|\n| argparse | 命令行参数解析 |\n| zipfile | 创建 wheel 压缩包 |\n| csv | 生成 RECORD 文件 |\n| hashlib | 计算文件 SHA256 校验和 |\n| subprocess | 执行 Go 编译命令 |\n| pathlib | 路径操作 |\n\n资料来源：[go_to_wheel/__init__.py:1-20]()\n\n## 设计决策\n\n### 纯 Python 包装器 vs .data/scripts\n\n工具选择使用 Python 包装器（`console_scripts` 入口点）而非直接将二进制文件放入 `.data/scripts/`，原因如下：\n\n1. **一致性**：跨平台行为统一\n2. **错误处理**：可提供友好的错误提示\n3. **可扩展性**：便于添加 Python 端功能\n4. **pipx 兼容**：与 pipx 无缝集成\n\n### CGO_ENABLED=0\n\n禁用 CGO 是确保跨平台兼容性的关键决策，避免 libc 版本差异带来的兼容性问题。\n\n### 静态链接\n\n通过设置 `CGO_ENABLED=0`，Go 编译器生成静态二进制文件，减少运行时依赖。\n\n## 技术规格总结\n\n| 规格项 | 值 |\n|-------|-----|\n| Python 版本要求 | >=3.10 |\n| Go 版本要求 | >=1.16 |\n| 默认平台数 | 8 |\n| 外部依赖数 | 0 |\n| wheel 格式标准 | PEP 427, PEP 376 |\n| 元数据格式 | PEP 566 |\n\n资料来源：[spec.md](), [README.md]()\n\n---\n\n<a id='page-3'></a>\n\n## 支持的平台\n\n### 相关页面\n\n相关主题：[Go 交叉编译流程](#page-5), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 支持的平台\n\n## 概述\n\n`go-to-wheel` 工具支持将 Go CLI 程序交叉编译为多个目标平台的 Python wheel 安装包。该工具内置了完整的平台支持矩阵，通过 `PLATFORM_MAPPINGS` 和 `DEFAULT_PLATFORMS` 两个核心数据结构来管理不同操作系统和架构的编译目标。\n\n## 平台映射机制\n\n### 核心数据结构\n\n`go-to-wheel` 使用 `PLATFORM_MAPPINGS` 字典建立平台标识符与实际编译参数的一对一映射关系：\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | linux | amd64 | manylinux_2_17_x86_64 |\n| `linux-arm64` | linux | arm64 | manylinux_2_17_aarch64 |\n| `linux-amd64-musl` | linux | amd64 | musllinux_1_2_x86_64 |\n| `linux-arm64-musl` | linux | arm64 | musllinux_1_2_aarch64 |\n| `darwin-amd64` | darwin | amd64 | macosx_10_9_x86_64 |\n| `darwin-arm64` | darwin | arm64 | macosx_11_0_arm64 |\n| `windows-amd64` | windows | amd64 | win_amd64 |\n| `windows-arm64` | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:24-32]()\n\n### 默认构建平台\n\n默认情况下，`go-to-wheel` 会为以下 8 个平台构建 wheel：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:36-45]()\n\n## 平台分类说明\n\n### Linux 平台 (glibc)\n\n基于 glibc 的 Linux 发行版（如 Ubuntu、Debian、Fedora、CentOS 等）使用标准的 manylinux 标签：\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `linux-amd64` | x86_64 | 主流 64 位 Linux |\n| `linux-arm64` | aarch64 | ARM 64 位 Linux (AWS Graviton, Apple Silicon Mac Linux 环境等) |\n\n### Linux 平台 (musl)\n\n基于 musl libc 的轻量级 Linux 发行版（如 Alpine Linux）使用 musllinux 标签：\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `linux-amd64-musl` | x86_64 | Alpine 等 musl 发行版 |\n| `linux-arm64-musl` | aarch64 | ARM 架构 Alpine 等 |\n\n### macOS 平台\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `darwin-amd64` | x86_64 | Intel Mac |\n| `darwin-arm64` | arm64 | Apple Silicon Mac (M1/M2/M3 等) |\n\n### Windows 平台\n\n| 平台 | 架构 | 适用系统 |\n|------|------|---------|\n| `windows-amd64` | amd64 | 64 位 Windows |\n| `windows-arm64` | arm64 | Windows on ARM |\n\n## 编译流程\n\n平台支持的实现涉及以下编译步骤：\n\n```mermaid\ngraph TD\n    A[指定平台列表] --> B{遍历每个平台}\n    B --> C[获取 GOOS/GOARCH]\n    C --> D[CGO_ENABLED=0 交叉编译]\n    D --> E[生成 wheel 元数据]\n    E --> F[打包为 .whl 文件]\n    F --> G[移动到输出目录]\n    G --> H{还有更多平台?}\n    H -->|是| B\n    H -->|否| I[完成]\n```\n\n交叉编译命令使用环境变量控制目标平台：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 自定义平台选择\n\n### 指定特定平台\n\n用户可以通过 `--platforms` 参数选择构建特定平台：\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n### 平台参数解析\n\n平台解析逻辑将逗号分隔的字符串转换为列表：\n\n```python\nplatforms = None\nif args.platforms:\n    platforms = [p.strip() for p in args.platforms.split(\",\")]\n```\n\n资料来源：[go_to_wheel/__init__.py:75-78]()\n\n## Wheel 文件命名规范\n\n生成的 wheel 文件遵循 PEP 427 规范，命名格式为：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n```\n\n例如：\n\n| 平台标识符 | 生成的 wheel 文件名 |\n|-----------|-------------------|\n| linux-amd64 | `mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl` |\n| linux-arm64 | `mytool-1.0.0-py3-none-manylinux_2_17_aarch64.whl` |\n| darwin-arm64 | `mytool-1.0.0-py3-none-macosx_11_0_arm64.whl` |\n| windows-amd64 | `mytool-1.0.0-py3-none-win_amd64.whl` |\n\n## 静态编译保证\n\n所有平台的编译都使用 `CGO_ENABLED=0` 标志，确保生成静态链接的二进制文件。这一设计决策确保了：\n\n- 避免 libc 版本兼容性问题\n- 二进制文件具有完全的便携性\n- 不依赖目标系统的动态库\n\n## 安装兼容性\n\n### pipx 安装\n\n生成的 wheel 可通过 pipx 安装，直接将 Go 二进制程序添加到用户 PATH：\n\n```bash\npipx install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n### pip 直接安装\n\n同样支持标准 pip 安装：\n\n```bash\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n## 依赖要求\n\n| 组件 | 版本要求 |\n|------|---------|\n| Go | >= 1.16 |\n| Python | >= 3.10 |\n\n## 总结\n\n`go-to-wheel` 的平台支持系统通过清晰的数据结构定义和自动化的交叉编译流程，为 Go CLI 程序提供了广泛的 Python wheel 分发能力。目前支持 8 个主流平台，覆盖了 Linux (glibc/musl)、macOS 和 Windows 的主要架构变体。\n\n---\n\n<a id='page-4'></a>\n\n## 元数据配置\n\n### 相关页面\n\n相关主题：[Wheel 生成机制](#page-6), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n</details>\n\n# 元数据配置\n\n## 概述\n\n元数据配置是 go-to-wheel 项目的核心功能模块，负责为生成的 Python wheel 包生成符合 PEP 规范的标准元数据文件。该模块处理从命令行参数到 wheel 包元数据字段的完整映射与转换过程。\n\ngo-to-wheel 将编译好的 Go 二进制文件打包为 Python wheel 包时，需要生成符合 Python 打包生态系统标准的元数据文件，包括 METADATA、WHEEL、entry_points.txt 和 RECORD。这些文件共同定义了包的名称、版本、依赖、入口点等关键信息。\n\n## 核心文件结构\n\nwheel 包遵循 PEP 427 标准格式，其内部文件结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n元数据配置模块主要负责生成 `dist-info` 目录下的四个核心文件。资料来源：[spec.md]()\n\n## 元数据类型详解\n\n### METADATA 文件\n\nMETADATA 文件遵循 PEP 566 规范，定义包的描述性信息。其生成逻辑位于 `generate_metadata()` 函数中：\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str = \"Go binary packaged as Python wheel\",\n    *,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    requires_python: str = \">=3.10\",\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的文件内容格式：\n\n```\nMetadata-Version: 2.1\nName: {package_name}\nVersion: {version}\nSummary: {description}\nAuthor: {author}\nAuthor-email: {author_email}\nLicense: {license}\nHome-page: {url}\nRequires-Python: {requires_python}\nDescription-Content-Type: text/markdown\n\n{readme_content}\n```\n\n| 字段 | 说明 | 来源参数 |\n|------|------|---------|\n| Metadata-Version | 元数据版本，固定为 2.1 | 固定值 |\n| Name | 包名称 | `name` 参数 |\n| Version | 包版本 | `version` 参数 |\n| Summary | 包描述 | `description` 参数 |\n| Author | 作者姓名 | `author` 参数 |\n| Author-email | 作者邮箱 | `author_email` 参数 |\n| License | 许可证标识符 | `license_` 参数 |\n| Home-page | 项目主页 URL | `url` 参数 |\n| Requires-Python | Python 版本要求 | `requires_python` 参数 |\n| Description-Content-Type | README 内容类型 | 仅当提供 readme_content 时添加 |\n\n资料来源：[go_to_wheel/__init__.py:180-216]()\n\n### WHEEL 文件\n\nWHEEL 文件遵循 PEP 427 规范，定义 wheel 包的分发属性：\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel {version}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n```\n\n| 字段 | 说明 | 值 |\n|------|------|-----|\n| Wheel-Version | wheel 格式版本 | 固定为 1.0 |\n| Generator | 生成工具标识 | `go-to-wheel {__version__}` |\n| Root-Is-Purelib | 是否为纯 Python 包 | 固定为 `false`（Go 二进制为本地扩展） |\n| Tag | wheel 平台标签 | `py3-none-{platform_tag}` |\n\n资料来源：[go_to_wheel/__init__.py:218-225]()\n\n### entry_points.txt 文件\n\nentry_points.txt 定义控制台入口点，使安装后的包可以在 PATH 中直接调用：\n\n```\n[console_scripts]\n{entry_point} = {package_name}:main\n```\n\n| 字段 | 说明 | 来源参数 |\n|------|------|---------|\n| [console_scripts] | 入口点类型 | 固定部分 |\n| {entry_point} | CLI 命令名称 | `entry_point` 参数，默认为包名 |\n| {package_name} | Python 模块名 | 规范化后的包名 |\n| main | 调用的函数名 | 固定为 `main` |\n\n资料来源：[go_to_wheel/__init__.py:227-232]()\n\n### RECORD 文件\n\nRECORD 文件遵循 PEP 376 规范，记录包内所有文件的路径、哈希值和大小：\n\n```\n{path},{sha256_hash},{size}\n```\n\n该文件为 CSV 格式，每行代表一个文件，文件列表以空行结束。RECORD 文件本身不包含哈希值（留空）。资料来源：[go_to_wheel/__init__.py:234-245]()\n\n## 命令行参数映射\n\ngo-to-wheel 通过 argparse 解析命令行参数，并将这些参数传递给 `build_wheels()` 函数生成元数据：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    description: str = \"Go binary packaged as Python wheel\",\n    requires_python: str = \">=3.10\",\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme: str | None = None,\n    ldflags: str | None = None,\n    set_version_var: str | None = None,\n) -> list[str]:\n```\n\n参数与元数据字段的对应关系：\n\n| CLI 参数 | 类型 | 默认值 | METADATA 字段 |\n|---------|------|--------|--------------|\n| `--name` | str | 目录 basename | Name |\n| `--version` | str | \"0.1.0\" | Version |\n| `--description` | str | \"Go binary packaged as Python wheel\" | Summary |\n| `--author` | str | None | Author |\n| `--author-email` | str | None | Author-email |\n| `--license` | str | None | License |\n| `--url` | str | None | Home-page |\n| `--requires-python` | str | \">=3.10\" | Requires-Python |\n| `--readme` | str | None | Description-Content-Type + 内容 |\n| `--entry-point` | str | 与 name 相同 | 控制台脚本名 |\n\n资料来源：[go_to_wheel/__init__.py:35-96]()\n\n## 默认值与自动推断\n\n### 包名自动推断\n\n```python\nif name is None:\n    name = go_path.name\n```\n\n当未指定 `--name` 参数时，系统自动使用 Go 模块目录的基础名称作为包名。资料来源：[go_to_wheel/__init__.py:250-251]()\n\n### 入口点自动推断\n\n```python\nif entry_point is None:\n    entry_point = name\n```\n\n当未指定 `--entry-point` 参数时，CLI 命令名默认与包名相同。资料来源：[go_to_wheel/__init__.py:253-254]()\n\n### README 文件读取\n\n```python\nreadme_content: str | None = None\nif readme:\n    readme_path = Path(readme)\n    if not readme_path.exists():\n        raise FileNotFoundError(f\"README file not found: {readme}\")\n    readme_content = readme_path.read_text(encoding=\"utf-8\")\n```\n\nREADME 文件路径通过 `--readme` 参数指定，系统读取文件内容并将其嵌入 METADATA 的 Description 字段。资料来源：[go_to_wheel/__init__.py:237-245]()\n\n## 平台标签映射\n\ngo-to-wheel 定义了完整的目标平台到 wheel 标签的映射关系：\n\n```python\nPLATFORM_MAPPINGS: dict[str, tuple[str, str, str]] = {\n    \"linux-amd64\": (\"linux\", \"amd64\", \"manylinux_2_17_x86_64\"),\n    \"linux-arm64\": (\"linux\", \"arm64\", \"manylinux_2_17_aarch64\"),\n    \"linux-amd64-musl\": (\"linux\", \"amd64\", \"musllinux_1_2_x86_64\"),\n    \"linux-arm64-musl\": (\"linux\", \"arm64\", \"musllinux_1_2_aarch64\"),\n    \"darwin-amd64\": (\"darwin\", \"amd64\", \"macosx_10_9_x86_64\"),\n    \"darwin-arm64\": (\"darwin\", \"arm64\", \"macosx_11_0_arm64\"),\n    \"windows-amd64\": (\"windows\", \"amd64\", \"win_amd64\"),\n    \"windows-arm64\": (\"windows\", \"arm64\", \"win_arm64\"),\n}\n\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|---------|------|--------|-----------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:14-27]()\n\n## 元数据生成流程\n\n元数据的生成发生在 wheel 构建过程中，整体流程如下：\n\n```mermaid\ngraph TD\n    A[接收 build_wheels 参数] --> B{验证 Go 模块目录}\n    B -->|go.mod 存在| C[读取 README 文件]\n    B -->|go.mod 不存在| Z[抛出 ValueError]\n    C --> D[设置默认值]\n    D --> E[处理 ldflags]\n    E --> F[遍历目标平台]\n    F --> G[编译 Go 二进制]\n    G --> H[创建临时目录结构]\n    H --> I[生成 Python 包装模块]\n    I --> J[生成元数据文件]\n    J --> K[计算文件哈希]\n    K --> L[生成 RECORD]\n    L --> M[打包为 ZIP]\n    M --> N[移动到输出目录]\n    N --> O[返回 wheel 路径列表]\n```\n\n元数据生成的关键步骤包括：\n\n1. **Python 包装模块生成**：创建 `__init__.py` 和 `__main__.py`，其中包含执行二进制文件的逻辑\n2. **METADATA 文件生成**：调用 `generate_metadata()` 创建包描述信息\n3. **WHEEL 文件生成**：调用 `generate_wheel_metadata()` 创建分发属性\n4. **entry_points.txt 生成**：调用 `generate_entry_points()` 创建控制台入口点\n5. **RECORD 文件生成**：收集所有文件，计算 SHA256 哈希，生成记录文件\n\n资料来源：[go_to_wheel/__init__.py:195-330]()\n\n## ldflags 与版本变量\n\ngo-to-wheel 支持通过 `--set-version-var` 参数将包版本嵌入 Go 二进制文件：\n\n```python\ncombined_ldflags_parts: list[str] = []\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n\ncombined_ldflags = \"-s -w \" + \" \".join(combined_ldflags_parts)\n```\n\n| 参数 | 说明 | 示例 |\n|------|------|-----|\n| `--set-version-var` | Go 变量路径，值自动使用 `--version` | `main.version` |\n| `--ldflags` | 附加的 Go 链接器标志 | `-X main.commit=abc123` |\n\n最终传递给 Go 编译器的 ldflags 格式为：\n\n```\n-s -w -X main.version=2.0.0 -X main.commit=abc123\n```\n\n其中 `-s -w` 为默认参数，用于剥离调试信息减少二进制体积。资料来源：[go_to_wheel/__init__.py:260-268]()\n\n## Python 包装模块\n\n元数据配置不仅包括 dist-info 目录下的文件，还包括 Python 包本身的代码。这些文件构成 Go 二进制与 Python 系统的桥梁：\n\n### `__init__.py`\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport sys\nimport subprocess\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"Return the path to the bundled binary.\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n### `__main__.py`\n\n```python\nfrom . import main\nmain()\n```\n\n包装模块采用 `console_scripts` 入口点机制而非 `.data/scripts/`，原因包括：\n- 跨平台行为一致\n- 可提供更友好的错误信息\n- 支持 pipx 无缝集成\n- 便于添加 Python 端功能\n\n资料来源：[spec.md]()\n\n## 完整元数据示例\n\n使用所有元数据选项构建 wheel：\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n生成的 METADATA 文件：\n\n```\nMetadata-Version: 2.1\nName: mytool-bin\nVersion: 2.0.0\nSummary: My awesome tool\nAuthor: Jane Doe\nAuthor-email: jane@example.com\nLicense: MIT\nHome-page: https://github.com/jane/mytool\nRequires-Python: >=3.10\nDescription-Content-Type: text/markdown\n\n{Redme 内容}\n```\n\n生成的 WHEEL 文件（以 linux-amd64 为例）：\n\n```\nWheel-Version: 1.0\nGenerator: go-to-wheel 0.1.0\nRoot-Is-Purelib: false\nTag: py3-none-manylinux_2_17_x86_64\n```\n\n资料来源：[README.md]()\n\n## 总结\n\n元数据配置模块是 go-to-wheel 项目实现 Go 程序 Python 分发的核心组件。通过标准化地生成符合 PEP 规范的元数据文件，该模块确保生成的 wheel 包能够被 pip、pipx 等 Python 包管理工具正确识别和处理。模块设计充分利用 Python 标准库，无需额外依赖，同时通过命令行参数提供了灵活的配置能力。\n\n---\n\n<a id='page-5'></a>\n\n## Go 交叉编译流程\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [支持的平台](#page-3), [Wheel 生成机制](#page-6)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# Go 交叉编译流程\n\n## 概述\n\nGo 交叉编译流程是 go-to-wheel 工具的核心功能，负责将 Go 语言编写的 CLI 程序编译为支持多个操作系统和架构的二进制文件。该流程通过设置 Go 的环境变量（`GOOS`、`GOARCH`、`CGO_ENABLED`）实现跨平台编译，生成静态链接的二进制文件，为后续打包为 Python wheel 提供基础。\n\ngo-to-wheel 的交叉编译设计目标是：\n- 一次构建，多平台输出\n- 生成静态链接二进制（无 libc 依赖问题）\n- 自动处理平台差异（如 Windows 的 .exe 扩展名）\n- 支持通过 ldflags 注入版本信息\n\n## 支持的平台映射\n\ngo-to-wheel 内置了完整的目标平台映射表，将用户友好的平台标识符映射到 Go 编译所需的操作系统、架构以及最终的 wheel 平台标签。\n\n### 平台映射表\n\n| 平台标识符 | GOOS | GOARCH | Wheel 平台标签 |\n|-----------|------|--------|---------------|\n| `linux-amd64` | `linux` | `amd64` | `manylinux_2_17_x86_64` |\n| `linux-arm64` | `linux` | `arm64` | `manylinux_2_17_aarch64` |\n| `linux-amd64-musl` | `linux` | `amd64` | `musllinux_1_2_x86_64` |\n| `linux-arm64-musl` | `linux` | `arm64` | `musllinux_1_2_aarch64` |\n| `darwin-amd64` | `darwin` | `amd64` | `macosx_10_9_x86_64` |\n| `darwin-arm64` | `darwin` | `arm64` | `macosx_11_0_arm64` |\n| `windows-amd64` | `windows` | `amd64` | `win_amd64` |\n| `windows-arm64` | `windows` | `arm64` | `win_arm64` |\n\n资料来源：[go_to_wheel/__init__.py:18-27](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n### 默认编译平台\n\n默认情况下，go-to-wheel 会为以下 8 个平台构建二进制文件：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n资料来源：[go_to_wheel/__init__.py:29-38](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n这一策略覆盖了主流的 Linux 发行版（glibc 和 musl 两种 libc）、macOS（Intel 和 Apple Silicon）以及 Windows（x64 和 ARM64）用户群体。\n\n## 交叉编译流程架构\n\n### 流程概览\n\n```mermaid\ngraph TD\n    A[用户调用 go-to-wheel] --> B[解析命令行参数]\n    B --> C{指定平台列表?}\n    C -->|是| D[使用用户指定平台]\n    C -->|否| E[使用 DEFAULT_PLATFORMS]\n    D --> F[遍历目标平台列表]\n    E --> F\n    F --> G{每个平台}\n    G --> H[从 PLATFORM_MAPPINGS 获取 GOOS/GOARCH]\n    H --> I[构建 Go 交叉编译命令]\n    I --> J[执行 go build]\n    J --> K[验证二进制文件生成]\n    K --> L[创建 Python 包结构]\n    L --> M[生成 wheel 元数据]\n    M --> N[打包为 .whl 文件]\n    N --> O{还有更多平台?}\n    O -->|是| G\n    O -->|否| P[输出所有 wheel 文件路径]\n```\n\n### 核心编译函数\n\n`build_wheels()` 函数是整个流程的入口点，负责协调交叉编译和 wheel 打包的各个环节：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    description: str = \"Go binary packaged as Python wheel\",\n    requires_python: str = \">=3.10\",\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme: str | None = None,\n    ldflags: str | None = None,\n    set_version_var: str | None = None,\n) -> list[str]:\n```\n\n资料来源：[go_to_wheel/__init__.py:131-157](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n## 编译命令详解\n\n### 基础编译命令\n\n对于每个目标平台，go-to-wheel 执行以下格式的 Go 编译命令：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n### 环境变量说明\n\n| 环境变量 | 值 | 作用 |\n|---------|-----|------|\n| `GOOS` | 目标操作系统 | 指定编译目标平台 |\n| `GOARCH` | 目标架构 | 指定 CPU 架构 |\n| `CGO_ENABLED` | `0` | 禁用 CGO，确保生成静态链接二进制 |\n\n### 编译参数说明\n\n| 参数 | 值 | 作用 |\n|-----|-----|------|\n| `-ldflags=\"-s -w\"` | 链接器标志 | `-s` 剥离符号表，`-w` 移除 DWARF 调试信息，减小二进制体积 |\n| `-o` | 输出路径 | 指定编译产物的位置 |\n\n### ldflags 扩展机制\n\ngo-to-wheel 支持通过 `--ldflags` 参数追加额外的链接器标志，允许用户嵌入版本信息等自定义数据：\n\n```python\n# 构建组合 ldflags：先设置版本变量，再追加用户 ldflags\ncombined_ldflags_parts: list[str] = []\n\n# 添加 -X 标志设置版本变量\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\n\n# 追加用户提供的 ldflags\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n\n# 最终 ldflags 格式: -s -w -X main.version=1.0.0 -X main.commit=abc123\ncombined_ldflags = \" \".join(combined_ldflags_parts)\n```\n\n资料来源：[go_to_wheel/__init__.py:180-195](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n这使得最终的链接器调用变为：\n\n```bash\n-ldflags=\"-s -w -X main.version=2.0.0\"\n```\n\n其中 `-X` 标志允许在编译时设置 Go 代码中的字符串变量值，这是 Go 项目中嵌入版本信息的标准做法。\n\n## 平台特定处理\n\n### Windows 平台\n\nWindows 平台的 Go 编译会自动添加 `.exe` 扩展名。go-to-wheel 在查找编译输出时使用以下逻辑：\n\n```python\n# Windows 平台检查\nis_windows = goos == \"windows\"\noutput_name = binary_name + \".exe\" if is_windows else binary_name\noutput_path = temp_dir / output_name\n```\n\n### Linux musl 平台\n\n对于 musl 基础镜像的 Linux 发行版（如 Alpine Linux），go-to-wheel 通过设置 `CGO_ENABLED=0` 确保生成的二进制不依赖 glibc，这是实现 musl 兼容性的关键。\n\n## 交叉编译流程详细步骤\n\n### 步骤 1：输入验证\n\n```mermaid\ngraph LR\n    A[go_dir 参数] --> B{目录存在?}\n    B -->|否| C[抛出 FileNotFoundError]\n    B -->|是| D{go.mod 存在?}\n    D -->|否| E[抛出 ValueError: Not a Go module]\n    D -->|是| F[继续处理]\n```\n\n### 步骤 2：参数解析与默认值\n\n```python\ngo_path = Path(go_dir).resolve()\n\n# 设置包名默认为目录名\nif name is None:\n    name = go_path.name\n\n# 设置入口点默认为包名\nif entry_point is None:\n    entry_point = name\n\n# 设置平台列表默认为所有支持的平台\nif platforms is None:\n    platforms = DEFAULT_PLATFORMS\n```\n\n### 步骤 3：平台迭代编译\n\n对于平台列表中的每个平台：\n\n1. 从 `PLATFORM_MAPPINGS` 获取 `goos`、`goarch`、`platform_tag`\n2. 构建 `subprocess.run()` 调用\n3. 设置环境变量 `GOOS`、`GOARCH`、`CGO_ENABLED`\n4. 执行 `go build` 命令\n5. 验证二进制文件是否成功生成\n\n### 步骤 4：二进制文件组织\n\n编译完成后，每个平台的二进制文件被组织到统一的目录结构中：\n\n```\n{package_name}/\n├── __init__.py\n├── __main__.py\n└── bin/\n    └── {binary_name}[.exe]    ← 编译生成的二进制文件\n```\n\n## 错误处理与验证\n\n### 编译错误处理\n\n如果 `go build` 命令执行失败，subprocess 会抛出异常，流程终止并向用户报告错误：\n\n```python\nresult = subprocess.run(\n    [go_binary, \"build\", \"-ldflags=\" + ldflags, \"-o\", str(output_path), \".\"],\n    cwd=go_path,\n    env=env,\n    capture_output=True,\n    text=True,\n)\n\nif result.returncode != 0:\n    raise RuntimeError(f\"Go build failed: {result.stderr}\")\n```\n\n### 包名验证规则\n\n根据 PEP 503，包名必须满足以下规则：\n\n| 规则 | 说明 |\n|-----|------|\n| 可用字符 | 小写字母、数字、连字符、下划线、句点 |\n| 首字符 | 必须以字母或数字开头 |\n| 规范化 | 连字符和下划线统一转换为连字符用于 wheel 文件名 |\n\n包目录使用 PEP 8 风格的导入名，即连字符替换为下划线：\n\n```python\n# 例如: my-tool → my_tool/\nimport_name = name.replace(\"-\", \"_\")\n```\n\n## 与 wheel 打包的集成\n\n### 数据流向\n\n```mermaid\ngraph LR\n    A[Go 源码] --> B[go build 交叉编译]\n    B --> C[各平台二进制文件]\n    C --> D[Python 包结构组装]\n    D --> E[wheel 元数据生成]\n    E --> F[.whl 文件打包]\n    F --> G[Python wheel 分发]\n```\n\n### wheel 生成流程\n\n交叉编译完成后，每个二进制文件会经历以下流程：\n\n1. **创建临时目录结构**：按照 wheel 规范创建目录层级\n2. **复制二进制文件**：将编译产物放入 `{package_name}/bin/` 目录\n3. **生成 Python 包装器**：创建 `__init__.py` 和 `__main__.py`\n4. **生成元数据文件**：创建 `METADATA`、`WHEEL`、`RECORD`、`entry_points.txt`\n5. **打包为 zip**：使用 `zipfile` 创建 `.whl` 文件\n\n### wheel 文件命名规范\n\n生成的 wheel 文件遵循 PEP 427 命名规范：\n\n```\n{name}-{version}-py3-none-{platform_tag}.whl\n```\n\n示例：\n- `mytool-0.1.0-py3-none-manylinux_2_17_x86_64.whl`\n- `mytool-0.1.0-py3-none-macosx_11_0_arm64.whl`\n- `mytool-0.1.0-py3-none-win_amd64.whl`\n\n## 命令行接口\n\n### 使用方式\n\n```bash\ngo-to-wheel path/to/go-folder [options]\n```\n\n### 交叉编译相关参数\n\n| 参数 | 说明 | 默认值 |\n|-----|------|--------|\n| `--platforms PLATFORMS` | 逗号分隔的目标平台列表 | 所有支持的平台 |\n| `--go-binary PATH` | Go 二进制文件路径 | `go`（从 PATH 环境变量查找） |\n| `--ldflags FLAGS` | 额外的 Go 链接器标志 | `None` |\n| `--set-version-var VAR` | 设置版本变量的 Go 变量名 | `None` |\n| `--version VERSION` | 包版本号 | `0.1.0` |\n\n### 使用示例\n\n构建特定平台的 wheel：\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n嵌入版本信息：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n自定义链接器标志：\n\n```bash\ngo-to-wheel ./mytool --ldflags \"-X main.commit=abc123\"\n```\n\n## 技术要点总结\n\n### 为什么使用 CGO_ENABLED=0\n\n禁用 CGO 是实现静态链接和跨发行版兼容性的关键：\n\n- **静态链接**：生成的二进制文件不依赖系统 libc\n- **无需交叉编译工具链**：Go 的交叉编译原生支持纯 Go 代码\n- **部署简化**：单个二进制文件即可运行，无需安装运行时依赖\n\n### ldflags 的最佳实践\n\n在 Go 项目中使用 `--set-version-var` 功能时，Go 源码应包含版本变量声明：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if len(os.Args) > 1 && os.Args[1] == \"--version\" {\n        fmt.Println(version)\n    }\n}\n```\n\n这样编译后的二进制文件可以通过 `--version` 参数显示正确的版本号。\n\n### 输出目录结构\n\n编译完成后，wheel 文件默认输出到 `./dist` 目录，用户可以通过 `--output-dir` 参数自定义输出位置。\n\n---\n\n<a id='page-6'></a>\n\n## Wheel 生成机制\n\n### 相关页面\n\n相关主题：[系统架构](#page-2), [Go 交叉编译流程](#page-5), [元数据配置](#page-4)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# Wheel 生成机制\n\n`go-to-wheel` 的核心功能是将 Go 语言编译的二进制程序封装为符合 Python PEP 427 标准的 wheel 安装包。本页面详细说明 wheel 生成的技术机制、文件结构和工作流程。\n\n## 概述\n\nWheel 生成机制是 `go-to-wheel` 将 Go 二进制程序转换为可分发 Python 包的核心模块。该机制包含三个主要阶段：\n\n1. **跨平台编译** - 使用 Go 工具链为不同操作系统和架构编译静态二进制文件\n2. **包结构构建** - 创建符合 PEP 427 规范的 wheel 目录结构\n3. **元数据生成** - 生成 METADATA、WHEEL、entry_points.txt 和 RECORD 文件\n\n资料来源：[spec.md]()\n\n## 平台映射表\n\ngo-to-wheel 支持的编译平台与 wheel 标签之间的映射关系定义在 `PLATFORM_MAPPINGS` 字典中：\n\n```python\nPLATFORM_MAPPINGS: dict[str, tuple[str, str, str]] = {\n    \"linux-amd64\": (\"linux\", \"amd64\", \"manylinux_2_17_x86_64\"),\n    \"linux-arm64\": (\"linux\", \"arm64\", \"manylinux_2_17_aarch64\"),\n    \"linux-amd64-musl\": (\"linux\", \"amd64\", \"musllinux_1_2_x86_64\"),\n    \"linux-arm64-musl\": (\"linux\", \"arm64\", \"musllinux_1_2_aarch64\"),\n    \"darwin-amd64\": (\"darwin\", \"amd64\", \"macosx_10_9_x86_64\"),\n    \"darwin-arm64\": (\"darwin\", \"arm64\", \"macosx_11_0_arm64\"),\n    \"windows-amd64\": (\"windows\", \"amd64\", \"win_amd64\"),\n    \"windows-arm64\": (\"windows\", \"arm64\", \"win_arm64\"),\n}\n```\n\n每个映射包含三个元素：`GOOS`（操作系统）、`GOARCH`（架构）和 wheel 标签。\n\n资料来源：[go_to_wheel/__init__.py:15-25](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L15-L25)\n\n## 默认平台列表\n\n`DEFAULT_PLATFORMS` 定义了未指定平台时的默认编译目标：\n\n```python\nDEFAULT_PLATFORMS = [\n    \"linux-amd64\",\n    \"linux-arm64\",\n    \"linux-amd64-musl\",\n    \"linux-arm64-musl\",\n    \"darwin-amd64\",\n    \"darwin-arm64\",\n    \"windows-amd64\",\n    \"windows-arm64\",\n]\n```\n\n这意味着默认情况下，go-to-wheel 会为 Linux（glibc 和 musl 两种 libc）、macOS 和 Windows 各平台生成 wheels。\n\n资料来源：[go_to_wheel/__init__.py:27-34](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L27-L34)\n\n## 核心函数\n\n### build_wheels 函数\n\n`build_wheels()` 是入口函数，负责协调整个 wheel 生成流程：\n\n```python\ndef build_wheels(\n    go_dir: str,\n    *,\n    name: str | None = None,\n    version: str = \"0.1.0\",\n    output_dir: str = \"./dist\",\n    entry_point: str | None = None,\n    platforms: list[str] | None = None,\n    go_binary: str = \"go\",\n    # ... 其他参数\n) -> list[str]:\n```\n\n该函数执行以下验证步骤：\n1. 检查 Go 目录是否存在\n2. 验证 `go.mod` 文件存在\n3. 读取 README 文件（如提供）\n4. 解析平台列表并设置默认值\n5. 组合 ldflags 参数\n\n资料来源：[go_to_wheel/__init__.py:131-220](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L131-L220)\n\n### build_single_wheel 函数\n\n`build_single_wheel()` 负责为单个平台构建 wheel 文件：\n\n```python\ndef build_single_wheel(\n    binary_content: bytes,\n    platform: str,\n    # ... 其他参数\n) -> str:\n```\n\n该函数的核心流程：\n1. 计算平台标签和包名称\n2. 创建临时目录结构\n3. 生成所有必需的文件\n4. 打包为 ZIP 文件\n5. 设置二进制文件的可执行权限\n\n资料来源：[go_to_wheel/__init__.py:65-128](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L65-L128)\n\n## Wheel 文件结构\n\n生成的 wheel 文件遵循 PEP 427 规范，其内部结构如下：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {import_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {import_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n关键点：\n- 包目录使用 **import_name**（将连字符替换为下划线）\n- 二进制文件位于 `bin/` 子目录\n- `dist-info/` 目录包含所有元数据文件\n- `Root-Is-Purelib: false` 表示这是平台特定包\n\n资料来源：[spec.md]()\n\n## 元数据生成\n\n### METADATA 文件\n\n`generate_metadata()` 函数生成符合 PEP 566 标准的 METADATA 文件：\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str,\n    requires_python: str,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的内容示例：\n\n```\nMetadata-Version: 2.1\nName: mytool\nVersion: 1.0.0\nSummary: My awesome tool\nRequires-Python: >=3.10\nDescription-Content-Type: text/markdown\n\n# My Tool\n\n...\n```\n\n资料来源：[go_to_wheel/__init__.py:240-280](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L240-L280)\n\n### WHEEL 文件\n\n`generate_wheel_metadata()` 函数生成 WHEEL 元数据：\n\n```python\ndef generate_wheel_metadata(platform_tag: str) -> str:\n    return f\"\"\"Wheel-Version: 1.0\nGenerator: go-to-wheel {__version__}\nRoot-Is-Purelib: false\nTag: py3-none-{platform_tag}\n\"\"\"\n```\n\n`Root-Is-Purelib: false` 表示该 wheel 包含平台特定的二进制文件。\n\n资料来源：[go_to_wheel/__init__.py:282-288](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L282-L288)\n\n### entry_points.txt\n\n`generate_entry_points()` 函数生成 console_scripts 入口点配置：\n\n```python\ndef generate_entry_points(entry_point: str, import_name: str) -> str:\n    return f\"\"\"[console_scripts]\n{entry_point} = {import_name}:main\n\"\"\"\n```\n\n这使得安装后可以直接通过命令行调用 `entry_point` 命令来执行 Go 程序。\n\n资料来源：[go_to_wheel/__init__.py:290-294](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L290-L294)\n\n### RECORD 文件\n\n`generate_record()` 函数生成 RECORD 文件，这是 PEP 376 规范要求的文件清单：\n\n```python\ndef generate_record(files: dict[str, bytes]) -> str:\n    output = io.StringIO()\n    writer = csv.writer(output)\n    \n    for path, content in files.items():\n        if path.endswith(\"RECORD\"):\n            writer.writerow([path, \"\", \"\"])\n        else:\n            hash_value = hashlib.sha256(content).digest()\n            hash_b64 = base64.urlsafe_b64encode(hash_value).rstrip(b\"=\").decode(\"ascii\")\n            size = len(content)\n            writer.writerow([path, f\"sha256={hash_b64}\", size])\n    \n    return output.getvalue()\n```\n\nRECORD 文件使用 CSV 格式，每行包含：文件路径、SHA256 哈希值和文件大小。\n\n资料来源：[go_to_wheel/__init__.py:296-308](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L296-L308)\n\n## Python 包装器\n\n生成的 `__init__.py` 包含 Go 二进制程序的调用逻辑：\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport sys\nimport subprocess\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"返回打包的二进制文件路径。\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"执行打包的二进制文件。\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows: 使用 subprocess.call 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix: 使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n关键设计决策：\n- Windows 使用 `subprocess.call` 以正确处理信号\n- Unix 使用 `os.execvp` 替换当前进程，获得原生的信号处理行为\n\n资料来源：[spec.md]()\n\n## 构建流程图\n\n```mermaid\ngraph TD\n    A[build_wheels 入口] --> B{验证 Go 目录和 go.mod}\n    B -->|通过| C[读取 README 文件]\n    B -->|失败| Z[抛出异常]\n    C --> D[设置默认值]\n    D --> E{遍历目标平台列表}\n    E -->|还有平台| F[调用 go build 编译]\n    F --> G[调用 build_single_wheel]\n    G --> H[生成包文件结构]\n    H --> I[生成元数据文件]\n    I --> J[打包为 ZIP]\n    J --> K[保存到输出目录]\n    K --> E\n    E -->|完成| L[返回 wheel 文件列表]\n```\n\n## 二进制编译过程\n\n对于每个目标平台，go-to-wheel 使用以下命令进行交叉编译：\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n编译参数说明：\n- `CGO_ENABLED=0`：禁用 CGO，生成静态链接的二进制文件\n- `-ldflags=\"-s -w\"`：剥离符号表和调试信息，减小文件体积\n- Windows 平台自动添加 `.exe` 扩展名\n\n资料来源：[spec.md]()\n\n## ldflags 合并机制\n\n`build_wheels` 函数支持通过 `--set-version-var` 和 `--ldflags` 参数自定义 Go 链接器标志：\n\n```python\n# 构建组合 ldflags: set_version_var 优先于用户 ldflags\ncombined_ldflags_parts: list[str] = []\nif set_version_var:\n    combined_ldflags_parts.append(f\"-X {set_version_var}={version}\")\nif ldflags:\n    combined_ldflags_parts.append(ldflags)\n```\n\n这允许：\n1. 通过 `--set-version-var main.version` 自动注入版本号\n2. 通过 `--ldflags` 添加自定义标志（如 git commit hash）\n\n资料来源：[go_to_wheel/__init__.py:193-200](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L193-L200)\n\n## 包名称规范\n\ngo-to-wheel 对包名称有以下处理规则：\n\n| 输入 | import_name | 分发名称 |\n|------|-------------|---------|\n| `mytool` | `mytool` | `mytool` |\n| `my-tool` | `my_tool` | `mytool` |\n| `my.tool` | `my_tool` | `mytool` |\n\n- **分发名称**：用于 wheel 文件名和 pip 安装\n- **import_name**：用于 Python 包目录（PEP 8 规范）\n- 两者通过名称规范化（将连字符和点号替换为下划线）相互转换\n\n资料来源：[spec.md]()\n\n## 可执行权限处理\n\n在创建 ZIP 文件时，go-to-wheel 为二进制文件设置 Unix 权限：\n\n```python\nif \"/bin/\" in file_path:\n    info = zipfile.ZipInfo(file_path)\n    info.external_attr = (stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) << 16\n    whl.writestr(info, content)\nelse:\n    whl.writestr(file_path, content)\n```\n\n这确保打包的二进制文件在解压后具有可执行权限（rwxr-xr-x）。\n\n资料来源：[go_to_wheel/__init__.py:113-119](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L113-L119)\n\n## 依赖关系\n\ngo-to-wheel 本身无外部 Python 依赖，仅使用 Python 标准库：\n\n- `argparse` - 命令行参数解析\n- `csv` - RECORD 文件生成\n- `hashlib` - SHA256 哈希计算\n- `zipfile` - wheel 打包\n- `subprocess` - Go 编译调用\n\n资料来源：[go_to_wheel/__init__.py:1-14](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py#L1-L14)\n\n---\n\n<a id='page-7'></a>\n\n## 快速开始\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [高级用法与示例](#page-8), [开发环境搭建](#page-9)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n</details>\n\n# 快速开始\n\n`go-to-wheel` 是一款将 Go 语言编写的命令行工具编译并打包为 Python Wheel 分发包的工具。本文档介绍如何快速上手使用该工具。\n\n## 前置要求\n\n### 系统依赖\n\n| 依赖项 | 版本要求 | 说明 |\n|--------|----------|------|\n| Python | >= 3.10 | 运行环境 |\n| Go | >= 1.16 | 用于编译 Go 模块 |\n\nGo 编译器需要安装并位于 PATH 环境变量中。\n\n### 环境检查\n\n```bash\n# 验证 Python 版本\npython --version\n\n# 验证 Go 已安装\ngo version\n```\n\n## 安装方式\n\n`go-to-wheel` 支持多种安装方式：\n\n```bash\n# 通过 pip 安装\npip install go-to-wheel\n\n# 通过 pipx 安装（推荐）\npipx install go-to-wheel\n```\n\n资料来源：[README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 基础用法\n\n### 最简命令\n\n使用默认配置为 Go 模块构建所有平台的 Wheel：\n\n```bash\ngo-to-wheel path/to/go-module\n```\n\n这会自动创建以下平台的 Wheel 文件到 `./dist` 目录：\n\n- Linux (glibc): amd64, arm64\n- Linux (musl): amd64, arm64\n- macOS: Intel (amd64), Apple Silicon (arm64)\n- Windows: amd64, arm64\n\n### 构建流程\n\n```mermaid\ngraph TD\n    A[go-to-wheel 命令] --> B[验证 Go 模块]\n    B --> C[交叉编译 Go 二进制]\n    C --> D[创建 Python 包结构]\n    D --> E[生成 Wheel 元数据]\n    E --> F[打包为 .whl 文件]\n    F --> G[输出到 ./dist 目录]\n```\n\n资料来源：[spec.md - Build Process](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n## 常用命令示例\n\n### 示例一：基本构建\n\n```bash\ngo-to-wheel ./mytool\n```\n\n生成的 Wheel 文件命名格式为：\n```\n{mytool}-{version}-py3-none-{platform_tag}.whl\n```\n\n### 示例二：自定义包名\n\n```bash\ngo-to-wheel ./mytool --name my-python-tool\n```\n\n这将生成名为 `my_python_tool` 的 Python 包。\n\n### 示例三：指定版本\n\n```bash\ngo-to-wheel ./mytool --version 1.2.3\n```\n\n### 示例四：指定输出目录\n\n```bash\ngo-to-wheel ./mytool --output-dir ./wheels\n```\n\n### 示例五：仅构建特定平台\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n```\n\n支持的平台标识符：\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|----------|------|--------|------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[README.md - Supported platforms](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 完整元数据配置\n\n为 PyPI 发布准备完整的 Wheel 包：\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n### 可用元数据选项\n\n| 选项 | 说明 | 默认值 |\n|------|------|--------|\n| `--name` | Python 包名 | 目录名 |\n| `--version` | 包版本 | 0.1.0 |\n| `--description` | 包描述 | \"Go binary packaged as Python wheel\" |\n| `--license` | 许可证标识符 | 无 |\n| `--author` | 作者姓名 | 无 |\n| `--author-email` | 作者邮箱 | 无 |\n| `--url` | 项目 URL | 无 |\n| `--readme` | README 文件路径 | 无 |\n| `--requires-python` | Python 版本要求 | >=3.10 |\n\n资料来源：[go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n## 嵌入版本信息\n\n### 方式一：使用 --set-version-var\n\n`go-to-wheel` 可以自动将版本号嵌入到 Go 二进制文件中。首先在 Go 代码中声明一个 version 变量：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if os.Args[1] == \"--version\" {\n        fmt.Println(version) // 构建后将输出 \"2.0.0\"\n    }\n}\n```\n\n然后使用 `--set-version-var` 参数：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n这会传递 `-X main.version=2.0.0` 给 Go 链接器。\n\n### 方式二：使用 --ldflags\n\n传递任意 Go 链接器标志：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 \\\n  --ldflags \"-X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n标志会被追加到默认的 `-s -w`，最终链接器调用为：\n```\n-ldflags=\"-s -w -X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n资料来源：[README.md - Examples](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n## 安装生成的 Wheel\n\n### 使用 pip 安装\n\n```bash\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n### 使用 uv 测试\n\n```bash\nuv run --with ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl mytool --help\n```\n\n### 使用 pipx 安装为全局命令\n\n```bash\npipx install ./dist/mytool-1.0.0-py3-none-*.whl\n```\n\n安装后，Go 二进制文件会自动添加到 PATH，可以直接运行：\n\n```bash\nmytool --help\n```\n\n## 内部构建机制\n\n### 编译参数\n\n`go-to-wheel` 使用以下参数构建 Go 二进制文件：\n\n| 参数 | 值 | 作用 |\n|------|-----|------|\n| CGO_ENABLED | 0 | 禁用 CGO，确保静态链接 |\n| -ldflags | -s -w | 剥离调试信息，减小体积 |\n\n```bash\nGOOS={goos} GOARCH={goarch} CGO_ENABLED=0 go build \\\n  -ldflags=\"-s -w\" \\\n  -o {output_path} \\\n  {go_module_path}\n```\n\n资料来源：[spec.md - Cross-Compile](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### Wheel 包结构\n\n生成的 Wheel 包含以下文件结构：\n\n```\n{package_name}-{version}-py3-none-{platform_tag}.whl\n├── {package_name}/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── {binary_name}[.exe]\n├── {package_name}-{version}.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n### Python 包装器\n\n`__init__.py` 包含一个包装函数，负责执行打包的二进制文件：\n\n```python\ndef main():\n    \"\"\"Execute the bundled binary.\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows 上使用 subprocess 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix 上使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n资料来源：[spec.md - Package Structure](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n## 开发调试\n\n### 本地开发安装\n\n```bash\ngit clone https://github.com/simonw/go-to-wheel\ncd go-to-wheel\n```\n\n### 运行测试\n\n```bash\nuv run pytest\n```\n\n## 故障排除\n\n### 常见问题\n\n| 问题 | 可能原因 | 解决方案 |\n|------|----------|----------|\n| \"Go directory not found\" | 指定路径不存在 | 确认路径正确 |\n| \"no go.mod file found\" | 目录不是 Go 模块 | 确认目录下有 go.mod |\n| \"Go compilation failed\" | Go 编译错误 | 检查 Go 代码语法 |\n| 安装后命令找不到 | PATH 未刷新 | 重新打开终端或 source 相关配置 |\n\n### 调试模式\n\n如需查看详细构建过程，可检查命令输出。`go-to-wheel` 会打印正在构建的平台信息：\n\n```\n$ go-to-wheel ./myapp --name myapp-bin\n\nlinux_amd64.whl\n  ✓ myapp_bin-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n  ✓ myapp_bin-1.0.0-py3-none-manylinux_2_17_aarch64.whl\n  ...\n\nDone! Built 8 wheels in ./dist\n```\n\n## 下一步\n\n- 查看完整[使用文档](README.md)了解更多高级用法\n- 参考 [spec.md](spec.md) 了解技术规格\n- 探索类似项目 [maturin](https://github.com/PyO3/maturin)（Rust 等价工具）\n\n---\n\n<a id='page-8'></a>\n\n## 高级用法与示例\n\n### 相关页面\n\n相关主题：[快速开始](#page-7), [Go 交叉编译流程](#page-5), [元数据配置](#page-4)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 高级用法与示例\n\n## 概览\n\n`go-to-wheel` 是一款将 Go CLI 程序编译为 Python wheel 分发包的命令行工具。在掌握基础用法后，本页将深入介绍其高级特性，包括跨平台精细化控制、版本信息嵌入、完整 PyPI 元数据配置等高级功能，帮助开发者将该工具集成到生产级发布流程中。\n\n资料来源：[README.md:1-50](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n## 核心参数详解\n\n### 完整参数对照表\n\n| 参数 | 说明 | 默认值 |\n|------|------|--------|\n| `--name` | Python 包名称 | 目录basename |\n| `--version` | 包版本号 | `0.1.0` |\n| `--output-dir` | 构建产物输出目录 | `./dist` |\n| `--entry-point` | CLI 命令名称 | 与包名相同 |\n| `--platforms` | 目标平台列表（逗号分隔） | 全部支持平台 |\n| `--go-binary` | Go 二进制文件路径 | `go` |\n| `--description` | 包描述 | `\"Go binary packaged as Python wheel\"` |\n| `--license` | 许可证标识符 | None |\n| `--author` | 作者姓名 | None |\n| `--author-email` | 作者邮箱 | None |\n| `--url` | 项目主页 | None |\n| `--requires-python` | Python 版本要求 | `>=3.10` |\n| `--readme` | README markdown 文件路径 | None |\n| `--set-version-var` | Go 变量名，用于嵌入版本 | None |\n| `--ldflags` | 额外 Go 链接器标志 | None |\n\n资料来源：[README.md:60-90](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n## 跨平台构建控制\n\n### 架构流程\n\n```mermaid\ngraph TD\n    A[go-to-wheel 命令] --> B[解析 --platforms 参数]\n    B --> C{平台列表为空?}\n    C -->|是| D[使用 DEFAULT_PLATFORMS]\n    C -->|否| E[解析用户指定平台]\n    D --> F[循环遍历目标平台]\n    E --> F\n    F --> G[GOOS/GOARCH 环境变量]\n    G --> H[CGO_ENABLED=0 静态编译]\n    H --> I[生成 wheel 文件]\n    I --> J[输出到 --output-dir]\n    J --> K[打印构建摘要]\n```\n\n### 支持的平台与 Wheel 标签映射\n\n| 平台标识 | GOOS | GOARCH | Wheel Tag |\n|----------|------|--------|-----------|\n| `linux-amd64` | linux | amd64 | `manylinux_2_17_x86_64` |\n| `linux-arm64` | linux | arm64 | `manylinux_2_17_aarch64` |\n| `linux-amd64-musl` | linux | amd64 | `musllinux_1_2_x86_64` |\n| `linux-arm64-musl` | linux | arm64 | `musllinux_1_2_aarch64` |\n| `darwin-amd64` | darwin | amd64 | `macosx_10_9_x86_64` |\n| `darwin-arm64` | darwin | arm64 | `macosx_11_0_arm64` |\n| `windows-amd64` | windows | amd64 | `win_amd64` |\n| `windows-arm64` | windows | arm64 | `win_arm64` |\n\n资料来源：[README.md:95-120](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n### 选择性构建特定平台\n\n```bash\n# 仅构建 Linux amd64 和 macOS ARM64\ngo-to-wheel ./mytool --platforms linux-amd64,darwin-arm64\n\n# 仅构建 Windows 版本\ngo-to-wheel ./mytool --platforms windows-amd64,windows-arm64\n```\n\n这种选择性构建能力允许开发者根据目标部署环境优化 CI/CD 流程，减少不必要的构建时间和存储空间。\n\n---\n\n## 版本嵌入与链接器标志\n\n### 编译参数合并逻辑\n\n`go-to-wheel` 在构建时会自动合并链接器标志，遵循以下优先级：\n\n1. 默认标志：`-s -w`（去除符号表和调试信息）\n2. 版本变量标志：`-X {var}={version}`（如果指定了 `--set-version-var`）\n3. 用户自定义标志：`--ldflags` 中的值\n\n资料来源：[go_to_wheel/__init__.py:180-200](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n```mermaid\ngraph LR\n    A[默认 ldflags<br/>-s -w] --> C[最终 ldflags]\n    B[--ldflags] --> C\n    D[--set-version-var] -->|先处理| B\n```\n\n### 使用 `--set-version-var` 自动嵌入版本\n\n当 Go 源代码中定义了 `version` 变量时，可通过此参数自动注入版本信息：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 --set-version-var main.version\n```\n\n对应的 Go 代码示例：\n\n```go\nvar version = \"dev\"\n\nfunc main() {\n    if len(os.Args) > 1 && os.Args[1] == \"--version\" {\n        fmt.Println(version)\n    }\n    // 其他逻辑...\n}\n```\n\n编译后，执行 `mytool --version` 将输出 `2.0.0`。\n\n资料来源：[README.md:35-55](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n### 高级链接器标志使用\n\n通过 `--ldflags` 传递任意链接器标志：\n\n```bash\ngo-to-wheel ./mytool --version 2.0.0 \\\n  --ldflags \"-X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n完整链接器调用变为：\n```\n-ldflags=\"-s -w -X main.version=2.0.0 -X main.commit=abc123\"\n```\n\n---\n\n## 完整 PyPI 发布元数据配置\n\n### 最小发布配置\n\n```bash\ngo-to-wheel ./mytool \\\n  --name mytool-bin \\\n  --version 2.0.0 \\\n  --description \"My awesome tool\" \\\n  --license MIT \\\n  --author \"Jane Doe\" \\\n  --author-email \"jane@example.com\" \\\n  --url \"https://github.com/jane/mytool\" \\\n  --readme README.md\n```\n\n### 生成的文件结构\n\n每个 wheel 包内部遵循 PEP 427 标准结构：\n\n```\n{mytool_bin-2.0.0-py3-none-manylinux_2_17_x86_64.whl}/\n├── mytool_bin/\n│   ├── __init__.py\n│   ├── __main__.py\n│   └── bin/\n│       └── mytool_bin\n├── mytool_bin-2.0.0.dist-info/\n│   ├── METADATA\n│   ├── WHEEL\n│   ├── RECORD\n│   └── entry_points.txt\n```\n\n资料来源：[spec.md:80-130](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### METADATA 文件内容生成\n\n```python\ndef generate_metadata(\n    name: str,\n    version: str,\n    description: str,\n    author: str | None = None,\n    author_email: str | None = None,\n    license_: str | None = None,\n    url: str | None = None,\n    requires_python: str = \">=3.10\",\n    readme_content: str | None = None,\n) -> str:\n```\n\n生成的 METADATA 文件遵循 PEP 566 标准，包含所有必需字段。\n\n资料来源：[go_to_wheel/__init__.py:50-90](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 内部封装机制\n\n### Python 包装器工作原理\n\n生成的 `__init__.py` 文件包含以下核心功能：\n\n```python\n\"\"\"Go binary packaged as Python wheel.\"\"\"\n\nimport os\nimport stat\nimport subprocess\nimport sys\n\n__version__ = \"{version}\"\n\ndef get_binary_path():\n    \"\"\"返回捆绑二进制文件的路径\"\"\"\n    return os.path.join(os.path.dirname(__file__), \"bin\", \"{binary_name}\")\n\ndef main():\n    \"\"\"执行捆绑的二进制文件\"\"\"\n    binary = get_binary_path()\n    if sys.platform == \"win32\":\n        # Windows: 使用 subprocess 处理信号\n        sys.exit(subprocess.call([binary] + sys.argv[1:]))\n    else:\n        # Unix: 使用 exec 替换进程\n        os.execvp(binary, [binary] + sys.argv[1:])\n```\n\n资料来源：[spec.md:100-140](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### 跨平台执行策略\n\n```mermaid\ngraph TD\n    A[pip install wheel] --> B[执行 entry_points.txt]\n    B --> C[调用 mypackage:main]\n    C --> D{检测 sys.platform}\n    D -->|win32| E[subprocess.call]\n    D -->|Unix| F[os.execvp]\n    E --> G[启动 Go 二进制]\n    F --> G\n```\n\n这种设计确保了在所有平台上都能获得一致的命令行体验，同时保持了 `pipx` 的完全兼容性。\n\n资料来源：[spec.md:140-150](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n---\n\n## 构建流程详解\n\n### 完整编译流程\n\n```mermaid\nflowchart TD\n    A[验证 go.mod 存在] --> B{--readme 参数?}\n    B -->|是| C[读取 README 内容]\n    B -->|否| D[继续]\n    C --> E[解析平台列表]\n    D --> E\n    E --> F{平台列表为空?}\n    F -->|是| G[使用 DEFAULT_PLATFORMS]\n    F -->|否| H[使用指定平台]\n    G --> I[遍历每个平台]\n    H --> I\n    I --> J[设置环境变量<br/>GOOS, GOARCH, CGO_ENABLED=0]\n    J --> K[go build 编译]\n    K --> L{编译成功?}\n    L -->|否| M[抛出 RuntimeError]\n    L -->|是| N[创建 wheel 目录结构]\n    N --> O[生成 __init__.py, __main__.py]\n    O --> P[生成 METADATA, WHEEL, entry_points.txt]\n    P --> Q[计算 RECORD 哈希]\n    Q --> R[压缩为 .whl 文件]\n    R --> S{还有更多平台?}\n    S -->|是| I\n    S -->|否| T[输出摘要]\n```\n\n资料来源：[spec.md:150-200](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n### 编译命令构造\n\n```python\nenv = os.environ.copy()\nenv[\"GOOS\"] = goos\nenv[\"GOARCH\"] = goarch\nenv[\"CGO_ENABLED\"] = \"0\"\n\nldflags_value = \"-s -w\"\nif ldflags:\n    ldflags_value += \" \" + ldflags\n\ncmd = [\n    go_binary,\n    \"build\",\n    f\"-ldflags={ldflags_value}\",\n    \"-o\",\n    output_path,\n    \".\",\n]\n```\n\n关键编译参数说明：\n- `CGO_ENABLED=0`：禁用 C 绑定，确保生成静态二进制文件\n- `-ldflags=\"-s -w\"`：去除调试信息，减小二进制体积\n- Windows 平台自动添加 `.exe` 扩展名\n\n资料来源：[go_to_wheel/__init__.py:210-240](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 常见使用场景\n\n### 场景一：GitHub Actions CI/CD 集成\n\n```yaml\n- name: Build Python wheels\n  run: |\n    go-to-wheel ./cmd/mytool \\\n      --name mytool \\\n      --version ${{ github.ref_name }} \\\n      --set-version-var main.version \\\n      --author \"${{ github.event.sender.login }}\" \\\n      --url \"https://github.com/${{ github.repository }}\" \\\n      --readme README.md\n  env:\n    GO_BINARY: /usr/local/bin/go\n```\n\n### 场景二：多入口点包管理\n\n对于生成多个可执行文件的 Go 模块：\n\n```bash\n# 构建主工具\ngo-to-wheel ./cmd/cli --name mycli --entry-point mycli\n\n# 构建辅助工具\ngo-to-wheel ./cmd/helper --name mycli-helper --entry-point mycli-helper\n```\n\n### 场景三：自定义 Go 编译器路径\n\n```bash\n# 使用项目本地 Go 安装\ngo-to-wheel ./mytool --go-binary /opt/go/bin/go\n\n# 使用 Docker 容器内的 Go\ndocker run --rm -v $(pwd):/workspace golang:1.21 \\\n  go-to-wheel /workspace/mytool --go-binary go\n```\n\n### 场景四：musl 静态链接（Alpine Linux 兼容）\n\n```bash\ngo-to-wheel ./mytool --platforms linux-amd64-musl,linux-arm64-musl\n```\n\n生成的 wheel 使用 `musllinux` 标签，适用于 Alpine Linux 等使用 musl libc 的发行版。\n\n---\n\n## 依赖与要求\n\n### 构建环境要求\n\n| 组件 | 最低版本 | 说明 |\n|------|----------|------|\n| Python | >= 3.10 | 运行时环境 |\n| Go | >= 1.16 | 编译目标代码 |\n\n### 工具本身依赖\n\n`go-to-wheel` 零外部 Python 依赖，完全使用标准库实现：\n\n- `argparse`：命令行参数解析\n- `csv`：RECORD 文件生成\n- `hashlib`：SHA256 哈希计算\n- `os`/`pathlib`：文件系统操作\n- `stat`：文件权限处理\n- `subprocess`：Go 编译调用\n- `zipfile`：wheel 打包\n\n资料来源：[spec.md:250-260](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n\n---\n\n## 故障排除\n\n### 常见错误及解决方案\n\n| 错误信息 | 原因 | 解决方案 |\n|----------|------|----------|\n| `FileNotFoundError: go directory not found` | 指定路径不存在 | 检查 `--name` 参数后的路径 |\n| `ValueError: Not a Go module` | 目录缺少 `go.mod` | 确保在 Go 模块根目录执行 |\n| `RuntimeError: Go compilation failed` | Go 编译错误 | 检查 Go 代码语法或 `CGO_ENABLED=0` 兼容性 |\n| `Error: No wheels were built` | 无有效目标平台 | 验证 `--platforms` 参数是否有效 |\n\n资料来源：[go_to_wheel/__init__.py:260-290](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n\n---\n\n## 验证构建结果\n\n### 查看 wheel 内容\n\n```bash\n# 解压查看结构\nunzip -l dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n\n# 提取并检查二进制\nunzip -p dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl \\\n  mytool/bin/mytool | file -\n```\n\n### 测试安装\n\n```bash\n# 使用 uv 测试安装\nuv run --with ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl mytool --help\n\n# 使用 pip 安装\npip install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n\n# 使用 pipx 安装（推荐用于命令行工具）\npipx install ./dist/mytool-1.0.0-py3-none-manylinux_2_17_x86_64.whl\n```\n\n资料来源：[README.md:125-145](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n\n---\n\n<a id='page-9'></a>\n\n## 开发环境搭建\n\n### 相关页面\n\n相关主题：[相关项目与参考](#page-10), [快速开始](#page-7)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n- [pyproject.toml](https://github.com/simonw/go-to-wheel/blob/main/pyproject.toml)\n- [tests/test_cli.py](https://github.com/simonw/go-to-wheel/blob/main/tests/test_cli.py)\n</details>\n\n# 开发环境搭建\n\n## 概述\n\n`go-to-wheel` 是一个用于将 Go CLI 程序编译为 Python wheel 的工具。本页面详细介绍如何搭建该项目的开发环境，包括环境准备、源码获取、依赖安装以及测试验证等完整流程。\n\n该工具的核心功能是通过 Go 交叉编译生成多平台二进制文件，并将其打包为符合 PEP 427 规范的 Python wheel，实现通过 `pip` 或 `pipx` 分发 Go 程序的目的。资料来源：[README.md](https://github.com/simonw/go-to-wheel)\n\n## 前置条件\n\n### 系统要求\n\n| 组件 | 最低版本 | 说明 |\n|------|----------|------|\n| Python | >= 3.10 | 项目使用结构化模式匹配等新特性 |\n| Go | >= 1.16 | 支持 `go mod` 模块化构建 |\n| Git | 任意版本 | 用于克隆源码仓库 |\n\n### 环境检查\n\n在开始搭建开发环境前，请确保目标系统已安装上述必要组件。可以通过以下命令验证：\n\n```bash\n# 检查 Python 版本\npython --version\n\n# 检查 Go 版本\ngo version\n\n# 检查 Git 版本\ngit --version\n```\n\n## 获取源码\n\n### 克隆仓库\n\n使用 Git 将项目源码克隆到本地：\n\n```bash\ngit clone https://github.com/simonw/go-to-wheel\ncd go-to-wheel\n```\n\n克隆完成后，目录结构应包含以下核心文件和目录：\n\n```\ngo-to-wheel/\n├── go_to_wheel/          # 主模块目录\n│   └── __init__.py       # 核心功能实现\n├── tests/                # 测试目录\n│   └── test_cli.py       # CLI 测试用例\n├── README.md             # 项目说明文档\n├── SPEC.md               # 详细规格说明\n└── pyproject.toml        # 项目配置\n```\n\n资料来源：[README.md - Development](https://github.com/simonw/go-to-wheel)\n\n## 依赖管理\n\n### 项目配置\n\n项目使用 `pyproject.toml` 管理依赖和构建配置。核心依赖声明如下：\n\n```toml\n[project]\nrequires-python = \">=3.10\"\ndependencies = []\n```\n\n值得注意的是，`go-to-wheel` 本身不依赖任何外部 Python 包，仅使用 Python 标准库完成所有功能。资料来源：[spec.md - Dependencies](https://github.com/simonw/go-to-wheel)\n\n### 安装开发依赖\n\n推荐使用 `uv` 作为 Python 包管理工具。若未安装，可通过以下方式安装：\n\n```bash\n# 安装 uv\npip install uv\n```\n\n安装项目及其开发依赖：\n\n```bash\n# 使用 uv 安装项目为可编辑模式\nuv pip install -e .\n\n# 或直接使用 uv run 运行命令（无需预先安装）\nuv run pytest\n```\n\n## 项目结构解析\n\n### 核心模块\n\n`go_to_wheel/__init__.py` 是项目的主模块，包含以下关键组件：\n\n| 组件 | 功能 |\n|------|------|\n| `PLATFORM_MAPPINGS` | Go 平台标识到 wheel 平台标签的映射表 |\n| `DEFAULT_PLATFORMS` | 默认构建的所有目标平台列表 |\n| `build_wheels()` | 核心构建函数，生成 wheel 包 |\n| `generate_metadata()` | 生成 wheel METADATA 文件 |\n| `generate_wheel_file()` | 生成 WHEEL 规范文件 |\n| `generate_entry_points()` | 生成 entry_points.txt |\n| `generate_record()` | 生成 RECORD 文件 |\n\n资料来源：[go_to_wheel/__init__.py:1-50](https://github.com/simonw/go-to-wheel)\n\n### 平台支持矩阵\n\n项目默认支持以下 8 个目标平台：\n\n| 平台标识 | GOOS | GOARCH | Wheel 标签 |\n|----------|------|--------|------------|\n| linux-amd64 | linux | amd64 | manylinux_2_17_x86_64 |\n| linux-arm64 | linux | arm64 | manylinux_2_17_aarch64 |\n| linux-amd64-musl | linux | amd64 | musllinux_1_2_x86_64 |\n| linux-arm64-musl | linux | arm64 | musllinux_1_2_aarch64 |\n| darwin-amd64 | darwin | amd64 | macosx_10_9_x86_64 |\n| darwin-arm64 | darwin | arm64 | macosx_11_0_arm64 |\n| windows-amd64 | windows | amd64 | win_amd64 |\n| windows-arm64 | windows | arm64 | win_arm64 |\n\n资料来源：[go_to_wheel/__init__.py:30-40](https://github.com/simonw/go-to-wheel)\n\n## 运行测试\n\n### 测试执行\n\n使用 `uv` 运行完整的测试套件：\n\n```bash\nuv run pytest\n```\n\n测试覆盖以下核心功能：\n\n- 命令行参数解析\n- Go 目录验证逻辑\n- wheel 包生成流程\n- 元数据文件生成\n- 多平台构建支持\n\n资料来源：[README.md - Development](https://github.com/simonw/go-to-wheel)\n\n### 本地构建验证\n\n搭建完成后，可通过以下命令验证工具是否正常工作：\n\n```bash\n# 查看帮助信息\ngo-to-wheel --help\n\n# 或使用 uv 运行\nuv run go-to-wheel --help\n```\n\n## 构建流程架构\n\n```mermaid\ngraph TD\n    A[输入 Go 模块目录] --> B[验证 go.mod 存在]\n    B --> C{检查平台列表}\n    C -->|未指定| D[使用默认平台]\n    C -->|指定平台| E[解析平台参数]\n    D --> F[交叉编译 Go 二进制]\n    E --> F\n    F --> G[创建临时目录结构]\n    G --> H[生成 Python 包装代码]\n    H --> I[生成元数据文件]\n    I --> J[计算 RECORD 哈希]\n    J --> K[打包为 wheel]\n    K --> L[输出到 dist 目录]\n```\n\n## CLI 参数配置\n\n项目通过 argparse 定义命令行接口，关键参数如下：\n\n| 参数 | 类型 | 默认值 | 说明 |\n|------|------|--------|------|\n| `--name` | 字符串 | 目录名 | Python 包名称 |\n| `--version` | 字符串 | 0.1.0 | 包版本号 |\n| `--output-dir` | 字符串 | ./dist | 输出目录 |\n| `--platforms` | 字符串 | 全部平台 | 目标平台列表 |\n| `--go-binary` | 字符串 | go | Go 二进制路径 |\n| `--ldflags` | 字符串 | None | 链接器标志 |\n\n资料来源：[go_to_wheel/__init__.py:100-150](https://github.com/simonw/go-to-wheel)\n\n## 常见问题\n\n### Go 未找到\n\n**问题**：运行时报错 `go: command not found`\n\n**解决**：确保 Go 已安装且添加到系统 PATH 环境变量中。验证方法：\n\n```bash\nwhich go\ngo version\n```\n\n### Python 版本不兼容\n\n**问题**：报 `SyntaxError` 或功能异常\n\n**解决**：项目要求 Python >= 3.10，请升级 Python 版本：\n\n```bash\npython --version  # 确认版本\n```\n\n### 构建失败\n\n**问题**：wheel 构建过程中出错\n\n**解决**：\n\n1. 确认 Go 模块目录包含 `go.mod` 文件\n2. 检查目标平台的 Go 工具链是否可用\n3. 使用 `--go-binary` 指定 Go 二进制路径\n\n资料来源：[spec.md - Package Name Validation](https://github.com/simonw/go-to-wheel)\n\n## 后续步骤\n\n开发环境搭建完成后，可进行以下操作：\n\n1. **构建示例 wheel**：尝试构建一个简单的 Go 工具\n\n   ```bash\n   go-to-wheel ./path/to/go-module\n   ```\n\n2. **本地安装测试**：安装生成的 wheel 并验证功能\n\n   ```bash\n   pip install ./dist/*.whl\n   ```\n\n3. **参与开发**：阅读 `SPEC.md` 了解项目详细规格，提交 Pull Request\n\n## 参考链接\n\n- [项目 GitHub 仓库](https://github.com/simonw/go-to-wheel)\n- [Python wheel 规范 (PEP 427)](https://peps.python.org/pep-0427/)\n- [Go 交叉编译文档](https://go.dev/wiki/WindowsCrossCompiling)\n\n---\n\n<a id='page-10'></a>\n\n## 相关项目与参考\n\n### 相关页面\n\n相关主题：[项目简介](#page-1), [系统架构](#page-2)\n\n<details>\n<summary>相关源码文件</summary>\n\n以下源码文件用于生成本页说明：\n\n- [README.md](https://github.com/simonw/go-to-wheel/blob/main/README.md)\n- [go_to_wheel/__init__.py](https://github.com/simonw/go-to-wheel/blob/main/go_to_wheel/__init__.py)\n- [spec.md](https://github.com/simonw/go-to-wheel/blob/main/spec.md)\n</details>\n\n# 相关项目与参考\n\n## 概述\n\n`go-to-wheel` 项目在设计和实现过程中参考了多个相关领域的开源项目和技术方案。理解这些相关项目有助于开发者把握该工具在生态系统中的定位，以及它与其他类似工具的关系和区别。\n\n本页面详细介绍 `go-to-wheel` 所参考的技术方案、灵感来源以及功能相似的替代工具，帮助用户根据具体场景选择合适的工具。\n\n## 灵感来源：maturin\n\n### 项目简介\n\n[maturin](https://github.com/PyO3/maturin) 是一个将 Rust 程序打包为 Python wheels 的工具，由 PyO3 团队开发和维护。它是目前 Rust 语言生态中最为成熟的「将原生语言程序转化为 Python 可分发包」解决方案。\n\n`go-to-wheel` 的设计理念直接受到了 maturin 的启发。正如 README.md 中所述：\n\n> maturin 是 Rust 的等效工具，启发了这个工具\n\n资料来源：[README.md:1]()\n\n### 核心功能对比\n\n| 特性 | maturin | go-to-wheel |\n|------|---------|-------------|\n| 源语言 | Rust | Go |\n| 绑定方式 | PyO3 绑定 + 直接 exec | 仅 exec 封装 |\n| 跨平台支持 | ✅ | ✅ |\n| CGO 支持 | 允许 | 禁用 (CGO_ENABLED=0) |\n| 依赖库 | PyO3, setuptools-rust | 仅标准库 |\n| 入口点类型 | console_scripts, pypi scripts | console_scripts |\n\n资料来源：[README.md:1](), [spec.md:1]()\n\n### 设计理念传承\n\nmaturin 的核心设计原则被 `go-to-wheel` 继承：\n\n1. **简化分发**：用户只需一条命令即可将原生程序转化为可通过 pip 安装的 wheel 包\n2. **跨平台兼容**：自动为多个目标平台编译二进制文件\n3. **最小依赖**：编译后的 wheel 包尽量减少运行时依赖\n4. **PEP 标准**：严格遵循 Python 打包规范 (PEP 427, PEP 566)\n\n资料来源：[spec.md:1]()\n\n## 模板项目：pip-binary-factory\n\n### 项目简介\n\n[pip-binary-factory](https://github.com/Bing-su/pip-binary-factory) 是一个用于打包预编译二进制文件的 Python 模板项目。它提供了将各种语言的预编译二进制文件封装为 PyPI 可分发包的参考实现。\n\nREADME.md 中将其描述为「用于打包预编译二进制文件的模板」：\n\n> pip-binary-factory - 用于打包预编译二进制文件的模板\n\n资料来源：[README.md:1]()\n\n### 与 go-to-wheel 的关系\n\n`go-to-wheel` 与 pip-binary-factory 解决的是不同层次的问题：\n\n```mermaid\ngraph TD\n    A[预编译二进制分发] --> B[pip-binary-factory]\n    A --> C[源代码编译分发]\n    C --> D[go-to-wheel]\n    B --> E[已有二进制文件]\n    D --> F[需要编译的 Go 源码]\n    \n    style B fill:#e1f5fe\n    style D fill:#fff3e0\n```\n\n| 维度 | pip-binary-factory | go-to-wheel |\n|------|-------------------|-------------|\n| 输入 | 预编译的二进制文件 | Go 源代码 |\n| 编译过程 | 无需编译 | 集成跨平台编译 |\n| 适用场景 | 已有二进制或第三方编译产物 | 需要从源码构建的场景 |\n| 工作流程 | 模板填充 + 打包 | 编译 + 打包一体化 |\n\n资料来源：[README.md:1]()\n\n## 技术背景：Python 打包生态\n\n### 相关 PEP 标准\n\n`go-to-wheel` 严格遵循以下 Python 打包标准：\n\n```mermaid\ngraph LR\n    A[go-to-wheel] --> B[PEP 427]\n    A --> C[PEP 376]\n    A --> D[PEP 566]\n    \n    B --> E[Wheel 格式规范]\n    C --> F[RECORD 文件规范]\n    D --> G[元数据格式]\n```\n\n| PEP 编号 | 名称 | go-to-wheel 实现 |\n|----------|------|------------------|\n| PEP 427 | Wheel Binary Package Format | 生成符合规范的 .whl 文件 |\n| PEP 376 | Database of Installed Python Distributions | 实现 RECORD 文件和 dist-info 目录 |\n| PEP 566 | Metadata Version 2.1 | 生成符合 2.1 版本的 METADATA |\n\n资料来源：[spec.md:1](), [go_to_wheel/__init__.py:1]()\n\n### 核心元数据文件\n\n`go-to-wheel` 生成的 wheel 包包含以下标准文件：\n\n```\n{package_name}-{version}.dist-info/\n├── METADATA        # 包元数据 (PEP 566)\n├── WHEEL           # Wheel 标记 (PEP 427)\n├── RECORD          # 文件哈希记录 (PEP 376)\n└── entry_points.txt  # 入口点定义\n```\n\n资料来源：[spec.md:1]()\n\n## 替代工具方案\n\n### 现有方案对比\n\n在 Go 程序 Python 分发领域，存在以下几种替代方案：\n\n| 方案 | 优点 | 缺点 |\n|------|------|------|\n| 手动编译 + pip install | 完全可控 | 需用户配置 Go 环境 |\n| Docker 镜像分发 | 隔离性好 | 部署复杂，不符合 Python 生态习惯 |\n| go-to-wheel | 一站式解决方案 | 仅支持 Go 语言 |\n| 预编译 wheels | 用户无编译等待 | 维护成本高 |\n\n资料来源：[README.md:1]()\n\n### go-to-wheel 的独特价值\n\n`go-to-wheel` 填补了 Go 生态在 Python 打包领域的关键空白：\n\n```mermaid\ngraph TD\n    A[Go 开发者] --> B{如何分发 CLI 工具?}\n    B --> C[手动编译]\n    B --> D[Docker]\n    B --> E[go-to-wheel]\n    \n    C --> F[用户体验差]\n    D --> G[不符合 Python 习惯]\n    E --> H[✅ Python 原生分发]\n    \n    style E fill:#c8e6c9\n    style H fill:#c8e6c9\n```\n\n## 参考文献\n\n### 相关链接\n\n| 项目 | 仓库地址 | 说明 |\n|------|----------|------|\n| maturin | https://github.com/PyO3/maturin | Rust 程序的 Python wheel 打包工具 |\n| pip-binary-factory | https://github.com/Bing-su/pip-binary-factory | 预编译二进制打包模板 |\n\n### 延伸阅读\n\n- [Distributing Go binaries like sqlite-scanner through PyPI using go-to-wheel](https://simonwillison.net/2026/Feb/4/distributing-go-binaries/) - 项目作者关于 go-to-wheel 设计背景的博客文章\n\n资料来源：[README.md:1]()\n\n---\n\n---\n\n## Doramagic 踩坑日志\n\n项目：simonw/go-to-wheel\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | release_recency=unknown\n\n<!-- canonical_name: simonw/go-to-wheel; human_manual_source: deepwiki_human_wiki -->\n",
      "summary": "DeepWiki/Human Wiki 完整输出，末尾追加 Discovery Agent 踩坑日志。",
      "title": "Human Manual / 人类版说明书"
    },
    "pitfall_log": {
      "asset_id": "pitfall_log",
      "filename": "PITFALL_LOG.md",
      "markdown": "# Pitfall Log / 踩坑日志\n\n项目：simonw/go-to-wheel\n\n摘要：发现 6 个潜在踩坑项，其中 0 个为 high/blocking；最高优先级：能力坑 - 能力判断依赖假设。\n\n## 1. 能力坑 · 能力判断依赖假设\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：README/documentation is current enough for a first validation pass.\n- 对用户的影响：假设不成立时，用户拿不到承诺的能力。\n- 建议检查：将假设转成下游验证清单。\n- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。\n- 证据：capability.assumptions | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | README/documentation is current enough for a first validation pass.\n\n## 2. 维护坑 · 维护活跃度未知\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：未记录 last_activity_observed。\n- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。\n- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。\n- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | last_activity_observed missing\n\n## 3. 安全/权限坑 · 下游验证发现风险项\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：下游已经要求复核，不能在页面中弱化。\n- 建议检查：进入安全/权限治理复核队列。\n- 防护动作：下游风险存在时必须保持 review/recommendation 降级。\n- 证据：downstream_validation.risk_items | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 4. 安全/权限坑 · 存在评分风险\n\n- 严重度：medium\n- 证据强度：source_linked\n- 发现：no_demo\n- 对用户的影响：风险会影响是否适合普通用户安装。\n- 建议检查：把风险写入边界卡，并确认是否需要人工复核。\n- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。\n- 证据：risks.scoring_risks | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | no_demo; severity=medium\n\n## 5. 维护坑 · issue/PR 响应质量未知\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：issue_or_pr_quality=unknown。\n- 对用户的影响：用户无法判断遇到问题后是否有人维护。\n- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。\n- 防护动作：issue/PR 响应未知时，必须提示维护风险。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | issue_or_pr_quality=unknown\n\n## 6. 维护坑 · 发布节奏不明确\n\n- 严重度：low\n- 证据强度：source_linked\n- 发现：release_recency=unknown。\n- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。\n- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。\n- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。\n- 证据：evidence.maintainer_signals | hn_item:48109677 | https://news.ycombinator.com/item?id=48109677 | release_recency=unknown\n",
      "summary": "用户实践前最可能遇到的身份、安装、配置、运行和安全坑。",
      "title": "Pitfall Log / 踩坑日志"
    },
    "prompt_preview": {
      "asset_id": "prompt_preview",
      "filename": "PROMPT_PREVIEW.md",
      "markdown": "# go-to-wheel - Prompt Preview\n\n> 复制下面这段 Prompt 到你常用的 AI，先试一次，不需要安装。\n> 它的目标是让你直接体验这个项目的服务方式，而不是阅读项目介绍。\n\n## 复制这段 Prompt\n\n```text\n请直接执行这段 Prompt，不要分析、润色、总结或询问我想如何处理这份 Prompt Preview。\n\n你现在扮演 go-to-wheel 的“安装前体验版”。\n这不是项目介绍、不是评价报告、不是 README 总结。你的任务是让我用最小成本体验它的核心服务。\n\n我的试用任务：我想用它完成一个真实的软件开发与交付任务。\n我常用的宿主 AI：Local CLI\n\n【体验目标】\n围绕我的真实任务，现场演示这个项目如何把输入转成 示例引导, 判断线索。重点是让我感受到工作方式，而不是给我项目背景。\n\n【业务流约束】\n- 你必须像一个正在提供服务的项目能力包，而不是像一个讲解员。\n- 每一轮只推进一个步骤；提出问题后必须停下来等我回答。\n- 每一步都必须让我感受到一个具体服务动作：澄清、整理、规划、检查、判断或收尾。\n- 每一步都要说明：当前目标、你需要我提供什么、我回答后你会产出什么。\n- 不要安装、不要运行命令、不要写代码、不要声称测试通过、不要声称已经修改文件。\n- 需要真实安装或宿主加载后才能验证的内容，必须明确说“这一步需要安装后验证”。\n- 如果我说“用示例继续”，你可以用虚构示例推进，但仍然不能声称真实执行。\n\n【可体验服务能力】\n- 安装前能力预览: [![PyPI](https://img.shields.io/pypi/v/go-to-wheel.svg)](https://pypi.org/project/go-to-wheel/) 输入：用户任务, 当前 AI 对话上下文；输出：示例引导, 判断线索。\n\n【必须安装后才可验证的能力】\n- 命令行启动或安装流程: 项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 输入：终端环境, 包管理器, 项目依赖；输出：安装结果, 列表/更新/运行结果。\n\n【核心服务流】\n请严格按这个顺序带我体验。不要一次性输出完整流程：\n1. page-1：项目简介。围绕“项目简介”模拟一次用户任务，不展示安装或运行结果。\n2. page-2：系统架构。围绕“系统架构”模拟一次用户任务，不展示安装或运行结果。\n3. page-3：支持的平台。围绕“支持的平台”模拟一次用户任务，不展示安装或运行结果。\n4. page-5：Go 交叉编译流程。围绕“Go 交叉编译流程”模拟一次用户任务，不展示安装或运行结果。\n5. page-6：Wheel 生成机制。围绕“Wheel 生成机制”模拟一次用户任务，不展示安装或运行结果。\n\n【核心能力体验剧本】\n每一步都必须按“输入 -> 服务动作 -> 中间产物”执行。不要只说流程名：\n1. page-1\n输入：用户提供的“项目简介”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n2. page-2\n输入：用户提供的“系统架构”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n3. page-3\n输入：用户提供的“支持的平台”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n4. page-5\n输入：用户提供的“Go 交叉编译流程”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n5. page-6\n输入：用户提供的“Wheel 生成机制”相关信息。\n服务动作：模拟项目在这一步的核心判断和整理方式。\n中间产物：一个可检查的小结果。\n\n【项目服务规则】\n这些规则决定你如何服务用户。不要解释规则本身，而要在每一步执行时遵守：\n- 先确认用户任务、输入材料和成功标准，再模拟项目能力。\n- 每一步都必须形成可检查的小产物，并等待用户确认后再继续。\n- 凡是需要安装、调用工具或访问外部服务的能力，都必须标记为安装后验证。\n\n【每一步的服务约束】\n- Step 1 / page-1：Step 1 必须围绕“项目简介”形成一个小中间产物，并等待用户确认。\n- Step 2 / page-2：Step 2 必须围绕“系统架构”形成一个小中间产物，并等待用户确认。\n- Step 3 / page-3：Step 3 必须围绕“支持的平台”形成一个小中间产物，并等待用户确认。\n- Step 4 / page-5：Step 4 必须围绕“Go 交叉编译流程”形成一个小中间产物，并等待用户确认。\n- Step 5 / page-6：Step 5 必须围绕“Wheel 生成机制”形成一个小中间产物，并等待用户确认。\n\n【边界与风险】\n- 不要声称已经安装、运行、调用 API、读写本地文件或完成真实任务。\n- 安装前预览只能展示工作方式，不能证明兼容性、性能或输出质量。\n- 涉及安装、插件加载、工具调用或外部服务的能力必须安装后验证。\n\n【可追溯依据】\n这些路径只用于你内部校验或在我追问“依据是什么”时简要引用。不要在首次回复主动展开：\n- https://news.ycombinator.com/item?id=48109677\n- https://github.com/simonw/go-to-wheel#readme\n- README.md\n- spec.md\n- go_to_wheel/__init__.py\n\n【首次问题规则】\n- 首次三问必须先确认用户目标、成功标准和边界，不要提前进入工具、安装或实现细节。\n- 如果后续需要技术条件、文件路径或运行环境，必须等用户确认目标后再追问。\n\n首次回复必须只输出下面 4 个部分：\n1. 体验开始：用 1 句话说明你将带我体验 go-to-wheel 的核心服务。\n2. 当前步骤：明确进入 Step 1，并说明这一步要解决什么。\n3. 你会如何服务我：说明你会先改变我完成任务的哪个动作。\n4. 只问我 3 个问题，然后停下等待回答。\n\n首次回复禁止输出：后续完整流程、证据清单、安装命令、项目评价、营销文案、已经安装或运行的说法。\n\nStep 1 / brainstorming 的二轮协议：\n- 我回答首次三问后，你仍然停留在 Step 1 / brainstorming，不要进入 Step 2。\n- 第二次回复必须产出 6 个部分：澄清后的任务定义、成功标准、边界条件、\n  2-3 个可选方案、每个方案的权衡、推荐方案。\n- 第二次回复最后必须问我是否确认推荐方案；只有我明确确认后，才能进入下一步。\n- 第二次回复禁止输出 git worktree、代码计划、测试文件、命令或真实执行结果。\n\n后续对话规则：\n- 我回答后，你先完成当前步骤的中间产物并等待确认；只有我确认后，才能进入下一步。\n- 每一步都要生成一个小的中间产物，例如澄清后的目标、计划草案、测试意图、验证清单或继续/停止判断。\n- 所有演示都写成“我会建议/我会引导/这一步会形成”，不要写成已经真实执行。\n- 不要声称已经测试通过、文件已修改、命令已运行或结果已产生。\n- 如果某个能力必须安装后验证，请直接说“这一步需要安装后验证”。\n- 如果证据不足，请明确说“证据不足”，不要补事实。\n```\n",
      "summary": "不安装项目也能感受能力节奏的安全试用 Prompt。",
      "title": "Prompt Preview / 安装前试用 Prompt"
    },
    "quick_start": {
      "asset_id": "quick_start",
      "filename": "QUICK_START.md",
      "markdown": "# Quick Start / 官方入口\n\n项目：simonw/go-to-wheel\n\n## 官方安装入口\n\n### Python / pip · 官方安装入口\n\n```bash\npip install go-to-wheel\n```\n\n来源：https://github.com/simonw/go-to-wheel#readme\n\n## 来源\n\n- hn: https://news.ycombinator.com/item?id=48109677\n- docs: https://github.com/simonw/go-to-wheel#readme\n",
      "summary": "从项目官方 README 或安装文档提取的开工入口。",
      "title": "Quick Start / 官方入口"
    }
  },
  "validation_id": "dval_b7241181c1994477a8167e0e79e3c2a9"
}
