昨天在網上看到別人用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文件,多了貌似會衝突。。