Skip to content

Commit

Permalink
add ProGuard
Browse files Browse the repository at this point in the history
  • Loading branch information
Nolij committed Apr 29, 2024
1 parent 98bd68e commit 8757907
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ jobs:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release_pre.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release_rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ jobs:
with:
fetch-depth: 0
fetch-tags: true
- name: install advzip
run: sudo apt-get install -y advancecomp
- name: Install Packages
run: sudo apt-get install -y advancecomp proguard-cli
- uses: actions/setup-java@v4
with:
distribution: temurin
Expand Down
40 changes: 23 additions & 17 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,35 @@ operator fun String.invoke(): String = rootProject.properties[this] as? String ?
enum class ReleaseChannel(
val suffix: String? = null,
val releaseType: ReleaseType? = null,
val deflation: JarShrinkingType,
val classes: ClassShrinkingType,
val json: JsonShrinkingType,
val deflation: JarShrinkingType = JarShrinkingType.SEVENZIP,
val classes: ClassShrinkingType = ClassShrinkingType.STRIP_NONE,
val json: JsonShrinkingType = JsonShrinkingType.PRETTY_PRINT,
val proguard: Boolean = false,
) {
DEV_BUILD(
suffix = "dev",
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_NONE,
json = JsonShrinkingType.PRETTY_PRINT),
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY,
proguard = true),
PRE_RELEASE(
suffix = "pre",
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_NONE,
json = JsonShrinkingType.PRETTY_PRINT),
suffix = "pre",
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY,
proguard = true),
RELEASE_CANDIDATE(
suffix = "rc",
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY),
suffix = "rc",
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY,
proguard = true),
RELEASE(
releaseType = ReleaseType.STABLE,
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY),
releaseType = ReleaseType.STABLE,
deflation = JarShrinkingType.SEVENZIP,
classes = ClassShrinkingType.STRIP_ALL,
json = JsonShrinkingType.MINIFY,
proguard = true),
}

val isRelease = rootProject.hasProperty("release_channel")
Expand Down Expand Up @@ -349,6 +354,7 @@ val compressJar = tasks.register<CompressJarTask>("compressJar") {
jarShrinkingType = releaseChannel.deflation
classShrinkingType = releaseChannel.classes
jsonShrinkingType = releaseChannel.json
useProguard(uniminedImpls.flatMap { implName -> project(":$implName").unimined.minecrafts.values })
}

afterEvaluate {
Expand Down
84 changes: 84 additions & 0 deletions buildSrc/src/main/kotlin/dev/nolij/zumegradle/JarCompressing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.gradle.kotlin.dsl.support.uppercaseFirstChar
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.tree.ClassNode
import xyz.wagyourtail.unimined.api.minecraft.MinecraftConfig
import java.io.File
import java.util.jar.JarEntry
import java.util.jar.JarFile
Expand Down Expand Up @@ -131,6 +132,78 @@ fun deflate(zip: File, type: JarShrinkingType) {
}
}

val JAVA_HOME = System.getProperty("java.home")

@Suppress("UnstableApiUsage")
fun applyProguard(outputJar: File, minecraftConfigs: List<MinecraftConfig>) {
val inputJar = outputJar.copyTo(
outputJar.parentFile.resolve("${outputJar.nameWithoutExtension}_.jar"), true)
inputJar.deleteOnExit()

val proguardCommand = ArrayList<String>()
proguardCommand.addAll(arrayOf(
"proguard",
"-ignorewarnings",
"-optimizationpasses", "10",
"-optimizations", "!class/merging/*,!method/marking/private",
"-allowaccessmodification",
"-optimizeaggressively",
"-overloadaggressively",
"-repackageclasses", "dev.nolij.zume",
"-printmapping", outputJar.parentFile.resolve("${outputJar.nameWithoutExtension}-mappings.txt").absolutePath,
"-injars", inputJar.absolutePath,
"-outjars", outputJar.absolutePath,
"-keepattributes", "Runtime*Annotations", // keep annotations
"-keep,allowoptimization", "public class dev.nolij.zume.api.** { public *; }", // public APIs
"-keepclassmembers", "class dev.nolij.zume.impl.config.ZumeConfigImpl { public <fields>; }", // dont rename config fields
"-keep,allowoptimization", "class dev.nolij.zume.ZumeMixinPlugin", // dont rename mixin plugin
"-keep", "class dev.nolij.zume.mixin.** { *; }", // dont touch mixins
"-keep,allowobfuscation,allowoptimization", "@*.*.fml.common.Mod class dev.nolij.zume.** { " + // Forge entrypoints
"public <init>(...); " +
"@*.*.fml.common.Mod\$EventHandler <methods>; " +
"@*.*.fml.common.eventhandler.SubscribeEvent <methods>; }",
"-keepclassmembers,allowoptimization", "class dev.nolij.zume.** { " + // screens
"public void render(int,int,float); " +
"public void tick(); " +
"public void init(); }",
"-keep,allowoptimization", "class dev.nolij.zume.** implements *.*.fml.client.IModGuiFactory", // Legacy Forge config providers
"-keep,allowoptimization", "class dev.nolij.zume.FabricZumeBootstrapper", // referenced in FMJ
"-keep,allowoptimization", "class dev.nolij.zume.modern.integration.ZumeModMenuIntegration", // referenced in FMJ
"-keep,allowoptimization", "class dev.nolij.zume.primitive.event.KeyBindingRegistrar", // referenced in FMJ
"-keep,allowoptimization", "class io.github.prospector.modmenu.** { *; }", // ugly classloader hack
))

val libraries = HashSet<String>()
libraries.add("${JAVA_HOME}/jmods/java.base.jmod")
libraries.add("${JAVA_HOME}/jmods/java.desktop.jmod")

for (minecraftConfig in minecraftConfigs) {
val prodNamespace = minecraftConfig.mcPatcher.prodNamespace

libraries.add(minecraftConfig.getMinecraft(prodNamespace, prodNamespace).toFile().absolutePath)

libraries.addAll(minecraftConfig.mods.getClasspathAs(prodNamespace, prodNamespace,
minecraftConfig.sourceSet.compileClasspath.files
.filter { !minecraftConfig.isMinecraftJar(it.toPath()) }
.toSet())
.filter { it.extension == "jar" }
.filter { !it.name.startsWith("zume") }
.map { it.absolutePath })
}

proguardCommand.add("-libraryjars")
proguardCommand.add(libraries.joinToString(":") { "\"$it\"" })

val process = ProcessBuilder(proguardCommand)
.inheritIO()
.start()
val exitCode = process.waitFor()
inputJar.delete()
if (exitCode != 0) {
error("ProGuard failed for $outputJar")
}
}

open class CompressJarTask : DefaultTask() {
@InputFile
lateinit var inputJar: File
Expand All @@ -143,6 +216,11 @@ open class CompressJarTask : DefaultTask() {

@Input
var jsonShrinkingType = JsonShrinkingType.NONE

@get:Input
val useProguard get() = this.minecraftConfigs != null

private var minecraftConfigs: List<MinecraftConfig>? = null

@get:OutputFile
val outputJar: File
Expand All @@ -165,10 +243,16 @@ open class CompressJarTask : DefaultTask() {
fun setJsonShrinkingType(value: String) {
jsonShrinkingType = JsonShrinkingType.valueOf(value.uppercase())
}

fun useProguard(minecraftConfigs: List<MinecraftConfig>?) {
this.minecraftConfigs = minecraftConfigs
}

@TaskAction
fun compressJar() {
squishJar(inputJar, classShrinkingType, jsonShrinkingType)
deflate(outputJar, jarShrinkingType)
if (useProguard)
applyProguard(outputJar, minecraftConfigs!!)
}
}

0 comments on commit 8757907

Please sign in to comment.