Skip to content

Instantly share code, notes, and snippets.

@RichyHBM
Last active August 29, 2018 23:10
Show Gist options
  • Save RichyHBM/8549101a80c92b28c28fb2992a736b3a to your computer and use it in GitHub Desktop.
Save RichyHBM/8549101a80c92b28c28fb2992a736b3a to your computer and use it in GitHub Desktop.
Avian executable with Scala example
//In subdirectory src/Foo
package Foo
object Bar {
val str = "Hello, world!"
}
PLATFORM=macosx
ARCH=x86_64
TAILS=true
SCALA_VERSION=2.11.8
TOP_LEVEL_DIR=$(pwd)
AVIAN_BUILD_DIR=avian/build/$PLATFORM-$ARCH
if [ $TAILS ]; then
AVIAN_BUILD_DIR=avian/build/$PLATFORM-$ARCH-tails
fi
if [ ! -d "avian" ]; then
git clone https://github.com/ReadyTalk/avian.git
git reset --hard edbce08
fi
export JAVA_HOME=$(/usr/libexec/java_home)
cd $TOP_LEVEL_DIR/avian
make platform=$PLATFORM tails=$TAILS
cd $TOP_LEVEL_DIR
mkdir build
cd build
if [ ! -f scala-library.jar ]; then
wget -O scala-library.jar http://central.maven.org/maven2/org/scala-lang/scala-library/$SCALA_VERSION/scala-library-$SCALA_VERSION.jar
fi
unzip scala-library.jar
rm -rf META-INF
rm rootdoc.txt
ar x $TOP_LEVEL_DIR/$AVIAN_BUILD_DIR/libavian.a
cp $TOP_LEVEL_DIR/$AVIAN_BUILD_DIR/classpath.jar boot.jar
mkdir classes
find $TOP_LEVEL_DIR/src/ -name "*.scala" > sources.txt
scalac -bootclasspath boot.jar -d $TOP_LEVEL_DIR/build/classes @sources.txt
mv boot.jar ./classes/
cd classes
jar u0f boot.jar $(find ./ -name "*.class")
cd ..
mv ./classes/boot.jar ./
jar u0f boot.jar library.properties scala/
$TOP_LEVEL_DIR/$AVIAN_BUILD_DIR/binaryToObject/binaryToObject boot.jar \
boot-jar.o _binary_boot_jar_start _binary_boot_jar_end $PLATFORM $ARCH
cp $TOP_LEVEL_DIR/embedded-jar-main.cpp ./
g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/darwin -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o
g++ -rdynamic *.o -ldl -lpthread -lz -o scala-avian -framework CoreFoundation
strip -S -x scala-avian
./scala-avian
#include "stdint.h"
#include "jni.h"
#include "stdlib.h"
#if (defined __MINGW32__) || (defined _MSC_VER)
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __attribute__ ((visibility("default"))) \
__attribute__ ((used))
#endif
#if (! defined __x86_64__) && ((defined __MINGW32__) || (defined _MSC_VER))
# define SYMBOL(x) binary_boot_jar_##x
#else
# define SYMBOL(x) _binary_boot_jar_##x
#endif
extern "C" {
extern const uint8_t SYMBOL(start)[];
extern const uint8_t SYMBOL(end)[];
EXPORT const uint8_t*
bootJar(unsigned* size)
{
*size = SYMBOL(end) - SYMBOL(start);
return SYMBOL(start);
}
} // extern "C"
extern "C" void __cxa_pure_virtual(void) { abort(); }
int
main(int ac, const char** av)
{
JavaVMInitArgs vmArgs;
vmArgs.version = JNI_VERSION_1_2;
vmArgs.nOptions = 1;
vmArgs.ignoreUnrecognized = JNI_TRUE;
JavaVMOption options[vmArgs.nOptions];
vmArgs.options = options;
options[0].optionString = const_cast<char*>("-Xbootclasspath:[bootJar]");
JavaVM* vm;
void* env;
JNI_CreateJavaVM(&vm, &env, &vmArgs);
JNIEnv* e = static_cast<JNIEnv*>(env);
jclass c = e->FindClass("Main");
if (not e->ExceptionCheck()) {
jmethodID m = e->GetStaticMethodID(c, "main", "([Ljava/lang/String;)V");
if (not e->ExceptionCheck()) {
jclass stringClass = e->FindClass("java/lang/String");
if (not e->ExceptionCheck()) {
jobjectArray a = e->NewObjectArray(ac-1, stringClass, 0);
if (not e->ExceptionCheck()) {
for (int i = 1; i < ac; ++i) {
e->SetObjectArrayElement(a, i-1, e->NewStringUTF(av[i]));
}
e->CallStaticVoidMethod(c, m, a);
}
}
}
}
int exitCode = 0;
if (e->ExceptionCheck()) {
exitCode = -1;
e->ExceptionDescribe();
}
vm->DestroyJavaVM();
return exitCode;
}
//In subdirectory src
import Foo._
object Main {
def main(args: Array[String]): Unit = {
println(Bar.str)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment