Proposal: GN Extensibility design

22 views
Skip to first unread message

Matt Stark

unread,
Jun 25, 2026, 3:20:06 AM (11 days ago) Jun 25
to gn-dev, chrome-build-team
Hi everyone,

As our build complexity grows, we’ve hit several limitations with the current GN extensibility model. I've written a proposal go/gn-extensibility-dd to address these concerns. The design doc is a long read (16 pages), so here's a TLDR for you:

Heavily inspired by bazel
In fact, it looks suspiciously like we've very precisely and meticulously stolen the API...
We use rules, depsets, and providers to create a simple and powerful framework to pull all of the complex logic out of the build files.

As an example, GN currently does not specify inputs for C++ actions. This is a feature we need to address build flakiness and nondeterminism, for reasons I won't explain here. It would be extremely nontrivial to implement directly in GN, but could be implemented with the following code. You can see how we could use this to collect arbitrary metadata about the (transitive) dependencies of a target, and do whatever we wanted with it:

HeadersInfo = provider(["headers"])

def _impl(ctx):
  public_headers_direct = ctx.gn.public()
  public_headers = depset(
    direct = public_headers_direct,
    transitive = [dep[HeadersInfo].headers for dep in ctx.gn.public_deps() if HeadersInfo in dep],
  )
  required_inputs = depset(
    direct = ctx.gn.sources(),
    transitive = [dep[HeadersInfo].headers for dep in ctx.gn.deps() if HeadersInfo in dep] + [public_headers]
  )

  return [
    HeadersInfo(headers = public_headers),
    GnInputsInfo(files = required_inputs),
  ]

static_library = rule_extension(implementation = _impl)
shared_library = rule_extension(implementation = _impl)
source_set = rule_extension(implementation = _impl)


Current state: Prototype working!
I made a prototype.

Addressing potential concerns
  • Value proposition: ~3 SWE months of work by the chrome build team. Likely to recoup time investment within a year.
  • Backwards compatibility: This is strictly opt-in. This is an optional (but strongly recommended) replacement for templates.
  • Performance: Benchmarks of the current prototype show that adding support for this feature has a statistically insignificant overhead to spin up the starlark interpreter for empty rules for every single build target. Writing more complex rules will of course have overhead, but:
    • As it's opt-in, you can choose whether or not it's worth it for you.
    • Implementing it with GN templates would also have overhead. I don't have metrics for how they compare yet
  • Long-term Maintenance: This feature interacts very minimally with existing GN code. For the most part, this code is able to be tested independently of GN
--
Thanks, Matt.

Dirk Pranke

unread,
Jun 25, 2026, 12:19:19 PM (11 days ago) Jun 25
to Matt Stark, gn-dev, chrome-build-team
Hi Matt,

Can you please make a public link for this (and/or make the doc public), assuming you do want this to be part of GN and not a fork of it?

Cheers,

-- Dirk

Matt Stark

unread,
Jun 25, 2026, 7:06:12 PM (10 days ago) Jun 25
to Dirk Pranke, gn-dev, chrome-build-team
Sorry about that. Here's the public link
--
Thanks, Matt.

Dirk Pranke

unread,
Jun 30, 2026, 6:38:30 PM (6 days ago) Jun 30
to Matt Stark, gn-dev, chrome-build-team
Hi Matt,

I apologize for the silence on this thread. What you are proposing is a significant modification of how GN works and a significant increase in the complexity of GN from a user's and maintainer's point of view (given that you're adding in a second language runtime).

As a result, it's taking me some time to consider your proposal and figure out how to respond :). I do plan to do so in more detail, and hopefully that'll happen in the next few days. If I can't get to it completely within that time frame I'll try to at least give you some updates as my thinking progresses, so that this isn't just dangling out there in the wind. 

Hope that works for you?

-- Dirk

David Turner

unread,
Jul 1, 2026, 7:38:28 AM (5 days ago) Jul 1
to Matt Stark, Dirk Pranke, gn-dev, chrome-build-team
Thanks Matt for your proposal. I added some comments to the doc and would like to add a few others here:
  • As a heavy Bazel user, I confirm that providers, depsets, custom rules with their own resolution function are the best way to extend GN. They provide a clear model for propagating information from dependencies to dependents, though this changes how GN works in a non-trivial way which will need very clear documentation.

  • I agree with rejecting Option A: I actually did implement in the past an experimental GN suspendable evaluator to propagate information from dependencies to dependents at `gn gen` time. This was invasive, had a few side benefits (like user-defined functions or a proper "break" statement in foreach() loops) but also many drawbacks, the first was drastically reducing evaluation parallelism in many simple cases. Hence a scheme where this propagation is pushed to resolution time instead (which can have higher parallelism), as in your proposal is the best way to go.

  • Starlark is probably the best language for this implementation; extending the GN language with new concepts is indeed likely to be very error-prone. On the other hand, introducing an FII layer and linking a Rust-built library into GN will make maintenance and debugging much more difficult in the future. How difficult would it be to write a C++ Starlark interpreter given that the language has a great spec and extensive test suites from its Go and Rust implementations? For example, I could use Gemini to create a decent (though non optimized) Starlark lexer and parser in a few minutes (still missing an evaluator which is where most work resides in). I know this is a lot to ask though.

  • One of GN's best features is its very human-friendly error messages. I hope that whatever Starlark integration is used can retain this feature for the sake of users (by contrast, this is something where Bazel is really bad).

  • Speaking as an expert in both Bazel and GN, please, please do not assume in any way that these GN Starlark definitions can be compatible with Bazel ones. Critical, non-superficial differences in how both systems operate make this impossible except for the most trivial cases. It's far better to describe this as a new GN-specific way to define templates and rule extensions using Starlark, borrowing concepts from Bazel, but document the GN versions properly without relying on the Bazel documentation (which has many unstated quality issues).
- Digit

For context, I am the TL for the Fuchsia build which is migrating from GN/Ninja to Bazel. This effort started several years ago because the maintainers of GN and Ninja rejected extending those systems to support our near future needs (at the time). We also didn't feel that forking both GN and Ninja would be a good use of our resources. It's interesting to see that Chrome has since replaced Ninja with Siso, and is considering Starlark-style extensibility for GN itself to solve similar issues :)

And this is not a suggestion to move Chrome to Bazel (that would be a big mistake for many reasons).

To unsubscribe from this group and stop receiving emails from it, send an email to gn-dev+un...@chromium.org.

Philipp Wollermann

unread,
Jul 1, 2026, 8:17:02 AM (5 days ago) Jul 1
to David Turner, Matt Stark, Dirk Pranke, gn-dev, chrome-build-team
Hey David :)

Thanks for the super helpful and detailed reply. I'll let Matt comment on the C++ vs. Rust trade-offs as I don't know Rust very well myself.

On Wed, Jul 1, 2026, 20:38 David Turner <di...@google.com> wrote:
this is not a suggestion to move Chrome to Bazel (that would be a big mistake for many reasons).

Could you elaborate why you think this would be a big mistake? I've personally been building my Chromium with Bazel recently and find it works just fine, and has a couple of benefits like integrated sandboxing, nicer UI, and faster incremental builds. Running the Chrome tests with "bazel test" and getting structured test results in the terminal is also pretty cool :)

It's definitely not perfect, there are some things that GN or Siso still do better, but I'm curious what risks you see.

Best,
Philipp

David Turner

unread,
Jul 1, 2026, 1:19:06 PM (5 days ago) Jul 1
to Philipp Wollermann, Matt Stark, Dirk Pranke, gn-dev, chrome-build-team
These points should be discussed in a different email thread, to not derail from Matt's excellent proposal and the discussion around it.
I'll try to start one soon when I have a little more time.

- Digit

PS: I was not aware that you could build all of Chromium with Bazel though, where are the docs? Please answer privately for now :-)

Reply all
Reply to author
Forward
0 new messages