Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

Proposal: -lib-version — Preserve Native Library Versions in Generated Bindings

Abierto
#1,062 0 comentarios 0 reacciones 0 asignados Ver en GitHub

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
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
c, go
Área
cli, tooling

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:

  1. Retain the Go module path and version from package loading, such as llar.io/[email protected].
  2. Read _llcppg_lib_version from 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 with go/constant.StringVal.
  3. Combine the native version v22.1.8 with the project's identity under the Hub naming model and LLGO's compilation target.
  4. 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.8 generates const _llcppg_lib_version = "v22.1.8" in llcppg.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.cfg or 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

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de goplus/llcppg

Todos los issues de goplus/llcppg

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.