Compare commits

...

2 Commits

Author SHA1 Message Date
s809 7c37a5c370 Run prepare only when needed 2025-04-27 00:40:12 +05:00
s809 b495ac4799 remove python dependency for building with correct sqlite natives 2025-04-27 00:13:24 +05:00
30 changed files with 61 additions and 36 deletions
-1
View File
@@ -29,7 +29,6 @@ buildAllJars/
relocate_natives/.venv/ relocate_natives/.venv/
relocate_natives/__pycache__/ relocate_natives/__pycache__/
relocate_natives/apple-codesign/ relocate_natives/apple-codesign/
relocate_natives/cache/
# file from notepad++ # file from notepad++
*.bak *.bak
-3
View File
@@ -17,9 +17,6 @@ variables:
# These can be extended so code is a bit less duplicated # These can be extended so code is a bit less duplicated
.build_java: .build_java:
#image: eclipse-temurin:17 #image: eclipse-temurin:17
before_script:
- apt-get update
- apt-get install python3 python3-pip python-is-python3 python3-venv -y --no-install-recommends
cache: cache:
key: "gradleCache_$CI_JOB_NAME_SLUG" key: "gradleCache_$CI_JOB_NAME_SLUG"
policy: pull-push policy: pull-push
+3 -25
View File
@@ -106,24 +106,12 @@ forgix {
class NativeTransformer implements Transformer { class NativeTransformer implements Transformer {
private boolean enabled = false
private final HashMap<String, String> replacements = new HashMap() private final HashMap<String, String> replacements = new HashMap()
private final HashMap<String, byte[]> rewrittenFiles = new HashMap() private final HashMap<String, byte[]> rewrittenFiles = new HashMap()
private var nativeRelocator private var nativeRelocator
public File rootDir public File rootDir
NativeTransformer() {
try {
int exitCode = Runtime.getRuntime().exec(new String[]{"python", "--version"}).waitFor()
if (exitCode == 0) {
enabled = true
}
} catch (IOException e) {
println(e)
}
}
void relocateNative(String target, String replacement) { void relocateNative(String target, String replacement) {
if (replacement.length() > target.length()) { if (replacement.length() > target.length()) {
throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}") throw new GradleException("Length of value \"${replacement}\" exceeds the length of \"${target}\": ${replacement.length()} > ${target.length()}")
@@ -132,22 +120,15 @@ class NativeTransformer implements Transformer {
replacements.put(target, replacement) replacements.put(target, replacement)
} }
void before(Closure closure) {
if (enabled)
closure.run()
}
@Override @Override
boolean canTransformResource(@Nonnull FileTreeElement element) { boolean canTransformResource(@Nonnull FileTreeElement element) {
return enabled && replacements.keySet().stream().anyMatch { return replacements.keySet().stream().anyMatch {
element.name.startsWith(it as String) element.name.startsWith(it as String)
} }
} }
@Override @Override
void transform(@Nonnull TransformerContext context) { void transform(@Nonnull TransformerContext context) {
println("Transforming $context.path...")
byte[] content = context.is.readAllBytes() byte[] content = context.is.readAllBytes()
if (nativeRelocator == null) { if (nativeRelocator == null) {
@@ -395,16 +376,13 @@ subprojects { p ->
// Sqlite Database // Sqlite Database
// librariesLocation isn't used because it's too long for replacing paths in native libraries // librariesLocation isn't used because it's too long for replacing paths in native libraries
// Allowing strings larger than the original string would require shifting the entire binary's contents // Allowing strings larger than the original string would require shifting the entire binary's contents
transform(NativeTransformer) {
rootDir = project.rootDir
before {
relocate "org.sqlite", "dh_sqlite", { relocate "org.sqlite", "dh_sqlite", {
exclude "org/sqlite/native/**" exclude "org/sqlite/native/**"
} }
relocate "jdbc:sqlite", "jdbc:dh_sqlite" relocate "jdbc:sqlite", "jdbc:dh_sqlite"
}
transform(NativeTransformer) {
rootDir = project.rootDir
relocateNative "org/sqlite", "dh_sqlite" relocateNative "org/sqlite", "dh_sqlite"
relocateNative "org_sqlite", "dh_1sqlite" relocateNative "org_sqlite", "dh_1sqlite"
} }
+7 -3
View File
@@ -12,14 +12,15 @@ class NativeRelocator
/** /**
* Initializes the NativeRelocator by preparing the environment if necessary. * Initializes the NativeRelocator by preparing the environment if necessary.
* Executes the appropriate preparation script based on the OS. * Executes the appropriate preparation script based on the OS.
*
* @throws Exception if the preparation script fails or an unsupported OS is detected.
*/ */
NativeRelocator(Path rootDirectory) throws Exception NativeRelocator(Path rootDirectory)
{ {
this.rootDirectory = rootDirectory; this.rootDirectory = rootDirectory;
this.cacheRoot = this.rootDirectory.resolve("cache"); this.cacheRoot = this.rootDirectory.resolve("cache");
}
private void prepare() throws Exception
{
if (this.rootDirectory.resolve(".venv").toFile().exists()) if (this.rootDirectory.resolve(".venv").toFile().exists())
{ {
return; return;
@@ -196,6 +197,9 @@ class NativeRelocator
return Files.readAllBytes(outputFilePath); return Files.readAllBytes(outputFilePath);
} }
System.out.println("Relocating to " + outputPath + "...");
this.prepare();
for (Map.Entry<String, String> replacement : replacements.entrySet()) for (Map.Entry<String, String> replacement : replacements.entrySet())
{ {
this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue()); this.replaceInNullTerminatedStrings(content, replacement.getKey(), replacement.getValue());
+1
View File
@@ -23,6 +23,7 @@ manifold_version=2024.1.37
nightconfig_version=3.6.6 nightconfig_version=3.6.6
lz4_version=1.8.0 lz4_version=1.8.0
xz_version=1.9 xz_version=1.9
# Before updating, read relocate_natives/README.md
sqlite_jdbc_version=3.47.2.0 sqlite_jdbc_version=3.47.2.0
# 8.2.1 is the newest version we can use since that's the version MC 1.16.5 uses # 8.2.1 is the newest version we can use since that's the version MC 1.16.5 uses
fastutil_version=8.2.1 fastutil_version=8.2.1
+46
View File
@@ -0,0 +1,46 @@
This directory contains the native files of libraries that were modified for relocation. They will be copied from here during the normal build steps.
Before adding/updating a library, make sure you have Python 3.8+ installed and check the instructions below.
How to add a library's natives:
1. In `build.gradle`:
- Make sure the target package is the same length or shorter (untested) than the source package. Underscores in native methods will take 2 characters so account for that as well.
- Exclude the native files and add them as `relocateNative` (see example).
Example:
```groovy
relocate "org.sqlite", "dh_sqlite", {
exclude "org/sqlite/native/**"
}
transform(NativeTransformer) {
// NativeTransformer configuration
rootDir = project.rootDir
// Replace native strings, e.g. used in calls back to Java
relocateNative "org/sqlite", "dh_sqlite"
// Rename native methods used when calling from Java
relocateNative "org_sqlite", "dh_1sqlite"
}
```
How to update a library's natives:
1. Delete the library's folder in cache/.
2. It will repopulate during the next build.
Why does this step exist?
- Native files are not handled by the shadow plugin correctly.
- I preferred it as a more streamlined approach, although a bit hacky.
- Possible alternatives:
- Use edited libraries' source code: although more straightforward, it requires maintaining and updating the repositories for the libraries being added
- Interfacing with the necessary libraries directly: an absolute mess for technical reasons
What are libraries used?
- LIEF: for fixing binaries after replacing strings
- apple-codesign: for re-signing Mac binaries, since their signatures get invalidated after previous steps