summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore9
-rw-r--r--examples/cross_calculator/android/AndroidManifest.xml18
-rw-r--r--examples/cross_calculator/android/build.xml92
-rw-r--r--examples/cross_calculator/android/custom_rules.xml17
-rw-r--r--examples/cross_calculator/android/jni/Android.mk32
-rw-r--r--examples/cross_calculator/android/jni/backend-jni.c42
-rw-r--r--examples/cross_calculator/android/project.properties14
-rw-r--r--examples/cross_calculator/android/readme.txt30
-rw-r--r--examples/cross_calculator/android/res/values/strings.xml4
-rwxr-xr-xexamples/cross_calculator/android/scripts/jnibuild.sh22
-rwxr-xr-xexamples/cross_calculator/android/scripts/nimbuild.sh34
-rwxr-xr-xexamples/cross_calculator/android/scripts/tags.sh13
-rw-r--r--examples/cross_calculator/android/src/com/github/nimrod/crosscalculator/CrossCalculator.java46
13 files changed, 373 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 417de4ab6..af25077dc 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 000000000..05b96fb50
--- /dev/null
+++ b/examples/cross_calculator/android/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+		package="com.github.nimrod.crosscalculator"
+		android:versionCode="1"
+		android:versionName="1.0">
+
+	<uses-sdk android:minSdkVersion="3" />
+
+	<application android:label="@string/app_name" android:debuggable="true">
+		<activity android:name=".CrossCalculator"
+			android:label="@string/app_name">
+			<intent-filter>
+				<action android:name="android.intent.action.MAIN" />
+				<category android:name="android.intent.category.LAUNCHER" />
+			</intent-filter>
+		</activity>
+	</application>
+</manifest>
diff --git a/examples/cross_calculator/android/build.xml b/examples/cross_calculator/android/build.xml
new file mode 100644
index 000000000..d7c88432a
--- /dev/null
+++ b/examples/cross_calculator/android/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="CrossCalculator" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contains the path to the SDK. It should *NOT* be checked into
+         Version Control Systems. -->
+    <property file="local.properties" />
+
+    <!-- The ant.properties file can be created by you. It is only edited by the
+         'android' tool to add properties to it.
+         This is the place to change some Ant specific build properties.
+         Here are some properties you may want to change/update:
+
+         source.dir
+             The name of the source directory. Default is 'src'.
+         out.dir
+             The name of the output directory. Default is 'bin'.
+
+         For other overridable properties, look at the beginning of the rules
+         files in the SDK, at tools/ant/build.xml
+
+         Properties related to the SDK location or the project target should
+         be updated using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems.
+
+         -->
+    <property file="ant.properties" />
+
+    <!-- if sdk.dir was not set from one of the property file, then
+         get it from the ANDROID_HOME env var.
+         This must be done before we load project.properties since
+         the proguard config can use sdk.dir -->
+    <property environment="env" />
+    <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+        <isset property="env.ANDROID_HOME" />
+    </condition>
+
+    <!-- The project.properties file is created and updated by the 'android'
+         tool, as well as ADT.
+
+         This contains project specific properties such as project target, and library
+         dependencies. Lower level build properties are stored in ant.properties
+         (or in .classpath for Eclipse projects).
+
+         This file is an integral part of the build system for your
+         application and should be checked into Version Control Systems. -->
+    <loadproperties srcFile="project.properties" />
+
+    <!-- quick check on sdk.dir -->
+    <fail
+            message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+            unless="sdk.dir"
+    />
+
+    <!--
+        Import per project custom build rules if present at the root of the project.
+        This is the place to put custom intermediary targets such as:
+            -pre-build
+            -pre-compile
+            -post-compile (This is typically used for code obfuscation.
+                           Compiled code location: ${out.classes.absolute.dir}
+                           If this is not done in place, override ${out.dex.input.absolute.dir})
+            -post-package
+            -post-build
+            -pre-clean
+    -->
+    <import file="custom_rules.xml" optional="true" />
+
+    <!-- Import the actual build file.
+
+         To customize existing targets, there are two options:
+         - Customize only one target:
+             - copy/paste the target into this file, *before* the
+               <import> task.
+             - customize it to your needs.
+         - Customize the whole content of build.xml
+             - copy/paste the content of the rules files (minus the top node)
+               into this file, replacing the <import> task.
+             - customize to your needs.
+
+         ***********************
+         ****** IMPORTANT ******
+         ***********************
+         In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+         in order to avoid having your file be overridden by tools such as "android update project"
+    -->
+    <!-- version-tag: 1 -->
+    <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
diff --git a/examples/cross_calculator/android/custom_rules.xml b/examples/cross_calculator/android/custom_rules.xml
new file mode 100644
index 000000000..91783a50e
--- /dev/null
+++ b/examples/cross_calculator/android/custom_rules.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="custom_rules" default="debug">
+	<target name="nim">
+		<exec executable="scripts/nimbuild.sh" failonerror="true">
+		</exec>
+	</target>
+	<target name="jni">
+		<exec executable="scripts/jnibuild.sh" failonerror="true">
+		</exec>
+	</target>
+	<target name="ndk">
+		<exec executable="ndk-build" failonerror="true">
+		</exec>
+	</target>
+	<target name="-post-compile" depends="nim, jni, ndk">
+	</target>
+</project>
diff --git a/examples/cross_calculator/android/jni/Android.mk b/examples/cross_calculator/android/jni/Android.mk
new file mode 100644
index 000000000..c1a0feac3
--- /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 000000000..3d65458ec
--- /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 <android/log.h>
+#include <string.h>
+#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 000000000..9fb894d9b
--- /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 000000000..f8b16d4fc
--- /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 000000000..05cd3ac93
--- /dev/null
+++ b/examples/cross_calculator/android/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">CrossCalculator</string>
+</resources>
diff --git a/examples/cross_calculator/android/scripts/jnibuild.sh b/examples/cross_calculator/android/scripts/jnibuild.sh
new file mode 100755
index 000000000..8b61f20f7
--- /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 000000000..97130b8dd
--- /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 000000000..95507064f
--- /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 000000000..22a4b9d0c
--- /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();
+	}
+}