Skip to content

Commit

Permalink
Basic setup, shared library loading
Browse files Browse the repository at this point in the history
  • Loading branch information
viandoxdev committed Apr 13, 2024
1 parent 0e40515 commit 2bf52f9
Show file tree
Hide file tree
Showing 10 changed files with 339 additions and 27 deletions.
52 changes: 51 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import org.apache.commons.lang3.SystemUtils
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import java.io.ByteArrayOutputStream
import java.util.regex.Pattern

plugins {
idea
Expand Down Expand Up @@ -75,11 +78,34 @@ val shadowImpl: Configuration by configurations.creating {
configurations.implementation.get().extendsFrom(this)
}

val common by configurations.creating
val shadowCommon by configurations.creating
val backend by configurations.creating {
isCanBeConsumed = false
isCanBeResolved = true
}

configurations {
compileClasspath {
extendsFrom(common)
}
runtimeClasspath {
extendsFrom(common)
}
create("developmentForge") {
extendsFrom(common)
}
}

dependencies {
minecraft("com.mojang:minecraft:1.8.9")
mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9")
forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9")

//common(project(path = ":native", configuration = "namedElements"))
//shadowCommon(project(path = ":native", configuration = "transformProductionForge"))
backend(project("native"))

shadowImpl(kotlin("stdlib-jdk8"))

// If you don't want mixins, remove these lines
Expand All @@ -90,11 +116,23 @@ dependencies {

// If you don't want to log in with your real minecraft account, remove this line
runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:1.1.2")

}

// Tasks:

val identifyHostRustcPlatform = tasks.register<Exec>("identifyRustcHostPlatform") {
commandLine("rustc", "-vV")
standardOutput = ByteArrayOutputStream()
ext.set("output", {
val output = standardOutput.toString()
val matcher = Pattern.compile("^host: (.*)\$", Pattern.MULTILINE).matcher(output)
matcher.find()
val platform = matcher.group(1)
println("Platform is $platform")
platform
})
}

tasks.withType(JavaCompile::class) {
options.encoding = "UTF-8"
}
Expand All @@ -112,6 +150,8 @@ tasks.withType(Jar::class) {
}

tasks.processResources {
dependsOn(identifyHostRustcPlatform)

inputs.property("version", project.version)
inputs.property("mcversion", mcVersion)
inputs.property("modid", modid)
Expand All @@ -122,6 +162,16 @@ tasks.processResources {
}

rename("(.+_at.cfg)", "META-INF/$1")

from(backend) {
eachFile {
if (!name.contains("-") && !name.contains("checksum")) {
// Exclude the artifact from the default Cargo task
exclude()
}
path = "natives/$path"
}
}
}


Expand Down
2 changes: 2 additions & 0 deletions native/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
11 changes: 11 additions & 0 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "smf"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[lib]
crate_type = ["cdylib"]

[dependencies]
113 changes: 113 additions & 0 deletions native/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
plugins {
id 'io.github.arc-blroth.cargo-wrapper' version '1.1.0'
}

repositories {
mavenCentral()
}

import ai.arcblroth.cargo.CargoExtension
import ai.arcblroth.cargo.CargoTask
import com.google.common.collect.ImmutableMap
import com.google.common.collect.ImmutableSet

import java.nio.file.DirectoryStream
import java.nio.file.Files
import java.security.MessageDigest
import java.util.regex.Pattern

Map.Entry<String, TaskProvider<? extends Task>> registerCrossBuildTask(String taskName, String targetName, String dllName) {
def cargoTask = tasks.register(taskName + ".cargo", CargoTask) {
def configuration = new CargoExtension()
// Not needed for now:
// configuration.cargoCommand = 'cross'
configuration.arguments = ['--target', targetName]
configuration.outputs = [(targetName): dllName]
configuration.profile = 'release'
configure(configuration)
dependsOn(getTasksByName("build", false))
}
def copyTask = tasks.register(taskName, Copy) {
dependsOn cargoTask
def task = cargoTask.get()
from(task.outputFiles) {
rename(name -> "$targetName-" + name)
}
into "build/natives/"
}
Map.entry(targetName, copyTask)
}

def cargoCrossBuildTasks = ImmutableMap.copyOf([
registerCrossBuildTask('compileWindowsLibrary', 'x86_64-pc-windows-gnu', 'smf.dll'),
registerCrossBuildTask('compileLinuxLibrary', 'x86_64-unknown-linux-gnu', 'libsmf.so'),
])

cargo {
cargoCommand = 'cargo'
outputs = ['': System.mapLibraryName('smf')]
profile = 'release'
}

def copyHostPlatformNative = tasks.register('copyHostPlatformNative', Copy) {
dependsOn build
mustRunAfter(cargoCrossBuildTasks.values())
def hostTarget = new ByteArrayOutputStream().withStream { outputStream ->
project.exec {
commandLine 'rustc', '-vV'
standardOutput = outputStream
}
def output = outputStream.toString()
def matcher = Pattern.compile("^host: (.*)\$", Pattern.MULTILINE).matcher(output)
matcher.find()
def platform = matcher.group(1)
println("Platform is $platform")
platform
}
from(build.outputFiles) {
rename(name -> "$hostTarget-" + name)
}
into "build/natives/"
}

def createFileDigests = tasks.register('createFileDigests') {
dependsOn copyHostPlatformNative
inputs.dir("build/natives")
outputs.file("build/checksum/checksums.txt")
outputs.files.singleFile.parentFile.mkdirs()
try (def output = new FileWriter(outputs.files.singleFile)) {
for (File file : inputs.files.asFileTree.files) {
MessageDigest digest = MessageDigest.getInstance("SHA-256")
byte[] contents = file.bytes
digest.update(contents)
String digestStr = Base64.encoder.encodeToString(digest.digest())
output.write("" + file.name + "\t" + contents.length + "\t" + digestStr + "\n")
}
}
}

afterEvaluate {
def additionalTargetsStr = System.getProperty("dev.vndx.smf.additionalTargets");
Set<String> additionalTargets = ImmutableSet.of()
if (additionalTargetsStr != null) {
additionalTargets = new HashSet<>(Arrays.asList(additionalTargetsStr.split(",")))
}

def addedTargets = [];
for (def e : cargoCrossBuildTasks) {
if (additionalTargets.contains(e.key)) {
artifacts.add('default', e.value)
addedTargets.add(e.key)
}
}
if (!addedTargets.isEmpty()) {
additionalTargets.removeAll(addedTargets)
}

if (!additionalTargets.isEmpty()) {
throw new GradleException("Unknown targets: " + additionalTargets)
}

artifacts.add('default', copyHostPlatformNative)
artifacts.add('default', createFileDigests)
}
14 changes: 14 additions & 0 deletions native/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version("0.6.0")
}

include("native")

rootProject.name = "smf"
22 changes: 0 additions & 22 deletions src/main/kotlin/dev/vndx/ExampleMod.kt

This file was deleted.

19 changes: 19 additions & 0 deletions src/main/kotlin/dev/vndx/SMF.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.vndx

import dev.vndx.bindings.loadNativeLibrary
import net.minecraft.client.Minecraft
import net.minecraft.init.Blocks
import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.FMLInitializationEvent
import org.apache.logging.log4j.LogManager

@Mod(modid = "smf", useMetadata = true)
class SMF {
@Mod.EventHandler
fun init(event: FMLInitializationEvent) {

val logger = LogManager.getLogger()

loadNativeLibrary(logger)
}
}
Loading

0 comments on commit 2bf52f9

Please sign in to comment.