Skip to content

Commit a0bca52

Browse files
committed
Rust build system integration.
1 parent 8194657 commit a0bca52

File tree

8 files changed

+350
-5
lines changed

8 files changed

+350
-5
lines changed

Diff for: Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ RM = rm -f # rm command
44
TARGET_LIB = assign-server/src/main/resources/libassign_pam.so # target lib
55

66
INC = $(JAVA_HOME)/include $(JAVA_HOME)/include/linux ./include
7+
INC += /usr/lib/jvm/java-8-openjdk-amd64/include /usr/lib/jvm/java-8-openjdk-amd64/include/linux/
78
INCDIRS = $(INC:%=-I%)
89

910
CFLAGS = ${INCDIRS} -Wall -Wextra -fPIC -O2 -g

Diff for: libaris/build.gradle

+28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ dependencies {
1212
compile 'org.apache.commons:commons-lang3:3.7'
1313
compile 'org.apache.logging.log4j:log4j-api:2.10.0'
1414
compile 'org.apache.logging.log4j:log4j-core:2.10.0'
15+
compile group: 'commons-io', name: 'commons-io', version: '2.6'
1516

1617
implementation 'org.antlr:antlr4-runtime:4.7.1'
1718
antlr 'org.antlr:antlr4:4.7.1'
@@ -23,3 +24,30 @@ dependencies {
2324

2425
testCompile group: 'junit', name: 'junit', version: '4.12'
2526
}
27+
28+
build { dependsOn "rust-build" }
29+
test { dependsOn "rust-build" }
30+
31+
task "rust-build" {
32+
dependsOn "compileJava"
33+
doFirst {
34+
exec {
35+
workingDir './src/main/rust'
36+
commandLine 'cargo', 'build', '--release'
37+
}
38+
copy {
39+
into './build/resources/main'
40+
from './src/main/rust/target/release/liblibaris_rs.so'
41+
}
42+
}
43+
}
44+
45+
task "get-runtime-classpath" {
46+
doFirst {
47+
def classpath = ''
48+
sourceSets.main.runtimeClasspath.each {
49+
classpath += ':' + it
50+
}
51+
println classpath
52+
}
53+
}

Diff for: libaris/src/main/java/edu/rpi/aris/ast/ASTConstructor.java

+42
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
package edu.rpi.aris.ast;
22

33
import edu.rpi.aris.ast.Expression.*;
4+
import java.io.*;
45
import java.util.*;
56
import org.antlr.v4.runtime.*;
67
import org.antlr.v4.runtime.misc.ParseCancellationException;
78
import org.antlr.v4.runtime.tree.*;
9+
import org.apache.commons.io.IOUtils;
10+
import org.apache.commons.lang3.SystemUtils;
11+
import org.apache.logging.log4j.*;
812

913
public class ASTConstructor extends ParseExpressionBaseVisitor<Expression> implements ParseExpressionVisitor<Expression> {
14+
// TODO: deduplicate with edu.rpi.aris.assign.server.auth.PAMLoginAuth and put into a common util class
15+
private static final Logger log = LogManager.getLogger();
16+
private static final Set<String> loaded = new HashSet();
17+
static { loadLib("liblibaris_rs"); }
18+
private static void loadLib(String LIB_NAME) {
19+
if (!SystemUtils.IS_OS_LINUX) {
20+
// TODO: drop a dll on windows, a .so on mac
21+
return;
22+
}
23+
String LIB_FILE = LIB_NAME + ".so";
24+
log.info("Loading " + LIB_FILE + " native library");
25+
26+
File tmpFile = new File(System.getProperty("java.io.tmpdir"), LIB_FILE);
27+
int i = 0;
28+
while (tmpFile.exists() && !tmpFile.delete())
29+
tmpFile = new File(System.getProperty("java.io.tmpdir"), LIB_NAME + (i++) + ".so");
30+
boolean copied = false;
31+
try (InputStream in = ClassLoader.getSystemResourceAsStream(LIB_FILE);
32+
FileOutputStream out = new FileOutputStream(tmpFile)) {
33+
if (in != null) {
34+
IOUtils.copy(in, out);
35+
copied = true;
36+
}
37+
} catch (IOException e) {
38+
copied = false;
39+
log.error("Failed to extract " + LIB_NAME + " to temp directory", e);
40+
}
41+
if (copied) {
42+
try {
43+
System.load(tmpFile.getCanonicalPath());
44+
loaded.add(LIB_NAME);
45+
} catch (Exception e) {
46+
log.error("Failed to load native " + LIB_NAME + " library", e);
47+
}
48+
}
49+
}
50+
51+
public static native Expression parseViaRust(String s);
1052
public static Expression parse(String s) {
1153
ASTConstructor x = new ASTConstructor();
1254
CharStream cs = new ANTLRInputStream(s);

Diff for: libaris/src/main/java/edu/rpi/aris/ast/Expression.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ public static class PredicateExpression extends Expression {
2525
}
2626
}
2727

28-
public static class UnaryExpression extends Expression {
29-
Expression operand;
28+
public static abstract class UnaryExpression extends Expression {
29+
public Expression operand;
3030
UnaryExpression() { operand = null; }
3131
}
3232
public static class NotExpression extends Expression.UnaryExpression {
3333
@Override public String toString() { return "~" + operand.toString(); }
3434
}
3535

36-
public static class BinaryExpression extends Expression {
37-
Expression l; Expression r;
36+
public static abstract class BinaryExpression extends Expression {
37+
public Expression l; public Expression r;
3838
BinaryExpression() { l = null; r = null; }
3939
}
4040
public static class ImplicationExpression extends Expression.BinaryExpression {
@@ -73,7 +73,7 @@ public static class BiconExpression extends Expression.AssociativeBinopExpressio
7373
}
7474

7575
public static abstract class QuantifierExpression extends Expression {
76-
String boundvar; Expression body;
76+
public String boundvar; public Expression body;
7777
protected abstract String canonicalRepr();
7878
QuantifierExpression() { boundvar = null; body = null; }
7979
@Override public String toString() { return canonicalRepr() + boundvar + ", (" + (body != null ? body.toString() : "null") + ")"; }

Diff for: libaris/src/main/rust/Cargo.lock

+213
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: libaris/src/main/rust/Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "libaris-rs"
3+
version = "0.1.0"
4+
authors = ["Avi Weinstock <[email protected]>"]
5+
6+
[dependencies]
7+
jni = "0.10.2"
8+
9+
[lib]
10+
crate_type = ["cdylib"]

Diff for: libaris/src/main/rust/src/lib.rs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
extern crate jni;
2+
3+
use jni::JNIEnv;
4+
use jni::objects::{JClass, JString};
5+
use jni::sys::jobject;
6+
7+
#[no_mangle]
8+
#[allow(non_snake_case)]
9+
pub extern "system" fn Java_edu_rpi_aris_ast_ASTConstructor_parseViaRust(env: JNIEnv, cls: JClass, e: JString) -> jobject {
10+
println!("Hello from Rust!");
11+
std::ptr::null_mut()
12+
}
13+
14+
15+
16+
#[derive(Debug)]
17+
enum USymbol { Not }
18+
19+
#[derive(Debug)]
20+
enum BSymbol { Implies, Plus, Mult }
21+
22+
#[derive(Debug)]
23+
enum ASymbol { And, Or, Bicon }
24+
25+
#[derive(Debug)]
26+
enum QSymbol { Forall, Exists }
27+
28+
#[derive(Debug)]
29+
enum Expression {
30+
Bottom,
31+
Predicate { name: String, args: Vec<String> },
32+
Unop { symbol: USymbol, operand: Box<Expression> },
33+
Binop { symbol: BSymbol, left: Box<Expression>, right: Box<Expression> },
34+
AssocBinop { symbol: ASymbol, exprs: Vec<Expression> },
35+
Quantifier { symbol: QSymbol, name: String, body: Box<Expression> },
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
}

0 commit comments

Comments
 (0)