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.
|
* This file is part of Baritone.
|
||||||
*
|
*
|
||||||
@ -103,33 +99,3 @@ jar {
|
|||||||
preserveFileTimestamps = false
|
preserveFileTimestamps = false
|
||||||
reproducibleFileOrder = true
|
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
|
./gradlew build
|
||||||
export VERSION=$(cat build.gradle | grep "version '" | cut -d "'" -f 2-2)
|
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
|
wget -nv https://downloads.sourceforge.net/project/proguard/proguard/6.0/proguard6.0.3.zip
|
||||||
unzip proguard6.0.3.zip 2>&1 > /dev/null
|
unzip proguard6.0.3.zip 2>&1 > /dev/null
|
||||||
cd build/libs
|
cd build/libs
|
||||||
|
rm -rf api.pro
|
||||||
echo "-injars 'baritone-$VERSION.jar'" >> api.pro # insert current version
|
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
|
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
|
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
|
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
|
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
|
mkdir ../../dist
|
||||||
java -jar ../../proguard6.0.3/lib/proguard.jar @api.pro
|
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
|
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
|
mv baritone-$VERSION.jar ../../dist/baritone-unoptimized-$VERSION.jar
|
||||||
cd ../../dist
|
cd ../../dist
|
||||||
shasum * | tee checksums.txt
|
shasum * | tee checksums.txt
|
||||||
|
Loading…
Reference in New Issue
Block a user