mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-15 07:43:26 +00:00
Adds android example using jni.
This commit is contained in:
9
.gitignore
vendored
9
.gitignore
vendored
@@ -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
|
||||
|
||||
18
examples/cross_calculator/android/AndroidManifest.xml
Normal file
18
examples/cross_calculator/android/AndroidManifest.xml
Normal file
@@ -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>
|
||||
92
examples/cross_calculator/android/build.xml
Normal file
92
examples/cross_calculator/android/build.xml
Normal file
@@ -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>
|
||||
17
examples/cross_calculator/android/custom_rules.xml
Normal file
17
examples/cross_calculator/android/custom_rules.xml
Normal file
@@ -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>
|
||||
32
examples/cross_calculator/android/jni/Android.mk
Normal file
32
examples/cross_calculator/android/jni/Android.mk
Normal file
@@ -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)
|
||||
42
examples/cross_calculator/android/jni/backend-jni.c
Normal file
42
examples/cross_calculator/android/jni/backend-jni.c
Normal file
@@ -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
|
||||
14
examples/cross_calculator/android/project.properties
Normal file
14
examples/cross_calculator/android/project.properties
Normal file
@@ -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
|
||||
30
examples/cross_calculator/android/readme.txt
Normal file
30
examples/cross_calculator/android/readme.txt
Normal file
@@ -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.
|
||||
4
examples/cross_calculator/android/res/values/strings.xml
Normal file
4
examples/cross_calculator/android/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">CrossCalculator</string>
|
||||
</resources>
|
||||
22
examples/cross_calculator/android/scripts/jnibuild.sh
Executable file
22
examples/cross_calculator/android/scripts/jnibuild.sh
Executable file
@@ -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
|
||||
34
examples/cross_calculator/android/scripts/nimbuild.sh
Executable file
34
examples/cross_calculator/android/scripts/nimbuild.sh
Executable file
@@ -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
|
||||
13
examples/cross_calculator/android/scripts/tags.sh
Executable file
13
examples/cross_calculator/android/scripts/tags.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ ! -d src ]
|
||||
then
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ -d src ]
|
||||
then
|
||||
~/bin/objctags -R \
|
||||
jni \
|
||||
src
|
||||
fi
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user