From cca7ade32e59eb9be08a23ec126017f04a18626c Mon Sep 17 00:00:00 2001 From: Terek Campbell Date: Fri, 4 Jan 2013 16:42:11 -0700 Subject: [PATCH] Changed the readme file to a Markdown file --- README.md | 732 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 732 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..8d27542f88 --- /dev/null +++ b/README.md @@ -0,0 +1,732 @@ +Avian - A lightweight Java Virtual Machine (JVM) +================================================ + +[![Build Status](https://travis-ci.org/ReadyTalk/avian.png?branch=master)](https://travis-ci.org/ReadyTalk/avian) + +Quick Start +----------- + +#### on Linux: + $ export JAVA_HOME=/usr/local/java # or wherever you have the JDK installed + $ make + $ build/linux-i386/avian -cp build/linux-i386/test Hello + +#### on Mac OS X: + $ export JAVA_HOME=/Library/Java/Home + $ make + $ build/darwin-i386/avian -cp build/darwin-i386/test Hello + +#### on Windows (MSYS): + $ git clone git@github.com:ReadyTalk/win32.git ../win32 + $ export JAVA_HOME="C:/Program Files/Java/jdk1.6.0_07" + $ make + $ build/windows-i386/avian -cp build/windows-i386/test Hello + +#### on Windows (Cygwin): + $ git clone git@github.com:ReadyTalk/win32.git ../win32 + $ export JAVA_HOME="/cygdrive/c/Program Files/Java/jdk1.6.0_07" + $ make + $ build/windows-i386/avian -cp build/windows-i386/test Hello + +Adjust JAVA_HOME according to your system, but be sure to use forward +slashes in the path. + + +Introduction +------------ + +Avian is a lightweight virtual machine and class library designed to +provide a useful subset of Java's features, suitable for building +self-contained applications. More information is available at the +project [web site](http://oss.readytalk.com/avian). + +If you have any trouble building, running, or embedding Avian, please +post a message to our [discussion group](http://groups.google.com/group/avian). + +That's also the place for any other questions, comments, or +suggestions you might have. + + +Supported Platforms +------------------- + +Avian can currently target the following platforms: + + * Linux (i386, x86_64, ARM, and 32-bit PowerPC) + * Windows (i386 and x86_64) + * Mac OS X (i386, x86_64 and 32-bit PowerPC) + * Apple iOS (i386 and ARM) + + +Building +-------- + +Build requirements include: + + * GNU make 3.80 or later + * GCC 3.4 or later (4.5.1 or later for Windows/x86_64) + or LLVM Clang 3.1 or later (see use-clang option below) + * JDK 1.5 or later + * MinGW 3.4 or later (only if compiling for Windows) + * zlib 1.2.3 or later + +Earlier versions of some of these packages may also work but have not +been tested. + +The build is directed by a single makefile and may be influenced via +certain flags described below, all of which are optional. + + $ make \ + platform={linux,windows,darwin} \ + arch={i386,x86_64,powerpc,arm} \ + process={compile,interpret} \ + mode={debug,debug-fast,fast,small} \ + lzma= \ + ios={true,false} \ + bootimage={true,false} \ + heapdump={true,false} \ + tails={true,false} \ + continuations={true,false} \ + use-clang={true,false} \ + openjdk= \ + openjdk-src= + + * `platform` - the target platform + * _default:_ output of $(uname -s | tr [:upper:] [:lower:]), +normalized in some cases (e.g. CYGWIN_NT-5.1 -> windows) + + * `arch` - the target architecture + * _default:_ output of $(uname -m), normalized in some cases +(e.g. i686 -> i386) + + * `process` - choice between pure interpreter or JIT compiler + * _default:_ compile + + * `mode` - which set of compilation flags to use to determine +optimization level, debug symbols, and whether to enable +assertions + * _default:_ fast + + * `lzma` - if set, support use of LZMA to compress embedded JARs and +boot images. The value of this option should be a directory +containing a recent LZMA SDK (available [here](http://www.7-zip.org/sdk.html)). Currently, only version 9.20 of +the SDK has been tested, but other versions might work. + * _default:_ not set + + * `ios` - if true, cross-compile for iOS on OS X. Note that +non-jailbroken iOS devices do not allow JIT compilation, so only +process=interpret or bootimage=true builds will run on such +devices. See [here](https://github.com/ReadyTalk/hello-ios) for an +example of an Xcode project for iOS which uses Avian. + * _default:_ false + + * `bootimage` - if true, create a boot image containing the pre-parsed +class library and ahead-of-time compiled methods. This option is +only valid for process=compile builds. Note that you may need to +specify both build-arch=x86_64 and arch=x86_64 on 64-bit systems +where "uname -m" prints "i386". + * _default:_ false + + * `heapdump` - if true, implement avian.Machine.dumpHeap(String), +which, when called, will generate a snapshot of the heap in a +simple, ad-hoc format for memory profiling purposes. See +heapdump.cpp for details. + * _default:_ false + + * `tails` - if true, optimize each tail call by replacing the caller's +stack frame with the callee's. This convention ensures proper +tail recursion, suitable for languages such as Scheme. This +option is only valid for process=compile builds. + * _default:_ false + + * `continuations` - if true, support continuations via the +avian.Continuations methods callWithCurrentContinuation and +dynamicWind. See Continuations.java for details. This option is +only valid for process=compile builds. + * _default:_ false + + * `use-clang` - if true, use LLVM's clang instead of GCC to build. +Note that this does not currently affect cross compiles, only +native builds. + * _default:_ false + + * `openjdk` - if set, use OpenJDK class library instead of the default +Avian class library. See "Building with the OpenJDK Class +Library" below for details. + * _default:_ not set + + * `openjdk-src` - if this and the openjdk option above are both set, +build an embeddable VM using the OpenJDK class library. The JNI +components of the OpenJDK class library will be built from the +sources found under the specified directory. See "Building with +the OpenJDK Class Library" below for details. + * _default:_ not set + +These flags determine the name of the directory used for the build. +The name always starts with _${platform}-${arch}_, and each non-default +build option is appended to the name. For example, a debug build with +bootimage enabled on Linux/i386 would be built in +_build/linux-i386-debug-bootimage_. This allows you to build with +several different sets of options independently and even +simultaneously without doing a clean build each time. + +If you are compiling for Windows, you may either cross-compile using +MinGW or build natively on Windows under MSYS or Cygwin. + +#### Installing MSYS: + + __1.__ Download and install the current MinGW and MSYS packages from + mingw.org, selecting the C and C++ compilers when prompted. Use the + post-install script to create the filesystem link to the compiler. + + __2.__ Download GNU Make 3.81 from the MSYS download page + (make-3.81-MSYS-1.0.11-2.tar.bz2) and extract the tar file into + _e.g. c:/msys/1.0_. + +#### Installing Cygwin: + + __1.__ Download and run setup.exe from [cygwin's website](http://www.cygwin.com), installing the base + system and these packages: make, gcc-mingw-g++, + mingw64-i686-gcc-g++, mingw64-x86_64-gcc-g++, and (optionally) git. + +You may also find our win32 repository useful: (run this from the +directory containing the avian directory) + + $ git clone git@github.com:ReadyTalk/win32.git + +This gives you the Windows JNI headers, zlib headers and library, and +a few other useful libraries like OpenSSL, libjpeg, and libpng. +There's also a win64 repository for 64-bit builds: + + $ git clone git@github.com:ReadyTalk/win64.git + + +Building with the Microsoft Visual C++ Compiler +----------------------------------------------- + +You can also build using the MSVC compiler, which makes debugging with +tools like WinDbg and Visual Studio much easier. Note that you will +still need to have GCC installed - MSVC is only used to compile the +C++ portions of the VM, while the assembly code and helper tools are +built using GCC. + +The MSVC build has been tested with Visual Studio Express Edition +versions 8, 9, and 10. Other versions may also work. + +To build with MSVC, install Cygwin as described above and set the +following environment variables: + + $ export PATH="/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/Common7/IDE:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC/BIN:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/Common7/Tools:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v3.5:/cygdrive/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727:/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC/VCPackages:/cygdrive/c/Program Files/Microsoft SDKs/Windows/v6.0A/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem" + $ export LIBPATH="C:\WINDOWS\Microsoft.NET\Framework\v3.5;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;" + $ export VCINSTALLDIR="C:\Program Files\Microsoft Visual Studio 9.0\VC" + $ export LIB="C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB;C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib;" + $ export INCLUDE="C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE;C:\Program Files\Microsoft SDKs\Windows\v6.0A\include;" + +Adjust these definitions as necessary according to your MSVC +installation. + +Finally, build with the msvc flag set to the MSVC tool directory: + + $ make msvc="/cygdrive/c/Program Files/Microsoft Visual Studio 9.0/VC" + +Building with the OpenJDK Class Library +--------------------------------------- + +By default, Avian uses its own lightweight class library. However, +that library only contains a relatively small subset of the classes +and methods included in the JRE. If your application requires +features beyond that subset, you may want to tell Avian to use +OpenJDK's class library instead. To do so, specify the directory +where OpenJDK is installed, e.g.: + + $ make openjdk=/usr/lib/jvm/java-7-openjdk + +This will build Avian as a conventional JVM (e.g. libjvm.so) which +loads its boot class library and native libraries (e.g. libjava.so) +from _/usr/lib/jvm/java-7-openjdk/jre_ at runtime. To run an +application in this configuration, you'll need to make sure the VM is +in your library search path. For example: + + $ LD_LIBRARY_PATH=build/linux-x86_64-openjdk \ + build/linux-x86_64-openjdk/avian-dynamic -cp /path/to/my/application \ + com.example.MyApplication + +Alternatively, you can enable a stand-alone build using OpenJDK by +specifying the location of the OpenJDK source code, e.g.: + + $ make openjdk=$(pwd)/../jdk7/build/linux-amd64/j2sdk-image \ + openjdk-src=$(pwd)/../jdk7/jdk/src + +You must ensure that the path specified for openjdk-src does not have +any spaces in it; make gets confused when dependency paths include +spaces, and we haven't found away around that except to avoid paths +with spaces entirely. + +The result of such a build is a self-contained binary which does not +depend on external libraries, jars, or other files. In this case, the +specified paths are used only at build time; anything needed at +runtime is embedded in the binary. Thus, the process of running an +application is simplified: + + $ build/linux-x86_64-openjdk-src/avian -cp /path/to/my/application \ + com.example.MyApplication + +Note that the resulting binary will be very large due to the size of +OpenJDK's class library. This can be mitigated using UPX, preferably +an LZMA-enabled version: + + $ upx --lzma --best build/linux-x86_64-openjdk-src/avian + +You can reduce the size futher for embedded builds by using ProGuard +and the supplied openjdk.pro configuration file (see "Embedding with +ProGuard and a Boot Image" below). Note that you'll still need to use +vm.pro in that case -- openjdk.pro just adds additional constraints +specific to the OpenJDK port. Also see app.mk in +_git://oss.readytalk.com/avian-swt-examples.git_ for an example of using +Avian, OpenJDK, ProGuard, and UPX in concert. + +Here are some examples of how to install OpenJDK and build Avian with +it on various OSes: + +#### Debian-based Linux: +_Conventional build:_ + + $ apt-get install openjdk-7-jdk + $ make openjdk=/usr/lib/jvm/java-7-openjdk test + +_Stand-alone build:_ + + $ apt-get install openjdk-7-jdk + $ apt-get source openjdk-7-jdk + $ apt-get build-dep openjdk-7-jdk + (cd openjdk-7-7~b147-2.0 && dpkg-buildpackage) + $ make openjdk=/usr/lib/jvm/java-7-openjdk \ + openjdk-src=$(pwd)/openjdk-7-7~b147-2.0/build/openjdk/jdk/src \ + test + +####Mac OS X: +_Prerequisite:_ Build OpenJDK 7 according to [this site](https://wikis.oracle.com/display/OpenJDK/Mac+OS+X+Port). + +_Conventional build:_ + + $ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image test + +_Stand-alone build:_ + + $ make openjdk=$(pwd)/../jdk7u-dev/build/macosx-amd64/j2sdk-image \ + openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test + +####Windows (Cygwin): +_Prerequisite:_ Build OpenJDK 7 according to [this site](http://weblogs.java.net/blog/simonis/archive/2011/10/28/yaojowbi-yet-another-openjdk-windows-build-instruction). + +_Conventional build:_ + + $ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image test + +_Stand-alone build:_ + + $ make openjdk=$(pwd)/../jdk7u-dev/build/windows-i586/j2sdk-image \ + openjdk-src=$(pwd)/../p/jdk7u-dev/jdk/src test + +Currently, only OpenJDK 7 is supported. Later versions might work, +but have not yet been tested. + + +Installing +---------- + +Installing Avian is as simple as copying the executable to the desired +directory: + + $ cp build/${platform}-${arch}/avian ~/bin/ + + +Embedding +--------- + +The following series of commands illustrates how to produce a +stand-alone executable out of a Java application using Avian. + +Note: if you are building on Cygwin, prepend "x86_64-w64-mingw32-" or +"i686-w64-mingw32-" to the ar, g++, gcc, strip, and dlltool commands +below (e.g. x86_64-w64-mingw32-gcc). + +__1.__ Build Avian, create a new directory, and populate it with the +VM object files and bootstrap classpath jar. + + $ make + $ mkdir hello + $ cd hello + $ ar x ../build/${platform}-${arch}/libavian.a + $ cp ../build/${platform}-${arch}/classpath.jar boot.jar + +__2.__ Build the Java code and add it to the jar. + + $ cat >Hello.java <embedded-jar-main.cpp <("-Xbootclasspath:[bootJar]"); + + JavaVM* vm; + void* env; + JNI_CreateJavaVM(&vm, &env, &vmArgs); + JNIEnv* e = static_cast(env); + + jclass c = e->FindClass("Hello"); + 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 + +__on Linux:__ + + $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \ + -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o + +__on Mac OS X:__ + + $ g++ -I$JAVA_HOME/include -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp \ + -o main.o + +__on Windows:__ + + $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/win32 \ + -D_JNI_IMPLEMENTATION_ -c embedded-jar-main.cpp -o main.o + +__5.__ Link the objects produced above to produce the final +executable, and optionally strip its symbols. + +__on Linux:__ + + $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello + $ strip --strip-all hello + +__on Mac OS X:__ + + $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello -framework CoreFoundation + $ strip -S -x hello + +__on Windows:__ + + $ dlltool -z hello.def *.o + $ dlltool -d hello.def -e hello.exp + $ g++ hello.exp *.o -L../../win32/lib -lmingwthrd -lm -lz -lws2_32 \ + -mwindows -mconsole -o hello.exe + $ strip --strip-all hello.exe + +Embedding with ProGuard and a Boot Image +---------------------------------------- + +The following illustrates how to embed an application as above, except +this time we preprocess the code using ProGuard and build a boot image +from it for quicker startup. The pros and cons of using ProGuard are +as follow: + + * Pros: ProGuard will eliminate unused code, optimize the rest, and + obfuscate it as well for maximum space savings + + * Cons: increased build time, especially for large applications, and + extra effort needed to configure it for applications which rely + heavily on reflection and/or calls to Java from native code + +For boot image builds: + + * Pros: the boot image build pre-parses all the classes and compiles + all the methods, obviating the need for JIT compilation at runtime. + This also makes garbage collection faster, since the pre-parsed + classes are never visited. + + * Cons: the pre-parsed classes and AOT-compiled methods take up more + space in the executable than the equivalent class files. In + practice, this can make the executable 30-50% larger. Also, AOT + compilation does not yet yield significantly faster or smaller code + than JIT compilation. Finally, floating point code may be slower + on 32-bit x86 since the compiler cannot assume SSE2 support will be + available at runtime, and the x87 FPU is not supported except via + out-of-line helper functions. + +Note you can use ProGuard without using a boot image and vice-versa, +as desired. + +The following instructions assume we are building for Linux/i386. +Please refer to the previous example for guidance on other platforms. + +__1.__ Build Avian, create a new directory, and populate it with the +VM object files. + + $ make bootimage=true + $ mkdir hello + $ cd hello + $ ar x ../build/linux-i386-bootimage/libavian.a + +__2.__ Create a stage1 directory and extract the contents of the +class library jar into it. + + $ mkdir stage1 + $ (cd stage1 && jar xf ../../build/linux-i386-bootimage/classpath.jar) + +__3.__ Build the Java code and add it to stage1. + + $ cat >Hello.java <hello.pro <bootimage-main.cpp <("-Davian.bootimage=bootimageBin"); + + options[1].optionString + = const_cast("-Davian.codeimage=codeimageBin"); + + JavaVM* vm; + void* env; + JNI_CreateJavaVM(&vm, &env, &vmArgs); + JNIEnv* e = static_cast(env); + + jclass c = e->FindClass("Hello"); + 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 + + $ g++ -I$JAVA_HOME/include -I$JAVA_HOME/include/linux \ + -D_JNI_IMPLEMENTATION_ -c bootimage-main.cpp -o main.o + +__8.__ Link the objects produced above to produce the final + executable, and optionally strip its symbols. + + $ g++ -rdynamic *.o -ldl -lpthread -lz -o hello + $ strip --strip-all hello + + +Trademarks +---------- + +Oracle and Java are registered trademarks of Oracle and/or its +affiliates. Other names may be trademarks of their respective owners. + +The Avian project is not affiliated with Oracle. \ No newline at end of file