Caught linking

- Upgrade buildSrc to kotlin buildscript
- Add TransitiveSourceSet extension to abstract creating the different
  source sets and creating the configurations to apply dependencies
This commit is contained in:
Jozufozu 2024-04-29 14:33:51 -07:00
parent 29b8c3b00f
commit 2072bea11b
9 changed files with 234 additions and 91 deletions

View file

@ -1,39 +0,0 @@
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
mavenCentral()
maven {
name = 'MinecraftForge'
url = 'https://maven.minecraftforge.net/'
}
maven {
name = 'Architectury'
url = 'https://maven.architectury.dev/'
}
maven { url = 'https://repo.spongepowered.org/repository/maven-public' }
maven { url = 'https://maven.parchmentmc.org' }
}
gradlePlugin {
plugins {
platformPlugin { PluginDeclaration plugin ->
plugin.id = 'flywheel.platform'
plugin.implementationClass = 'com.jozufozu.gradle.PlatformPlugin'
}
jarSetPlugin { PluginDeclaration plugin ->
plugin.id = 'flywheel.jar-sets'
plugin.implementationClass = 'com.jozufozu.gradle.JarSetPlugin'
}
packageInfosPlugin { PluginDeclaration plugin ->
plugin.id = 'flywheel.package-infos'
plugin.implementationClass = 'com.jozufozu.gradle.PackageInfosPlugin'
}
}
}
dependencies {
implementation 'dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6-SNAPSHOT'
}

44
buildSrc/build.gradle.kts Normal file
View file

@ -0,0 +1,44 @@
plugins {
id("groovy-gradle-plugin")
id("java-gradle-plugin")
kotlin("jvm") version "1.9.20"
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
mavenCentral()
maven("https://maven.minecraftforge.net/") {
name = "MinecraftForge"
}
maven("https://maven.architectury.dev/") {
name = "Architectury"
}
maven("https://repo.spongepowered.org/repository/maven-public")
maven("https://maven.parchmentmc.org")
}
gradlePlugin {
plugins {
create("platformPlugin") {
id = "flywheel.platform"
implementationClass = "com.jozufozu.gradle.PlatformPlugin"
}
create("jarSetPlugin") {
id = "flywheel.jar-sets"
implementationClass = "com.jozufozu.gradle.JarSetPlugin"
}
create("packageInfosPlugin") {
id = "flywheel.package-infos"
implementationClass = "com.jozufozu.gradle.PackageInfosPlugin"
}
create("transitiveSourceSetsPlugin") {
id = "flywheel.transitive-source-sets"
implementationClass = "com.jozufozu.gradle.TransitiveSourceSetsPlugin"
}
}
}
dependencies {
implementation("dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6-SNAPSHOT")
}

View file

@ -30,27 +30,10 @@ class PlatformPlugin implements Plugin<Project> {
def loom = project.getExtensions().getByType(LoomGradleExtensionAPI) def loom = project.getExtensions().getByType(LoomGradleExtensionAPI)
def publishing = project.getExtensions().getByType(PublishingExtension) def publishing = project.getExtensions().getByType(PublishingExtension)
// Loom only populates mc stuff to the main source set,
// so grab that here and use it for the others.
// Note that the `+` operator does NOT perform a deep copy
// of a FileCollection, so this object is shared between
// the source sets and we should avoid mutating it.
SourceSet platformImpl = sourceSets.named('main').get() SourceSet platformImpl = sourceSets.named('main').get()
FileCollection mcCompileClassPath = platformImpl.compileClasspath
SourceSet platformApi = sourceSets.create('api') SourceSet platformApi = sourceSets.create('api')
platformApi.compileClasspath = mcCompileClassPath
SourceSet platformLib = sourceSets.create('lib') SourceSet platformLib = sourceSets.create('lib')
platformLib.compileClasspath = mcCompileClassPath + platformApi.output
SourceSet platformBackend = sourceSets.create('backend') SourceSet platformBackend = sourceSets.create('backend')
platformBackend.compileClasspath = mcCompileClassPath + platformApi.output + platformLib.output
// Assign here rather than concatenate to avoid modifying the mcCompileClassPath FileCollection
platformImpl.compileClasspath = mcCompileClassPath + platformApi.output + platformLib.output + platformBackend.output
// This isn't necessary for forge but fabric needs to recognize each classpath entry from ModSettings.
platformImpl.runtimeClasspath += platformApi.output + platformLib.output + platformBackend.output
// This is needed for both platforms. // This is needed for both platforms.
def mainMod = loom.mods.maybeCreate('main') def mainMod = loom.mods.maybeCreate('main')
@ -59,16 +42,6 @@ class PlatformPlugin implements Plugin<Project> {
mainMod.sourceSet(platformBackend) mainMod.sourceSet(platformBackend)
mainMod.sourceSet(platformImpl) mainMod.sourceSet(platformImpl)
def forApi = newConfiguration(project, 'forApi').get()
def forLib = newConfiguration(project, 'forLib').get()
def forBackend = newConfiguration(project, 'forBackend').get()
def forImpl = newConfiguration(project, 'forImpl').get()
extendsFrom(project, platformApi.compileOnlyConfigurationName, forApi)
extendsFrom(project, platformLib.compileOnlyConfigurationName, forApi, forLib)
extendsFrom(project, platformBackend.compileOnlyConfigurationName, forApi, forLib, forBackend)
extendsFrom(project, platformImpl.compileOnlyConfigurationName, forApi, forLib, forBackend, forImpl)
SourceSet commonApi = commonSourceSets.named('api').get() SourceSet commonApi = commonSourceSets.named('api').get()
SourceSet commonLib = commonSourceSets.named('lib').get() SourceSet commonLib = commonSourceSets.named('lib').get()
SourceSet commonBackend = commonSourceSets.named('backend').get() SourceSet commonBackend = commonSourceSets.named('backend').get()

View file

@ -0,0 +1,40 @@
package com.jozufozu.gradle
import org.gradle.api.tasks.SourceSet
class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) {
internal val compileSourceSets = mutableSetOf<SourceSet>()
internal val runtimeSourceSets = mutableSetOf<SourceSet>()
fun rootCompile() {
parent.compileClasspath?.let { sourceSet.compileClasspath = it }
}
fun rootRuntime() {
parent.runtimeClasspath?.let { sourceSet.runtimeClasspath = it }
}
fun rootImplementation() {
rootCompile()
rootRuntime()
}
fun compile(vararg sourceSets: SourceSet) {
compileSourceSets += sourceSets
for (sourceSet in sourceSets) {
this.sourceSet.compileClasspath += sourceSet.output
}
}
fun runtime(vararg sourceSets: SourceSet) {
runtimeSourceSets += sourceSets
for (sourceSet in sourceSets) {
this.sourceSet.runtimeClasspath += sourceSet.output
}
}
fun implementation(vararg sourceSets: SourceSet) {
compile(*sourceSets)
runtime(*sourceSets)
}
}

View file

@ -0,0 +1,79 @@
package com.jozufozu.gradle
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.kotlin.dsl.the
open class TransitiveSourceSetsExtension(private val project: Project) {
var compileClasspath: FileCollection? = null
var runtimeClasspath: FileCollection? = null
private val transitives = mutableMapOf<SourceSet, TransitiveSourceSetConfigurator>()
fun create(name: String) {
sourceSet(project.the<SourceSetContainer>().maybeCreate(name))
}
fun create(name: String, action: Action<TransitiveSourceSetConfigurator>) {
sourceSet(project.the<SourceSetContainer>().maybeCreate(name), action)
}
fun sourceSet(name: String) {
sourceSet(project.the<SourceSetContainer>().getByName(name))
}
fun sourceSet(name: String, action: Action<TransitiveSourceSetConfigurator>) {
sourceSet(project.the<SourceSetContainer>().getByName(name), action)
}
fun sourceSet(sourceSet: SourceSet) {
registerSourceSet(sourceSet)
}
fun sourceSet(sourceSet: SourceSet, action: Action<TransitiveSourceSetConfigurator>) {
action.execute(registerSourceSet(sourceSet))
}
private fun registerSourceSet(sourceSet: SourceSet): TransitiveSourceSetConfigurator {
return transitives.computeIfAbsent(sourceSet) { TransitiveSourceSetConfigurator(this, it) }
}
fun createCompileConfigurations() {
val configs = transitives.mapValues { (sourceSet, _) ->
project.configurations.create("for${sourceSet.name.capitalize()}") {
isCanBeConsumed = true
isCanBeResolved = false
}
}
transitives.forEach { (sourceSet, configurator) ->
project.configurations.named(sourceSet.compileOnlyConfigurationName).configure {
extendsFrom(configs[sourceSet])
configurator.compileSourceSets.forEach {
extendsFrom(configs[it])
}
}
}
}
fun createRuntimeConfigurations() {
val configs = transitives.mapValues { (sourceSet, _) ->
project.configurations.create("run${sourceSet.name.capitalize()}") {
isCanBeConsumed = true
isCanBeResolved = false
}
}
transitives.forEach { (sourceSet, configurator) ->
project.configurations.named(sourceSet.runtimeOnlyConfigurationName).configure {
extendsFrom(configs[sourceSet])
configurator.runtimeSourceSets.forEach {
extendsFrom(configs[it])
}
}
}
}
}

View file

@ -0,0 +1,10 @@
package com.jozufozu.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
class TransitiveSourceSetsPlugin: Plugin<Project> {
override fun apply(target: Project) {
target.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, target)
}
}

View file

@ -7,36 +7,28 @@ plugins {
id 'flywheel.package-infos' id 'flywheel.package-infos'
id 'flywheel.subproject' id 'flywheel.subproject'
id 'flywheel.jar-sets' id 'flywheel.jar-sets'
id 'flywheel.transitive-source-sets'
} }
sourceSets { transitiveSourceSets {
// Loom only populates mc stuff to the main source set, compileClasspath = sourceSets.main.compileClasspath
// so grab that here and use it for the others.
// Note that the `+` operator does NOT perform a deep copy
// of a FileCollection, so this object is shared between
// the source sets and we should avoid mutating it.
FileCollection mcCompileClassPath = main.compileClasspath
SourceSet api = api { create('api') {
compileClasspath = mcCompileClassPath rootCompile()
} }
SourceSet lib = lib { create('lib') {
compileClasspath = mcCompileClassPath + api.output rootCompile()
compile sourceSets.api
} }
SourceSet backend = backend { create('backend') {
compileClasspath = mcCompileClassPath + api.output + lib.output rootCompile()
compile sourceSets.api, sourceSets.lib
} }
sourceSet(sourceSets.main) {
main { compile sourceSets.api, sourceSets.lib, sourceSets.backend
// Assign here rather than concatenate to avoid modifying the mcCompileClassPath FileCollection
compileClasspath = mcCompileClassPath + api.output + lib.output + backend.output
} }
sourceSet(sourceSets.test) {
test { implementation sourceSets.api, sourceSets.lib, sourceSets.backend
// Only test needs runtimeClasspath filled since the game shouldn't run from common alone.
// Fine to concatenate here.
compileClasspath += api.output + lib.output + backend.output
runtimeClasspath += api.output + lib.output + backend.output
} }
} }

View file

@ -7,10 +7,32 @@ plugins {
id 'flywheel.package-infos' id 'flywheel.package-infos'
id 'flywheel.subproject' id 'flywheel.subproject'
id 'flywheel.platform' id 'flywheel.platform'
id 'flywheel.transitive-source-sets'
} }
evaluationDependsOn(':common') evaluationDependsOn(':common')
transitiveSourceSets {
compileClasspath = sourceSets.main.compileClasspath
create('api') {
rootCompile()
}
create('lib') {
rootCompile()
compile sourceSets.api
}
create('backend') {
rootCompile()
compile sourceSets.api, sourceSets.lib
}
sourceSet(sourceSets.main) {
implementation sourceSets.api, sourceSets.lib, sourceSets.backend
}
createCompileConfigurations()
}
defaultPackageInfos { defaultPackageInfos {
forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main
} }
@ -50,5 +72,5 @@ dependencies {
forApi project(path: ':common', configuration: 'commonApiOnly') forApi project(path: ':common', configuration: 'commonApiOnly')
forLib project(path: ':common', configuration: 'commonLib') forLib project(path: ':common', configuration: 'commonLib')
forBackend project(path: ':common', configuration: 'commonBackend') forBackend project(path: ':common', configuration: 'commonBackend')
forImpl project(path: ':common', configuration: 'commonImpl') forMain project(path: ':common', configuration: 'commonImpl')
} }

View file

@ -7,10 +7,32 @@ plugins {
id 'flywheel.package-infos' id 'flywheel.package-infos'
id 'flywheel.subproject' id 'flywheel.subproject'
id 'flywheel.platform' id 'flywheel.platform'
id 'flywheel.transitive-source-sets'
} }
evaluationDependsOn(':common') evaluationDependsOn(':common')
transitiveSourceSets {
compileClasspath = sourceSets.main.compileClasspath
create('api') {
rootCompile()
}
create('lib') {
rootCompile()
compile sourceSets.api
}
create('backend') {
rootCompile()
compile sourceSets.api, sourceSets.lib
}
sourceSet(sourceSets.main) {
compile sourceSets.api, sourceSets.lib, sourceSets.backend
}
createCompileConfigurations()
}
defaultPackageInfos { defaultPackageInfos {
forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main forSourceSets sourceSets.api, sourceSets.lib, sourceSets.backend, sourceSets.main
} }
@ -60,5 +82,5 @@ dependencies {
forApi project(path: ':common', configuration: 'commonApiOnly') forApi project(path: ':common', configuration: 'commonApiOnly')
forLib project(path: ':common', configuration: 'commonLib') forLib project(path: ':common', configuration: 'commonLib')
forBackend project(path: ':common', configuration: 'commonBackend') forBackend project(path: ':common', configuration: 'commonBackend')
forImpl project(path: ':common', configuration: 'commonImpl') forMain project(path: ':common', configuration: 'commonImpl')
} }