diff options
-rwxr-xr-x | .gitignore | 9 | ||||
-rw-r--r-- | examples/cross_calculator/android/AndroidManifest.xml | 18 | ||||
-rw-r--r-- | examples/cross_calculator/android/build.xml | 92 | ||||
-rw-r--r-- | examples/cross_calculator/android/custom_rules.xml | 17 | ||||
-rw-r--r-- | examples/cross_calculator/android/jni/Android.mk | 32 | ||||
-rw-r--r-- | examples/cross_calculator/android/jni/backend-jni.c | 42 | ||||
-rw-r--r-- | examples/cross_calculator/android/project.properties | 14 | ||||
-rw-r--r-- | examples/cross_calculator/android/readme.txt | 30 | ||||
-rw-r--r-- | examples/cross_calculator/android/res/values/strings.xml | 4 | ||||
-rwxr-xr-x | examples/cross_calculator/android/scripts/jnibuild.sh | 22 | ||||
-rwxr-xr-x | examples/cross_calculator/android/scripts/nimbuild.sh | 34 | ||||
-rwxr-xr-x | examples/cross_calculator/android/scripts/tags.sh | 13 | ||||
-rw-r--r-- | examples/cross_calculator/android/src/com/github/nimrod/crosscalculator/CrossCalculator.java | 46 |
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(); + } +} |