昨天在网上看到别人用aauto写本地小程序写的很爽,我以为若是java的jre能小一点,凭借java庞大的第三方类库写小工具也还算不错的。本人就常常用eclipse+一些commons包写些小工具软件。不过惋惜的是只能本身用,对于没装java环境的人来讲就麻烦了。因此就去网上找到了一个轻量级java虚拟机avian。可是在编译和安装过程当中遇到了不少困难,特此记录。java
废话少说,先说重点。其实在这个软件的gihub首页以及清晰的讲述了安装教程,无奈这是英文的,并且主要是本身没有过编译开源程序的经验,也没有玩过什么msys,cygwin的linux编译环境。此次也算是看成一次练习,毕竟之前我只要遇到须要本身编译的开源项目就敬而远之。linux
其实安装的难点有两个,第一个在http://kingj.iteye.com/blog/1614892这个博客中已经一语道破了。。win32/64文件夹要和avian的解压文件夹并列。。我一直觉得要合并着来着,官网也没有特殊说明,本人也没有玩过linux命令行,因此。。不说多了说多了都是泪。。git
第二个就是cygwin的安装。这个的安装注定是要折腾的,虽然网上处处都是教程,可是问题是这些教程有不少细节都没有明说啊,也饶了很多远路。除了通常教程都说的要按照的github
binutils、gcc、gcc-mingw、gdb以外,还要安装make,zlib(第一次安装我照着教程装忘记装avian须要的make了,吐血。。)。这都是32位的,若是你要安装64位的则还有make, gcc-mingw-g++, mingw64-i686-gcc-g++, mingw64-x86_64-gcc-g++, mingw64-x86_64-zlib(这几个其实avian官网有介绍,可是没有介绍zlib。。由于是写在中间,因此我也是后来才看到的,这排版真心不科学。。)反正我电脑是64位的,因此我这几个都安装了,避免出现任何问题。。shell
环境装好了,而后须要的就是照着官网的教程敲命令 了小程序
这里以32位为例。由于在64位下能够编译32位的,可是编译成64位的就不能在32位运行了。windows
$ git clone https://github.com/ReadyTalk/win32.git ../win32 #官网是下载win64,咱们所有改为win32。不过那个官网的git地址有问题,本身去github下载zip复制也行 $ export JAVA_HOME="/cygdrive/c/Program Files/Java/jdk1.7.0_45" #引入JAVA_HOME,至关于windows下cmd的setpath吧 $ make platform=windows arch=i386 #这里须要注意,没有指定编译环境默认就是本机环境,若是电脑是64位的,那么以前你下载的win32头文件会冲突,因此必须指定为i386,若是你是想编译64位的,则以前的git clone就应该是64位的 $ build/windows-i386/avian -cp build/windows-i386/test Hello #这个测试程序运行成功就表明编译成功了。
而后将虚拟机嵌入打包,github上有详细的教程。等我之后再整理。。api
# building platform=windows #make platform=windows arch=i386/x86_64 arch=i386 project=Hello #project名称 mainClass=Hello #main函数所在类 #i686-w64-mingw32- x86_64-w64-mingw32- #这个是个坑爹的地方了,官网没有详细介绍。cygwin须要安装mingw-gcc...等同已系列的文件来支持32位的编译 #若是是32位编译,则ar,gcc,g++,dlltool,strip 要加前缀i686-w64-mingw32- #若是是64位编译,则要加前缀x86_64-w64-mingw32- cd /cygdrive/d/java/avian/avian #转到avian的安装目录 export JAVA_HOME=/cygdrive/d/Java/jdk1.7.0_17 # 第一次须要经过make指令编译avian,如不指定平台,默认就是本地平台。注:在shell中\是换行的意思 #make platform=${platform} arch=${arch} #Embedding #在嵌入以前,须要经过eclipse编写一个 mkdir ../projects/${project} cd ../projects/${project} i686-w64-mingw32-ar x ../../avian/build/${platform}-${arch}/libavian.a #cp ../../avian/build/${platform}-${arch}/classpath.jar boot.jar cat >Hello.java <<EOF public class Hello { public static void main(String[] args) { System.out.println("hello, world!"); } } EOF javac -bootclasspath boot.jar Hello.java #jar u0f boot.jar Hello.class ../../avian/build/${platform}-${arch}/binaryToObject/binaryToObject boot.jar boot-jar.o _binary_boot_jar_start _binary_boot_jar_end ${platform} ${arch} cat >embedded-jar-main.cpp <<EOF #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("${mainClass}"); 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; } EOF i686-w64-mingw32-g++ -fno-exceptions -fno-rtti -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/win32" -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o i686-w64-mingw32-dlltool -z ${project}.def *.o i686-w64-mingw32-dlltool -d ${project}.def -e ${project}.exp i686-w64-mingw32-gcc ${project}.exp *.o -L../../win32/lib -lmingwthrd -lz -lws2_32 \ -lIphlpapi -mwindows -mconsole -o ${project}.exe i686-w64-mingw32-strip --strip-all ${project}.exe
eclipse工程须要去除jre ,而后引入avian/build/windows-xxx/classpath.jar,导出runnable jar包.eclipse
导出以后复制到项目目录中,改名为boot.jar.而后把命令清单复制到cygwin的命令行窗口执行就好了函数
在avian的官网有swt的zip包,网上也有介绍,不过安装时须要注意的是jar包里面只能有一个dll文件,多了貌似会冲突。。