Proposal: Platform-Specific Project Layout and Output
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
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 内容生成。
描述
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:
- Each platform is fully independent and lives in its own
$GOOS-$GOARCHdirectory (for exampledarwin-arm64), following Go's own naming exactly. Dirinllcppg.cfggains a mandatory$GOOS-$GOARCH/prefix when the project is platform-specific.- 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-$GOARCHas 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, andllcppg.cfgstay 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
Dirthat mentions$GOOSor$GOARCHanywhere other than as the leading$GOOS-$GOARCH/segment is an error. - A project whose headers live under platform directories but whose
Dirlacks the prefix is not detected specially; it is simply treated as a normal project. Detection is driven by theDirprefix 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
GOOSandGOARCHenvironment 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
Dirwithout 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
Dirprefix.
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
- Concrete prefixes in
Dir. ShouldDiralso be allowed to name a concrete platform (for exampledarwin-arm64/include) to pin a project to one platform, or must it always use the$GOOS-$GOARCHplaceholder form? - 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. - Cross-conversion. Running llcppg on a Linux host for
darwin/arm64requires the Darwin headers to be parsed with the right target triple. The framework allows it throughGOOS/GOARCH, but the clang invocation details (target triple, sysroot) need to be specified. - 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-$GOARCHform; a coarser grouping can be considered later if real cases appear.
- 主要语言
- Go
- 星标
- 40
- 派生
- 13
- 平均合并
- 1 小时 57 分钟
- 30 天内合并 PR
- 154
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
goplus/llcppg 的其他 Issue
-
难度 5/5 一周以上 新手友好度 25/100
维护者通常 1 天内回复
-
Proposal: `Define` — inject constants into the generated package可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭configuration feature proposal
难度 5/5 一周以上 新手友好度 25/100
维护者通常 1 天内回复
-
bug
难度 5/5 一周以上 新手友好度 28/100
维护者通常 1 天内回复
-
bug
难度 4/5 3-5 天 新手友好度 55/100
维护者通常 1 天内回复
-
feature proposal
难度 5/5 一周以上 新手友好度 18/100
维护者通常 1 天内回复
相似的 Issue
-
go good first issue
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
area: api bug severity:low
难度 2/5 1-3 小时 新手友好度 72/100
-
难度 2/5 1-3 小时 新手友好度 66/100
-
raised-by:desk to:worker
难度 1/5 1 小时以内 新手友好度 74/100
medici-finance/assay#5167 ·
维护者通常 1 天内回复
-
Response matcher: a changed integer above 2^53 passes because JSON numbers are compared as float64未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复