diff --git a/.gitignore b/.gitignore
index 417de4ab65..af25077dce 100755
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,12 @@ xcuserdata/
# iOS specific absolute paths
examples/cross_calculator/ios/resources/ui/*.m
examples/cross_calculator/ios/tags
+
+# Android specific absolute paths.
+examples/cross_calculator/android/bin/
+examples/cross_calculator/android/gen/
+examples/cross_calculator/android/jni/backend-jni.h
+examples/cross_calculator/android/libs/
+examples/cross_calculator/android/local.properties
+examples/cross_calculator/android/obj/
+examples/cross_calculator/android/tags
diff --git a/examples/cross_calculator/android/AndroidManifest.xml b/examples/cross_calculator/android/AndroidManifest.xml
new file mode 100644
index 0000000000..05b96fb503
--- /dev/null
+++ b/examples/cross_calculator/android/AndroidManifest.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cross_calculator/android/build.xml b/examples/cross_calculator/android/build.xml
new file mode 100644
index 0000000000..d7c88432a7
--- /dev/null
+++ b/examples/cross_calculator/android/build.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cross_calculator/android/custom_rules.xml b/examples/cross_calculator/android/custom_rules.xml
new file mode 100644
index 0000000000..91783a50e4
--- /dev/null
+++ b/examples/cross_calculator/android/custom_rules.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cross_calculator/android/jni/Android.mk b/examples/cross_calculator/android/jni/Android.mk
new file mode 100644
index 0000000000..c1a0feac3a
--- /dev/null
+++ b/examples/cross_calculator/android/jni/Android.mk
@@ -0,0 +1,32 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := nimrod
+LOCAL_SRC_FILES := nimcache/backend.c nimcache/system.c
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/nimcache
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := backend-jni
+LOCAL_SRC_FILES := backend-jni.c
+LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
+LOCAL_STATIC_LIBRARIES := nimrod
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/examples/cross_calculator/android/jni/backend-jni.c b/examples/cross_calculator/android/jni/backend-jni.c
new file mode 100644
index 0000000000..3d65458ec8
--- /dev/null
+++ b/examples/cross_calculator/android/jni/backend-jni.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include
+#include
+#include "backend-jni.h"
+#include "backend.h"
+
+#define TAG "backend-jni.c"
+
+jint JNICALL Java_com_github_nimrod_crosscalculator_CrossCalculator_myAdd
+ (JNIEnv *env, jobject thiz, jint a, jint b)
+{
+ char buf[256];
+ const jint ret = myAdd(a, b);
+ // Using logging from inside the native bridge to log-debug.
+ sprintf(buf, "a %d + b %d = ret %d", a, b, ret);
+ __android_log_write(ANDROID_LOG_DEBUG, TAG, buf);
+ return ret;
+}
+
+void JNICALL Java_com_github_nimrod_crosscalculator_CrossCalculator_initNimMain
+ (JNIEnv *env, jclass thiz)
+{
+ NimMain();
+ __android_log_write(ANDROID_LOG_DEBUG, TAG, "Nimrod initialised");
+}
+
+// vim:tabstop=2 shiftwidth=2 syntax=c
diff --git a/examples/cross_calculator/android/project.properties b/examples/cross_calculator/android/project.properties
new file mode 100644
index 0000000000..9fb894d9b4
--- /dev/null
+++ b/examples/cross_calculator/android/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-3
diff --git a/examples/cross_calculator/android/readme.txt b/examples/cross_calculator/android/readme.txt
new file mode 100644
index 0000000000..f8b16d4fcf
--- /dev/null
+++ b/examples/cross_calculator/android/readme.txt
@@ -0,0 +1,30 @@
+In this directory you will find the Android platform cross-calculator sample.
+
+Due to the nature of Android being java and nimrod generating C code, the build
+process is slightly more complex because jni code has to be written to bridge
+both languages. In a distant future it may be possible for nimrod to generate
+the whole jni bridge, but for the moment this is manual work.
+
+For the jni bridge to work first the java code is compiled with the nimrod code
+just declared as a native method which will be resolved at runtime. The scripts
+nimbuild.sh and jnibuild.sh are in charge of building the nimrod code and
+generating the jni bridge from the java code respectively. Finally, the
+ndk-build command from the android ndk tools has to be run to build the binary
+libary which will be installed along the final apk.
+
+All these steps are wrapped in the ant build script through the customization
+of the -post-compile rule. If you have the android ndk tools installed and you
+modify scripts/nimbuild.sh to point to the directory where you have nimrod
+installed on your system, you can simply run "ant debug" to build everything.
+
+Once the apk is built you can install it on your device or emulator with the
+command "adb install bin/CrossCalculator-debug.apk".
+
+You can use this example as a starting point for your project or look at the
+history of the github project at https://github.com/gradha/nimrod-on-android.
+That repository documents the individual integration steps you would take for
+any Android project (note it uses Eclipse rather than ant to build and
+therefore the build process requires more manual fiddling).
+
+This example runs against the Android level 3 API, meaning devices from
+Android 1.5 and above should be able to run the generated binary.
diff --git a/examples/cross_calculator/android/res/values/strings.xml b/examples/cross_calculator/android/res/values/strings.xml
new file mode 100644
index 0000000000..05cd3ac93c
--- /dev/null
+++ b/examples/cross_calculator/android/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ CrossCalculator
+
diff --git a/examples/cross_calculator/android/scripts/jnibuild.sh b/examples/cross_calculator/android/scripts/jnibuild.sh
new file mode 100755
index 0000000000..8b61f20f7c
--- /dev/null
+++ b/examples/cross_calculator/android/scripts/jnibuild.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Force errors to fail script.
+set -e
+
+# If we are running from inside the scripts subdir, get out.
+if [ ! -d src ]
+then
+ cd ..
+fi
+
+# Ok, are we out now?
+if [ -d src ]
+then
+ javah -classpath bin/classes \
+ -o jni/backend-jni.h \
+ com.github.nimrod.crosscalculator.CrossCalculator
+else
+ echo "Uh oh, bin/classes directory not found?"
+ echo "Try compiling your java code, or opening in eclipse."
+ exit 1
+fi
diff --git a/examples/cross_calculator/android/scripts/nimbuild.sh b/examples/cross_calculator/android/scripts/nimbuild.sh
new file mode 100755
index 0000000000..97130b8dd6
--- /dev/null
+++ b/examples/cross_calculator/android/scripts/nimbuild.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Set this to the local or full path of your nimrod compiler
+PATH_TO_NIMROD=~/project/nimrod/bin/nimrod
+# Set this to the location of the nimbase.h file so
+# the script can update it if it changes.
+PATH_TO_NIMBASE=~/project/nimrod/lib/nimbase.h
+
+# Force errors to fail script.
+set -e
+
+# If we are running from inside the scripts subdir, get out.
+if [ ! -d src ]
+then
+ cd ..
+fi
+
+DEST_NIMBASE=jni/nimcache/nimbase.h
+
+# Ok, are we out now?
+if [ -d src ]
+then
+ $PATH_TO_NIMROD c --noMain --app:lib \
+ --nimcache:jni/nimcache --cpu:arm --os:linux \
+ --compileOnly --header ../nimrod_backend/*.nim
+ if [ "${PATH_TO_NIMBASE}" -nt "${DEST_NIMBASE}" ]
+ then
+ echo "Updating nimbase.h"
+ cp "${PATH_TO_NIMBASE}" "${DEST_NIMBASE}"
+ fi
+else
+ echo "Uh oh, src directory not found?"
+ exit 1
+fi
diff --git a/examples/cross_calculator/android/scripts/tags.sh b/examples/cross_calculator/android/scripts/tags.sh
new file mode 100755
index 0000000000..95507064f4
--- /dev/null
+++ b/examples/cross_calculator/android/scripts/tags.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [ ! -d src ]
+then
+ cd ..
+fi
+
+if [ -d src ]
+then
+ ~/bin/objctags -R \
+ jni \
+ src
+fi
diff --git a/examples/cross_calculator/android/src/com/github/nimrod/crosscalculator/CrossCalculator.java b/examples/cross_calculator/android/src/com/github/nimrod/crosscalculator/CrossCalculator.java
new file mode 100644
index 0000000000..22a4b9d0c7
--- /dev/null
+++ b/examples/cross_calculator/android/src/com/github/nimrod/crosscalculator/CrossCalculator.java
@@ -0,0 +1,46 @@
+package com.github.nimrod.crosscalculator;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class CrossCalculator extends Activity
+{
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ /* Create a TextView and set its content.
+ * the text is retrieved by calling a native
+ * function.
+ */
+ TextView tv = new TextView(this);
+ final int a = 4;
+ final int b = 18;
+ final int c = myAdd(a, b);
+ tv.setText("myAdd(" + a + ", " + b + ") = " + c);
+ setContentView(tv);
+ }
+
+ /* A native method that is implemented by the
+ * 'backend-jni' native library, which is packaged
+ * with this application. Adds to integers.
+ */
+ public native int myAdd(int a, int b);
+
+ /* A native method used to initialise Nimrod.
+ */
+ static public native void initNimMain();
+
+ /* this is used to load the 'backend-jni' library on application
+ * startup. The library has already been unpacked into
+ * /data/data/com.github.nimrod.backendjni/lib/libbackend-jni.so at
+ * installation time by the package manager.
+ */
+ static {
+ System.loadLibrary("backend-jni");
+ initNimMain();
+ }
+}