Proposal: Platform-Specific Project Layout and Output

已关闭
#1,125 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
35/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
go
领域
tooling

调研方向

Start by reading the llcppg.cfg Dir rules and tracing how the CLI selects its source and destination directories. Then check how GOOS and GOARCH are obtained and where generated output is placed. Done means platform-prefixed inputs resolve to the expected platform directory, output is written under the matching destination subdirectory, and non-platform projects retain current behavior; the proposal leaves several design questions open.

由索引模型根据 Issue 内容生成。

描述

Architecture-Design configuration

Summary

llcppg currently assumes that a C/C++ library looks the same on every platform: one include directory, one generated Go package. That assumption breaks down for libraries whose headers differ per operating system and architecture, with libc being the most important example. This proposal introduces a minimal platform-awareness framework for llcppg.cfg. libc is used throughout as the motivating example, but nothing in the design is specific to it.

The core ideas are:

  1. Each platform is fully independent and lives in its own $GOOS-$GOARCH directory (for example darwin-arm64), following Go's own naming exactly.
  2. Dir in llcppg.cfg gains a mandatory $GOOS-$GOARCH/ prefix when the project is platform-specific.
  3. When converting, llcppg automatically places output under <dest-dir>/$GOOS-$GOARCH. Users never create the platform subdirectory themselves.

Motivation

libc is not one library. Each platform has a different maintainer and a different set of headers:

Platform libc provider
darwin macOS SDK (libSystem)
linux glibc, musl, or others
windows UCRT / MSVCRT

Their types, constants, and function sets differ (struct stat, errno values, O_* flags, sigaction, and so on). A single binding cannot describe all of them, and trying to merge them by hand defeats the purpose of automatic generation.

The sensible model is the one Go itself uses: treat each GOOS/GOARCH pair as its own world, generate a binding for each, and let tooling pick the right one later. This proposal only covers the first part: generating and organizing the per-platform bindings.

Project Layout

A platform-specific llcppg project looks like this:

<a-llcppg-project>/
    go.mod
    go.sum
    llcppg.cfg
    darwin-arm64/
        include/
            <headers of the library for darwin/arm64>
    linux-amd64/
        include/
            <headers of the library for linux/amd64>
    ...

Taking libc as an example: darwin-arm64/include would hold the relevant files from the macOS SDK, while linux-amd64/include would hold the headers of the Linux libc being targeted (glibc or musl, for instance).

Rules:

  • The directory name is exactly $GOOS-$GOARCH as defined by Go (darwin-arm64, linux-amd64, linux-arm64, windows-amd64, and so on). No aliases, no custom spellings.
  • Each platform directory is self-contained. It carries its own headers, and nothing is shared between platforms.
  • go.mod, go.sum, and llcppg.cfg stay at the project root and are common to all platforms.

Configuration

The Dir field

For an ordinary, platform-independent project, Dir is typically one of:

"Dir": "./include"
"Dir": "./include/..."

For a platform-specific project, Dir must instead start with the $GOOS-$GOARCH/ prefix:

"Dir": "$GOOS-$GOARCH/include"
"Dir": "$GOOS-$GOARCH/include/..."

The prefix is what tells llcppg that the project is platform-specific. The rest of the path keeps its existing meaning: a plain directory, or a directory followed by /... to include subdirectories recursively.

A complete example
{
  "name": "libc",
  "Dir": "$GOOS-$GOARCH/include/...",
  "Files": [
    "stdio.h",
    "stdlib.h",
    "string.h"
  ]
}

With this configuration and the layout above, llcppg run for darwin/arm64 reads headers from darwin-arm64/include/..., and run for linux/amd64 reads them from linux-amd64/include/.... Everything else in llcppg.cfg (prefixes, type aliases, and so on) behaves as it does today and applies to whichever platform is being converted.

Validation

llcppg should reject configurations that would silently produce confusing results:

  • A Dir that mentions $GOOS or $GOARCH anywhere other than as the leading $GOOS-$GOARCH/ segment is an error.
  • A project whose headers live under platform directories but whose Dir lacks the prefix is not detected specially; it is simply treated as a normal project. Detection is driven by the Dir prefix only.
  • If the resolved platform directory does not exist, llcppg fails with a message that names the expected path (for example darwin-arm64/include).

Output Layout

When converting, the user passes <dest-dir> exactly as before:

llcppg <dest-dir> [<src-dir>]

For a platform-specific project, llcppg does not write the generated package directly into <dest-dir>. It appends the platform directory automatically:

<dest-dir>/
    darwin-arm64/
        <generated Go package for darwin/arm64>

and for another platform:

<dest-dir>/
    linux-amd64/
        <generated Go package for linux/amd64>

Key points:

  • The user never creates darwin-arm64 (or any other platform directory) by hand. It is created by llcppg.
  • The same <dest-dir> can therefore accumulate bindings for several platforms, one subdirectory each, without any collision.
  • For ordinary platform-independent projects nothing changes: output still goes straight into <dest-dir>.

Selecting the Target Platform

llcppg needs to know which platform it is converting for, so it can expand $GOOS-$GOARCH. The proposal follows Go's conventions:

  • The GOOS and GOARCH environment variables select the target platform.
  • If they are unset, llcppg uses the host platform (runtime.GOOS / runtime.GOARCH).

Because platforms are independent, producing bindings for several platforms is simply a matter of running llcppg once per platform:

GOOS=darwin GOARCH=arm64 llcppg <dest-dir> [<src-dir>]
GOOS=linux  GOARCH=amd64 llcppg <dest-dir> [<src-dir>]

Both runs write into their own subdirectory of <dest-dir>.

Compatibility

  • Existing projects are unaffected. A Dir without the $GOOS-$GOARCH/ prefix keeps the current behavior in full, including the output location.
  • No change is required to the cfg schema other than the new meaning of the Dir prefix.

Non-Goals

This proposal deliberately stops at "generate and organize per-platform bindings". The following are left for follow-up proposals:

  • A unified import path that automatically selects the right platform package at build time (for example via build constraints or a facade package).
  • Sharing or deduplicating declarations across platforms.
  • Fetching or vendoring SDK headers for a platform; the headers are provided in the platform directory by the project author.

Open Questions

  1. Concrete prefixes in Dir. Should Dir also be allowed to name a concrete platform (for example darwin-arm64/include) to pin a project to one platform, or must it always use the $GOOS-$GOARCH placeholder form?
  2. Go package path. The generated package lands in <dest-dir>/darwin-arm64, so its import path ends with the platform directory. A follow-up proposal should decide how consumers import a platform-neutral name on top of this.
  3. Cross-conversion. Running llcppg on a Linux host for darwin/arm64 requires the Darwin headers to be parsed with the right target triple. The framework allows it through GOOS/GOARCH, but the clang invocation details (target triple, sysroot) need to be specified.
  4. Architecture-independent platforms. Some systems may want a single directory per OS (linux) rather than per OS/arch pair. This proposal sticks to Go's $GOOS-$GOARCH form; a coarser grouping can be considered later if real cases appear.
主要语言
Go
星标
40
派生
13
平均合并
1 小时 57 分钟
30 天内合并 PR
154

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

goplus/llcppg 的其他 Issue

查看 goplus/llcppg 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。