Proposal: -lib-version — Preserve Native Library Versions in Generated Bindings
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 35/100
Línea de trabajo
Start with the command flag registration in cmd/llcppg/llcppg.go and the generation flow in cmd/llcppg/gen.go, which should show where cfg.NewPackage returns and where llcppg.i.go is written (default name in tool/gen.go). Check how cl/compile.go emits existing package constants, then trace where a new -lib-version value would be added to each generated package. Done means the acceptance criteria are met: the constant appears in llcppg.i.go for every generated package, and output is unchanged when the flag is omitted.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Why
The LLAR Hub workflow lets a user fetch a Go binding and build with LLGO:
go get llar.io/[email protected]
llgo build
Before linking, LLGO needs to install the native library required by that binding. The missing information is its original version: in this example, the Go binding version v1.22.18-pre.3 corresponds to native clang-c v22.1.8. LLGO needs to recover v22.1.8 to request:
llar install llar.io/[email protected]
The Go version alone cannot reliably supply this value. Native release names need not follow SemVer, publishers may rewrite them, and a binding-generator update can produce another Go release without changing the native version.
The binding publisher knows the native version when preparing the headers. This proposal lets it pass that version to llcppg, which records it in the generated Go package. LLGO can then read it before requesting native artifacts.
Usage
Add an optional generation flag, -lib-version:
llcppg -lib-version=v22.1.8 ./generated ./binding-input
The argument is the original version of the native library whose headers are being processed. The caller supplies matching headers, configuration, and version. For an LLAR-driven generation, this is the actual selected native version; the formula's fromVer still belongs to formula selection.
The existing llcppg.cfg continues to describe how to generate the bindings. It gains no version field. The same configuration can be reused with different header versions by changing the input headers and this command argument.
Generated output
For a generated package named clang, llcppg adds the following declaration to its existing llcppg.i.go output:
package clang
const _llcppg_lib_version = "v22.1.8"
_llcppg_lib_version is an unexported package-level Go string constant used as an llcppg metadata convention. Its value is the caller-supplied native version, preserved exactly. It carries no package-manager or consumer dependency.
The value is an opaque string: do not remove a leading v, normalize it to SemVer, or decode it as a Go version. Generate a correctly escaped Go string literal so punctuation, quotes, backslashes, and non-ASCII text retain their value.
If one invocation generates several packages for the same native library through Pkgs, emit the constant in each generated package. A consumer importing only a subpackage must still be able to read it without loading the module's root package.
When -lib-version is omitted, retain the existing generation behavior and emit no additional version constant.
How this records the mapping
llcppg does not need the eventual Go module tag. The published Go version identifies the binding contents, and those contents carry the native version:
| Published Go binding | Generated _llcppg_lib_version |
|---|---|
llar.io/[email protected] |
v22.1.8 |
llar.io/[email protected] |
v22.1.8 |
Here, a binding revision changes while the native version remains the same. Publishing the generated constant with each release preserves that association without a separate mapping table.
Using the result in LLGO
For a loaded binding package, the intended consumer flow is:
- Retain the Go module path and version from package loading, such as
llar.io/[email protected]. - Read
_llcppg_lib_versionfrom the loaded package's source or its complete, source-derived type scope, and check that it is a nonempty string constant. When using type information, obtain its value withgo/constant.StringVal. - Combine the native version
v22.1.8with the project's identity under the Hub naming model and LLGO's compilation target. - Request the corresponding native installation before resolving native link flags, then use the installed libraries for linking.
LLGO already reads package constants such as LLGoPackage. _llcppg_lib_version is unexported, so its reader must use source or type information that retains the declaration; it must not rely on Go export data containing this constant. Reading it requires no execution of generated code. Because it travels in Go source, vendoring and local replacements retain the value from the binding actually loaded.
Without the constant, this mechanism supplies no native version. Consumers must not guess one from a mapped Go tag. Existing manually configured linking remains available. The installation command above illustrates the Hub request; the choice of subprocess or library integration is separate work.
Responsibilities and scope
- The caller chooses the native version and matching headers. llcppg records that choice; it cannot verify the headers' release identity from an arbitrary version string.
- llcppg generates the declaration without understanding LLAR formulas,
fromVer, native package installation, or Go release-tag policy. Inputs obtained outside LLAR can use the same option. - The publisher includes the generated declaration when publishing the Go binding. LLGO consumes it to recover the native version.
This proposal does not add a version field to llcppg.cfg, a header such as llar.h, a version index, or a public Go helper API. Native project-name association, installation API design, and wrap.a publication remain separate work. Existing c module versioning and dependency-header lookup are unchanged.
Implementation notes
The change can stay in the command's generation flow. Register the flag alongside the existing command flags, then add the constant after cfg.NewPackage returns and before writing the generated files. The returned cl.Package embeds gogen.Package, so the command can use existing declaration-building facilities without adding version handling to the C/C++ parser or configuration schema. Use the existing default output file, llcppg.i.go.
Relevant source: command flags, generation and output, generated package and existing constant emission, default output filename.
Acceptance criteria
-
-lib-version=v22.1.8generatesconst _llcppg_lib_version = "v22.1.8"inllcppg.i.go. - Omitting the flag preserves the existing output behavior.
- Non-SemVer versions and values requiring Go string escaping survive generation unchanged.
- Every package generated for the native library receives the value, including subpackages selected through
Pkgs. - A lookup using the loaded source or complete, source-derived type information reads the unexported constant independently of the Go module's published version, without relying on its presence in Go export data.
- No version field in
llcppg.cfgor LLAR package dependency is required.
Related: xgo-dev/llar#203 addresses the same version-recovery problem through a generated native header. This proposal supplies the version directly to llcppg and emits the Go constant directly.
- Lenguaje dominante
- Go
- Estrellas
- 39
- Forks
- 13
- Merge medio
- 1 h 33 min
- PR fusionados (30 d)
- 256
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de goplus/llcppg
-
configuration
Dificultad 4/5 3-5 días Aptitud para principiantes 30/100
Los mantenedores suelen responder en 1 día
-
Architecture-Design feature proposal
Dificultad 5/5 Más de una semana Aptitud para principiantes 15/100
goplus/llcppg#1056 · 6 comentarios ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 5/5 Más de una semana Aptitud para principiantes 28/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
Los mantenedores suelen responder en 1 día
-
feature proposal
Dificultad 5/5 Más de una semana Aptitud para principiantes 18/100
Los mantenedores suelen responder en 1 día
Todos los issues de goplus/llcppg
Issues similares
-
bug
Dificultad 2/5 Medio día Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
kind/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
kubernetes-sigs/external-dns#6816 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
ANSI translator ignores SGR 22/24 (and other attribute-off codes): bold and underline never turn offAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Named Tuple element with a space in its name fails to parsePosiblemente ocupada @spicysharkco la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
ClickHouse/clickhouse-go#2073 ·
Los mantenedores suelen responder en 1 día