The nuget {} DSL
Reference for the nuget {} extension, read from NugetExtension.kt, NugetPublishConfig.kt, NugetDependency.kt, NugetDependencyScope.kt, and NugetBindConfig.kt in nuget-plugin/src/main/kotlin/io/github/xxfast/kotlin/native/nuget/.
nuget { }
Member | Configures | Required |
|---|---|---|
|
| optional, omit for a consume-only project |
|
| optional, omit for a publish-only project |
A project can declare either block, both, or neither meaningfully. publish {} alone publishes a package with no reverse bindings; dependencies {} alone binds C# packages into Kotlin without publishing anything. See Gradle tasks for exactly which tasks each combination registers.
publish { }
Configures NugetPublishConfig. Every field is a nullable String with no default. Nothing in the DSL itself enforces they're set, but packNuget fails once it reads an unset one.
Property | Type | Required | Maps to |
|---|---|---|---|
|
| yes |
|
|
| yes |
|
|
| yes |
|
|
| yes |
|
|
| yes | the Kotlin package the generated C# namespaces are rooted at; sub-packages map relative to it. Also the default export scope: see below |
| function | no | empty; when set, only these package prefixes (and their sub-packages) are bridged |
| function | no | empty; applied after |
Export scoping
By default NugetProcessor bridges every public declaration in the module. include/exclude on publish {} scope that down, mirroring bind { include/exclude } on the reverse side: a package prefix match (pkg == p || pkg.startsWith("$p.")), with exclude always winning over include.
A package that is only reached via dependencies { dependency(...) { bind { } } } (the reverse stub packages generated for a consumed C# dependency) is always exported regardless of include/exclude, since a module that both publishes forward and consumes a NuGet dependency needs those bound types reachable from its own forward return types to keep compiling.
See ADR-063 for the full predicate and the rootPackage behaviour-change rationale.
Cross-module export closure
include/exclude/rootPackage also decide what crosses a Gradle module boundary. The export set is a reachability closure from the module's own admitted declarations (the roots above): the processor walks return types, parameter types, property types, type arguments of an admitted carrier (Flow<T>, List<T>/Set<T>/Map<K,V>), sealed subclasses, and primary-constructor parameter types, and admits every discovered declaration through the same include/exclude/rootPackage predicate, whether it lives in this module or in a dependency module pulled in with implementation(project(":models")). No separate DSL verb is needed: a :models module under the same rootPackage is admitted automatically.
A reachable dependency-module type whose package falls outside the effective include set is skipped with SKIPPED_UNEXPORTED_DEPENDENCY_TYPE, naming the exact include(...) line that would admit it, rather than silently dropping the member or leaking an unusable handle. When at least one type is admitted from a dependency module, the processor also emits one INFO_EXPORTED_FROM_DEPENDENCY line per KSP run, naming the whole admitted set, since a per-type warning would be noise at this scale.
Deferred, each needing its own decision: supertype edges (an admitted class implementing an admitted interface does not gain : IFoo in C#), cross-module generic classes, and cross-module suspend/Flow-returning members on an admitted dependency type (a root may still return Flow<DepType>; it's the dependency type's own suspend/Flow members that are skipped).
See ADR-066 for the full admission and edge-walking rules.
dependencies { }
Configures a NugetDependencyScope, whose only member is dependency(...).
dependency(id, version = null) { }
Parameter | Type | Required |
|---|---|---|
|
| yes, the NuGet package id |
|
| no, omit for an unpinned |
Inside the trailing block, NugetDependency exposes:
Property / function | Type | Required | Notes |
|---|---|---|---|
|
| no | same as the |
|
| no | an extra NuGet feed URL, added to |
| function, configures | no | omit to resolve the dependency without generating any Kotlin bindings for it |
bind { }
Configures NugetBindConfig. Declaring bind {} at all is what triggers nugetExtractApi, nugetGenerateBindings, and nugetGenerateShims for that dependency. See Gradle tasks.
Property / function | Type | Required | Default |
|---|---|---|---|
|
| no | the dependency id, lowercased with |
| function | no | empty, with no |
| function | no | empty |
| function | no | none |
include/exclude match a C# namespace exactly, or any of its sub-namespaces (ns == filter or ns.startsWith("$filter.")); when both match the same namespace, exclude wins. alias maps one specific C# namespace to a Kotlin package, overriding both packageName and the id-derived default for that namespace only.
Only one bind { } block is supported per dependency (a second call overwrites the first).
See ADR-044 for the DSL's design rationale, and ADR-047 for the include/exclude filter semantics. For what actually gets bound once a namespace is included, see Consuming C# in Kotlin.