You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LLAR should integrate with external tools through plugins that run outside the LLAR process and communicate through a public protocol. A plugin must not import LLAR internal Go packages or depend on in-memory Formula, resolver, build, or artifact objects.
This proposal establishes the process and ownership boundary only. The transport, message schema, process-launch direction, and first concrete build-system plugin remain follow-up decisions.
Motivation
LLAR can resolve, build, cache, and install native libraries, but a downstream C or C++ project does not yet have a supported way to consume those libraries through its own build system.
For example, a CMake project needs LLAR's resolved artifacts and consumption information translated into CMake behavior. A Meson or Bazel integration needs the same LLAR facts translated into its own native model. Putting all of those translations into LLAR would couple the core to every consumer build system.
The alternatives researched in #121 do not provide the desired boundary. Homebrew exposes installed prefixes and process environment, while Conan couples package metadata to build-system-specific generators. LLAR instead needs external integrations that can be implemented, installed, and released independently of the LLAR core.
The common need is a stable process boundary through which an external component can obtain LLAR-owned facts and translate them into consumer-owned behavior.
Current Workarounds
Consumers currently have to prepare global compiler, linker, CMake, or pkg-config search paths; inspect installed artifacts themselves; or add LLAR-specific handling directly to their build.
These approaches either introduce process-global state or duplicate LLAR knowledge in each consumer. The existing cmake.use and related Formula helpers solve a different problem: they allow a Formula build to consume another LLAR dependency while LLAR is building it. They do not provide an integration contract for an external downstream project.
Goals
Keep every plugin outside the LLAR process.
Let plugins use a public protocol without importing LLAR internal Go packages.
Keep dependency resolution and artifact ownership in LLAR.
Keep CMake, Meson, Bazel, language, IDE, and other consumer-specific translation outside LLAR.
Allow LLAR and plugins to be developed and released independently under an explicit compatibility contract.
Expose only the minimum LLAR-owned data required for a plugin to do its own work.
Out of Scope
Choosing between standard input/output, a local socket, or another transport.
Choosing the request encoding, framing, or protocol-version mechanism.
Deciding whether LLAR launches a plugin or a plugin launches or connects to LLAR.
Defining the request and response schema.
Selecting or implementing the first CMake, Meson, Bazel, language, or IDE plugin.
Loading plugin code into the LLAR process.
Adding build-system-specific behavior to LLAR core packages.
Replacing Formula dependency resolution or changing existing Formula APIs.
A plugin is an independent process. All interaction between LLAR and a plugin crosses a public protocol boundary as protocol data.
LLAR-owned resolution and artifacts
|
| public protocol
|
External plugin owned by its consumer integration
Neither side may rely on the other's in-memory objects. In particular, a plugin must not receive or import LLAR's Formula context, module loader, dependency graph implementation, build context, cache implementation, or artifact-store implementation.
Ownership
LLAR owns dependency resolution, artifact selection and access, and the LLAR facts exposed by the protocol. It must not interpret those facts as CMake targets, Meson dependencies, Bazel providers, language package settings, or IDE configuration.
Each plugin owns translation into its consumer's native behavior. For example, a CMake plugin may translate protocol results into CMake behavior, but CMake concepts remain outside LLAR.
The protocol owns the compatibility boundary, request and response validation, and error representation. A follow-up proposal must define these details before implementation begins.
Example Data Flow
The boundary for a future CMake integration would be:
CMake project
-> external LLAR CMake plugin
-> request LLAR resolution through the public protocol
<- receive LLAR-owned result data
-> translate that data into CMake behavior
This example fixes the ownership direction, not the transport or schema. The same boundary must allow a Meson, Bazel, language, or IDE integration without adding that consumer's concepts to LLAR.
Architecture Impact
LLAR gains one public protocol boundary but does not gain a general in-process plugin host. Existing Formula loading, dependency resolution, builds, cache behavior, and artifact storage remain internal and unchanged unless a later protocol proposal explicitly exposes a minimum result derived from them.
An external plugin failure is reported at the protocol boundary. It must not execute inside or extend LLAR's internal object graph. Consumer-specific configuration and side effects remain owned by that plugin and its host tool.
Compatibility
This proposal is additive and changes no existing command, Formula API, build result, cache entry, artifact format, or pkg-config behavior by itself.
The later protocol design must define compatibility between independently released LLAR and plugin versions. No transport or versioning mechanism is selected here.
Alternatives Considered
In-process plugins
Rejected because they couple plugins to LLAR's implementation language, runtime, internal APIs, and process lifecycle. A plugin failure could also fail the LLAR process.
Global environment preparation
Rejected as the plugin contract because compiler, linker, CMake, and pkg-config environment variables are process-global and cannot represent every consumer's native model. A plugin may still prepare an environment when that is the correct behavior for its own host.
Build-system integrations inside LLAR
Rejected because LLAR would need to own CMake, Meson, Bazel, language, and IDE behavior and release on their compatibility schedules.
pkg-config as the only integration surface
Rejected as the complete plugin boundary because pkg-config is one native-library consumption format, not a general integration protocol. The work in #180 remains useful and independent.
Open Questions
Which side owns process launch and lifetime?
Which transport and message framing should the first protocol use?
What is the minimum first operation and its input and output data?
How do independently released implementations negotiate compatibility?
How are plugins discovered, selected, installed, and trusted?
Which consumer integration should be the first end-to-end reference?
Acceptance Criteria
A plugin can be implemented in a separate repository and process without importing LLAR internal packages.
LLAR core contains no consumer-specific CMake, Meson, Bazel, language, or IDE translation introduced by the plugin system.
All exchanged information is defined by a public protocol rather than shared in-memory objects.
A follow-up protocol proposal can define one operation without changing this ownership boundary.
Existing LLAR and Formula behavior remains unchanged until a concrete protocol operation is implemented.
Proposal: Out-of-process plugin protocol
Summary
LLAR should integrate with external tools through plugins that run outside the LLAR process and communicate through a public protocol. A plugin must not import LLAR internal Go packages or depend on in-memory Formula, resolver, build, or artifact objects.
This proposal establishes the process and ownership boundary only. The transport, message schema, process-launch direction, and first concrete build-system plugin remain follow-up decisions.
Motivation
LLAR can resolve, build, cache, and install native libraries, but a downstream C or C++ project does not yet have a supported way to consume those libraries through its own build system.
For example, a CMake project needs LLAR's resolved artifacts and consumption information translated into CMake behavior. A Meson or Bazel integration needs the same LLAR facts translated into its own native model. Putting all of those translations into LLAR would couple the core to every consumer build system.
The alternatives researched in #121 do not provide the desired boundary. Homebrew exposes installed prefixes and process environment, while Conan couples package metadata to build-system-specific generators. LLAR instead needs external integrations that can be implemented, installed, and released independently of the LLAR core.
The common need is a stable process boundary through which an external component can obtain LLAR-owned facts and translate them into consumer-owned behavior.
Current Workarounds
Consumers currently have to prepare global compiler, linker, CMake, or pkg-config search paths; inspect installed artifacts themselves; or add LLAR-specific handling directly to their build.
These approaches either introduce process-global state or duplicate LLAR knowledge in each consumer. The existing
cmake.useand related Formula helpers solve a different problem: they allow a Formula build to consume another LLAR dependency while LLAR is building it. They do not provide an integration contract for an external downstream project.Goals
Out of Scope
.pccreation work proposed in proposal: create pkg-config metadata from Formulas #180.Proposal
Design Rule
A plugin is an independent process. All interaction between LLAR and a plugin crosses a public protocol boundary as protocol data.
Neither side may rely on the other's in-memory objects. In particular, a plugin must not receive or import LLAR's Formula context, module loader, dependency graph implementation, build context, cache implementation, or artifact-store implementation.
Ownership
LLAR owns dependency resolution, artifact selection and access, and the LLAR facts exposed by the protocol. It must not interpret those facts as CMake targets, Meson dependencies, Bazel providers, language package settings, or IDE configuration.
Each plugin owns translation into its consumer's native behavior. For example, a CMake plugin may translate protocol results into CMake behavior, but CMake concepts remain outside LLAR.
The protocol owns the compatibility boundary, request and response validation, and error representation. A follow-up proposal must define these details before implementation begins.
Example Data Flow
The boundary for a future CMake integration would be:
This example fixes the ownership direction, not the transport or schema. The same boundary must allow a Meson, Bazel, language, or IDE integration without adding that consumer's concepts to LLAR.
Architecture Impact
LLAR gains one public protocol boundary but does not gain a general in-process plugin host. Existing Formula loading, dependency resolution, builds, cache behavior, and artifact storage remain internal and unchanged unless a later protocol proposal explicitly exposes a minimum result derived from them.
An external plugin failure is reported at the protocol boundary. It must not execute inside or extend LLAR's internal object graph. Consumer-specific configuration and side effects remain owned by that plugin and its host tool.
Compatibility
This proposal is additive and changes no existing command, Formula API, build result, cache entry, artifact format, or pkg-config behavior by itself.
The later protocol design must define compatibility between independently released LLAR and plugin versions. No transport or versioning mechanism is selected here.
Alternatives Considered
In-process plugins
Rejected because they couple plugins to LLAR's implementation language, runtime, internal APIs, and process lifecycle. A plugin failure could also fail the LLAR process.
Global environment preparation
Rejected as the plugin contract because compiler, linker, CMake, and pkg-config environment variables are process-global and cannot represent every consumer's native model. A plugin may still prepare an environment when that is the correct behavior for its own host.
Build-system integrations inside LLAR
Rejected because LLAR would need to own CMake, Meson, Bazel, language, and IDE behavior and release on their compatibility schedules.
pkg-config as the only integration surface
Rejected as the complete plugin boundary because pkg-config is one native-library consumption format, not a general integration protocol. The work in #180 remains useful and independent.
Open Questions
Acceptance Criteria