fully automated reproducible space deterministic builds
This commit is contained in:
parent
130b21f738
commit
f33a2ef11b
34
build.gradle
34
build.gradle
@ -1,7 +1,3 @@
|
||||
import java.util.jar.JarEntry
|
||||
import java.util.jar.JarFile
|
||||
import java.util.jar.JarOutputStream
|
||||
|
||||
/*
|
||||
* This file is part of Baritone.
|
||||
*
|
||||
@ -103,33 +99,3 @@ jar {
|
||||
preserveFileTimestamps = false
|
||||
reproducibleFileOrder = true
|
||||
}
|
||||
|
||||
build {
|
||||
// while "jar" supports preserveFileTimestamps false
|
||||
// reobfJar doesn't, it just sets all the last modified times to that instant where it runs the reobfuscator
|
||||
// so we have to set all those last modified times back to zero
|
||||
doLast {
|
||||
File jarFile = new File("build/libs/baritone-" + version + ".jar")
|
||||
JarFile jf = new JarFile(jarFile)
|
||||
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File("temp.jar")))
|
||||
jf.entries().unique { it.name }.sort { it.name }.each {
|
||||
if (it.name != "META-INF/fml_cache_annotation.json" && it.name != "META-INF/fml_cache_class_versions.json") {
|
||||
JarEntry clone = new JarEntry(it)
|
||||
clone.time = 0
|
||||
jos.putNextEntry(clone)
|
||||
copy(jf.getInputStream(it), jos)
|
||||
}
|
||||
}
|
||||
jos.finish()
|
||||
jf.close()
|
||||
file("temp.jar").renameTo(jarFile)
|
||||
}
|
||||
}
|
||||
|
||||
void copy(InputStream is, OutputStream os) {
|
||||
byte[] buffer = new byte[1024]
|
||||
int len = 0
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len)
|
||||
}
|
||||
}
|
||||
|
49
scripts/Determinizer.java
Normal file
49
scripts/Determinizer.java
Normal file
@ -0,0 +1,49 @@
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0.
|
||||
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
|
||||
* @author leijurv
|
||||
*/
|
||||
public class Determinizer {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
System.out.println("Input path: " + args[0] + " Output path: " + args[1]);
|
||||
JarFile jarFile = new JarFile(new File(args[0]));
|
||||
JarOutputStream jos = new JarOutputStream(new FileOutputStream(new File(args[1])));
|
||||
ArrayList<JarEntry> entries = jarFile.stream().collect(Collectors.toCollection(ArrayList::new));
|
||||
entries.sort(Comparator.comparing(JarEntry::getName));
|
||||
for (JarEntry entry : entries) {
|
||||
if (entry.getName().equals("META-INF/fml_cache_annotation.json")) {
|
||||
continue;
|
||||
}
|
||||
if (entry.getName().equals("META-INF/fml_cache_class_versions.json")) {
|
||||
continue;
|
||||
}
|
||||
JarEntry clone = new JarEntry(entry.getName());
|
||||
clone.setTime(0);
|
||||
jos.putNextEntry(clone);
|
||||
copy(jarFile.getInputStream(entry), jos);
|
||||
}
|
||||
jos.finish();
|
||||
jarFile.close();
|
||||
}
|
||||
|
||||
public static void copy(InputStream is, OutputStream os) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, len);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,9 +3,17 @@ set -e # this makes the whole script fail immediately if any one of these comman
|
||||
./gradlew build
|
||||
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
|
||||
|
||||
cd scripts
|
||||
javac Determinizer.java
|
||||
java Determinizer ../build/libs/baritone-$VERSION.jar temp.jar
|
||||
mv temp.jar ../build/libs/baritone-$VERSION.jar
|
||||
cd ..
|
||||
|
||||
|
||||
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
|
||||
unzip proguard6.0.3.zip 2>&1 > /dev/null
|
||||
cd build/libs
|
||||
rm -rf api.pro
|
||||
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
|
||||
cat ../../scripts/proguard.pro | grep -v "this is the rt jar" | grep -v "\-injars" >> api.pro # remove default rt jar and injar lines
|
||||
echo "-libraryjars '$(java -verbose 2>/dev/null | sed -ne '1 s/\[Opened \(.*\)\]/\1/p')'" >> api.pro # insert correct rt.jar location
|
||||
@ -16,11 +24,17 @@ cat api.pro | grep -v "this is the keep api" > standalone.pro # standalone doesn
|
||||
mkdir -p tempLibraries
|
||||
cat ../../scripts/proguard.pro | grep tempLibraries | grep .jar | cut -d "/" -f 2- | cut -d "'" -f -1 | xargs -n1 -I{} bash -c "find ~/.gradle -name {}" | tee /dev/stderr | xargs -n1 -I{} cp {} tempLibraries
|
||||
|
||||
rm -rf ../../dist
|
||||
mkdir ../../dist
|
||||
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
|
||||
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-api-$VERSION.jar
|
||||
cd ../../scripts
|
||||
java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-api-$VERSION.jar
|
||||
cd ../build/libs
|
||||
rm -rf Obfuscated/*
|
||||
java -jar ../../proguard6.0.3/lib/proguard.jar @standalone.pro
|
||||
mv Obfuscated/baritone-$VERSION.jar ../../dist/baritone-standalone-$VERSION.jar
|
||||
cd ../../scripts
|
||||
java Determinizer ../build/libs/Obfuscated/baritone-$VERSION.jar ../dist/baritone-standalone-$VERSION.jar
|
||||
cd ../build/libs
|
||||
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
|
||||
cd ../../dist
|
||||
shasum * | tee checksums.txt
|
||||
|
Loading…
Reference in New Issue
Block a user