win8.1 cygwin編譯java輕量虛擬機avian

1.背景

  昨天在網上看到別人用aauto寫本地小程序寫的很爽,我以爲若是java的jre能小一點,憑藉java龐大的第三方類庫寫小工具也還算不錯的。本人就常常用eclipse+一些commons包寫些小工具軟件。不過惋惜的是隻能本身用,對於沒裝java環境的人來講就麻煩了。因此就去網上找到了一個輕量級java虛擬機avian。可是在編譯和安裝過程當中遇到了不少困難,特此記錄。java

 

2.開始編譯

  廢話少說,先說重點。其實在這個軟件的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

 

 

3.打包並嵌入虛擬機

# 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的命令行窗口執行就好了函數

 

4.swt配置

在avian的官網有swt的zip包,網上也有介紹,不過安裝時須要注意的是jar包裏面只能有一個dll文件,多了貌似會衝突。。

相關文章
相關標籤/搜索