208 lines
8.6 KiB
Groovy
208 lines
8.6 KiB
Groovy
plugins {
|
|
id 'java'
|
|
id 'fabric-loom' apply false
|
|
}
|
|
|
|
/**
|
|
* Compatibility buckets, not Minecraft versions.
|
|
*
|
|
* Every project under :platform is compiled against one representative version
|
|
* and declares -- in its own gradle.properties -- the full range of Minecraft
|
|
* versions that the resulting jar actually runs on. The grouping comes from
|
|
* measured API breakpoints, documented in docs/PORTING.md.
|
|
*/
|
|
ext.platformProjects = { subprojects.findAll { it.path.startsWith(':platform:') } }
|
|
ext.sharedProjects = { subprojects.findAll { it.path.startsWith(':shared:') } }
|
|
|
|
subprojects {
|
|
apply plugin: 'java'
|
|
|
|
group = rootProject.mod_group
|
|
version = rootProject.mod_version
|
|
|
|
repositories {
|
|
maven { name = 'Fabric'; url = 'https://maven.fabricmc.net/' }
|
|
mavenCentral()
|
|
}
|
|
|
|
dependencies {
|
|
compileOnly "org.projectlombok:lombok:${rootProject.lombok_version}"
|
|
annotationProcessor "org.projectlombok:lombok:${rootProject.lombok_version}"
|
|
|
|
testCompileOnly "org.projectlombok:lombok:${rootProject.lombok_version}"
|
|
testAnnotationProcessor "org.projectlombok:lombok:${rootProject.lombok_version}"
|
|
testImplementation platform("org.junit:junit-bom:${rootProject.junit_version}")
|
|
testImplementation 'org.junit.jupiter:junit-jupiter'
|
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
|
}
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.encoding = 'UTF-8'
|
|
}
|
|
|
|
tasks.withType(Test).configureEach {
|
|
useJUnitPlatform()
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Shared modules: zero Minecraft on the classpath.
|
|
//
|
|
// These compile to Java 17 bytecode because 1.20-1.20.4 run on a Java 17 JVM.
|
|
// That is a real constraint on the code, not just a flag: no virtual threads
|
|
// and no Java 21 pattern matching in shared code.
|
|
// ---------------------------------------------------------------------------
|
|
configure(sharedProjects()) {
|
|
// java-library so a module can re-export what its consumers legitimately
|
|
// need: :shared:ui hands RenderBridge types straight to platform code.
|
|
apply plugin: 'java-library'
|
|
|
|
java {
|
|
toolchain { languageVersion = JavaLanguageVersion.of(21) }
|
|
}
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.release = rootProject.shared_java as int
|
|
}
|
|
|
|
dependencies {
|
|
// Gson ships inside Minecraft's own dependency set on every supported
|
|
// version, so we compile against it but never bundle it. See
|
|
// docs/PORTING.md for the version range this has to stay within.
|
|
compileOnly "com.google.code.gson:gson:${rootProject.gson_api_version}"
|
|
compileOnly "org.slf4j:slf4j-api:${rootProject.slf4j_api_version}"
|
|
|
|
testImplementation "com.google.code.gson:gson:${rootProject.gson_api_version}"
|
|
testImplementation "org.slf4j:slf4j-api:${rootProject.slf4j_api_version}"
|
|
testRuntimeOnly "org.slf4j:slf4j-simple:${rootProject.slf4j_api_version}"
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Platform modules: the only code allowed to touch Minecraft types.
|
|
// ---------------------------------------------------------------------------
|
|
configure(platformProjects()) {
|
|
apply plugin: 'fabric-loom'
|
|
|
|
def mcVersion = project.property('minecraft_version')
|
|
def mcJava = project.property('mc_java') as int
|
|
def deobfuscated = project.property('deobfuscated').toBoolean()
|
|
|
|
// Minecraft 26.x ships already deobfuscated, so Loom has nothing to remap.
|
|
// It still insists on a mappings artifact carrying a 'named' namespace, so
|
|
// we hand it a header-only tiny-v2 file: three namespaces, zero rows, which
|
|
// Loom reads as "every name maps to itself".
|
|
//
|
|
// This is written during configuration rather than by a task because Loom
|
|
// resolves the mappings configuration while it configures the project --
|
|
// a task output would not exist yet. It is 47 bytes and deterministic.
|
|
def identityMappings = null
|
|
if (deobfuscated) {
|
|
identityMappings = layout.buildDirectory
|
|
.file("identity-mappings/identity-mappings-${mcVersion}.jar").get().asFile
|
|
if (!identityMappings.exists()) {
|
|
identityMappings.parentFile.mkdirs()
|
|
new java.util.zip.ZipOutputStream(identityMappings.newOutputStream()).withCloseable { zip ->
|
|
zip.putNextEntry(new java.util.zip.ZipEntry('mappings/mappings.tiny'))
|
|
zip.write("tiny\t2\t0\tofficial\tintermediary\tnamed\n".getBytes('UTF-8'))
|
|
zip.closeEntry()
|
|
}
|
|
}
|
|
}
|
|
|
|
java {
|
|
// javac can always read older bytecode, so one toolchain covers every
|
|
// bucket except 26.x, whose Minecraft classes are Java 25.
|
|
toolchain { languageVersion = JavaLanguageVersion.of(Math.max(mcJava, 21)) }
|
|
withSourcesJar()
|
|
}
|
|
|
|
// The compatibility layer. platform/common holds the adapter code that is
|
|
// textually identical on all nine buckets -- the Fabric entrypoint, the
|
|
// ClientBridge assembly, and the two seams (I18n, KeyboardHandler) that have
|
|
// not moved since 1.20. It is a source root rather than a project because it
|
|
// imports net.minecraft, so it has to be compiled once per bucket against
|
|
// that bucket's Minecraft; there is no single jar it could produce.
|
|
//
|
|
// Everything it calls that *does* differ lives in dev.photosync.platform.impl,
|
|
// which each bucket supplies from its own src/main/java under the same
|
|
// package. Common code names those classes directly and the bucket's source
|
|
// root satisfies them -- so the invariant half is written once, and the half
|
|
// that churns is a per-bucket file the compiler checks.
|
|
sourceSets.main.java.srcDir rootProject.file('platform/common/src/main/java')
|
|
sourceSets.main.resources.srcDir rootProject.file('platform/common/src/main/resources')
|
|
|
|
tasks.withType(JavaCompile).configureEach {
|
|
options.release = mcJava
|
|
}
|
|
|
|
dependencies {
|
|
minecraft "com.mojang:minecraft:${mcVersion}"
|
|
|
|
if (deobfuscated) {
|
|
mappings project.files(identityMappings)
|
|
} else {
|
|
mappings loom.officialMojangMappings()
|
|
}
|
|
|
|
modImplementation "net.fabricmc:fabric-loader:${project.property('loader_version')}"
|
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.property('fabric_api_version')}"
|
|
|
|
// Shared code is compiled once per bucket's bytecode target and folded
|
|
// into the platform jar below. No shading, no jar-in-jar: these are our
|
|
// own classes and they carry no third-party dependencies.
|
|
rootProject.sharedProjects().each { implementation it }
|
|
}
|
|
|
|
loom {
|
|
runs {
|
|
client {
|
|
client()
|
|
ideConfigGenerated = true
|
|
}
|
|
}
|
|
}
|
|
|
|
processResources {
|
|
def tokens = [
|
|
mod_id : rootProject.mod_id,
|
|
mod_name : rootProject.mod_name,
|
|
mod_version : rootProject.mod_version,
|
|
mod_description : rootProject.mod_description,
|
|
mod_license : rootProject.mod_license,
|
|
mod_sources : rootProject.mod_sources,
|
|
minecraft_range : project.property('minecraft_range'),
|
|
loader_version : project.property('loader_version'),
|
|
java_version : String.valueOf(mcJava),
|
|
// Mixin refuses to apply a class whose bytecode is newer than the
|
|
// declared level, and platform classes are compiled at the
|
|
// bucket's own level -- so this has to follow mc_java.
|
|
mixin_compat : "JAVA_${mcJava}",
|
|
]
|
|
inputs.properties(tokens)
|
|
filesMatching(['fabric.mod.json', '*.mixins.json']) { expand(tokens) }
|
|
}
|
|
|
|
jar {
|
|
rootProject.sharedProjects().each { from it.sourceSets.main.output }
|
|
|
|
manifest {
|
|
attributes(
|
|
'Implementation-Title': rootProject.mod_name,
|
|
'Implementation-Version': rootProject.mod_version,
|
|
'Minecraft-Version': mcVersion,
|
|
'Minecraft-Range': project.property('minecraft_range')
|
|
)
|
|
}
|
|
}
|
|
|
|
// Give every bucket's artifact a distinguishable name.
|
|
base.archivesName = "${rootProject.mod_id}-${mcVersion}"
|
|
}
|
|
|
|
// Convenience: build every bucket's shippable jar in one go.
|
|
tasks.register('buildAllPlatforms') {
|
|
group = 'build'
|
|
description = 'Builds the remapped mod jar for every compatibility bucket.'
|
|
dependsOn platformProjects().collect { "${it.path}:build" }
|
|
}
|