Sep
13
2011

 

What is JNI?  JNI is a set of specifications/framework that allows Java code to call C/C++ native code.  In Android world, JNI is supported through the Android NDK (I think NDK stands for Native Development Kit but even Google doesn’t say what it really stands for on their page: http://developer.android.com/sdk/ndk/index.html). You still need to use Java to call the Native Interfaces, but you can code most of you app in C/C++.

Why use JNI?  I can think of two obvious answers:

1. Execution speed (Java is almost always slower than C/C++ and it is easier to optimize C/C++ code than Java code).

2. Porting from a large C/C++ code-base, for code reuse, to save time and efforts.

Most NDK techniques requires the use of command-line and some sort of Linux shell and that one thing that I really dreaded, but if you are brave enough here’s a link to the documentation: http://developer.android.com/sdk/ndk/overview.html.  Luckily as Android matures, there are several plug-ins that simplifies this, such as Sequoyah: http://www.eclipse.org/sequoyah/documentation/.

This guide assumes that you have already have a basic Android SDK set-up and you know how to compile and run the regular sample projects, as well as creating basic projects.

Let me warn beforehand you that getting the NDK to work can be frustrating — things can go wrong in different parts.  There is not a single package which allows you to just sit back and install just one thing.  You need to install a lot of components, change paths, change settings, and more.  Further complexity added by many different Eclipse versions and configurations, conflicting plug-ins, missing prerequisted plug-ins, etc.

I recommend starting out with a fresh Eclipse install to avoid unnecessary headache altogether. Since Eclipse installation basically only involves extracting the files (and having Java installed), you can have multiple copies of Eclipse as long as they are in different folders.

Setting Up The Development Environment

1. Install Eclipse and the Android SDK

I am using Eclipse Indigo for this guide.  I’m running Windows 7. Here’s the Eclipse About box in case you need it for reference or want to use the exact same one:

Eclipse SDK
Version: 3.7.0
Build id: I20110613-1736
(c) Copyright Eclipse contributors and others 2000, 2011.  All rights reserved.
Visit http://www.eclipse.org/platform
This product includes software developed by the
Apache Software Foundation http://www.apache.org/

Here’s the download link that I use: http://download.eclipse.org/eclipse/downloads/drops/R-3.7-201106131736/winPlatform.php#EclipseSDK.

Android SDK can be retrieved from: http://developer.android.com/sdk/installing.html. I also wrote a guide here: http://permadi.com/blog/2010/02/getting-started-with-android-development-with-eclipse/.

2. Install Eclipse C/C++ Development Tools

After Eclipse is installed, run it and go to the menu->Help->Install New Software.  Select the Indigo or CDT update site.  Select Programming Languages and select/check C/C++ Development Tools

Click Next and install.

3. Install Sequoyah Plug In

The Sequoyah Android plug ins is awesome, this is one plug-in that you need in order to avoid the Command Line stuff.  Download it from the update site. I used  http://download.eclipse.org/sequoyah/updates/2.0/ — this link is meant to be entered in Eclipse, not in the browser.  You can read more about Sequoyah here: http://www.eclipse.org/sequoyah/documentation/.

Again, from menu->Help->Install New Software and enter the update site above. You must uncheck Group Items By Category checkbox (can be seen in the bottom half of the picture below) to see the available components and then just select them all. I am not sure which one is really needed, but I didn’t want really care since there’s no harm installing all.

Once you have Sequoyah installed, I recommend checking out the Sequoyah User Guide section in the Eclipse Help menu at some point because it contains some useful information, some which helped me throughout the way of getting the process going. I will guide you through the setup here so you can skip it for now, but if you encounter issues that are not covered here, check there first.

4. Install Android NDK

In addition to the Android SDK (https://dl-ssl.google.com/android/eclipse/), you need the Android NDK.  You can get the NDK from: http://developer.android.com/sdk/ndk/index.html.  Download and unzip the Android NDK manually (not inside Eclipse). I am using android-ndk-r5c for this guide. I recommend using the latest but if something doesn’t work and you want to narrow down the issue, here’s the link to the version I use for this guide: http://dl.google.com/android/ndk/android-ndk-r5c-windows.zip.

5. Add the PATH of the unzipped Android NDK.

Add the root of the folder where you installed the NDK into the OS environment variable.   For instance, since I unzipped the file into: C:\android-ndk-r5c\, then the PATH to add is C:\android-ndk-r5c\, not any subfolder within it.

Note that there are some sample code in the NDK, but we’re ignoring them for now since they require more complicated compilation process and they do not have Eclipse projects (you’ll need to create the projects by hand).

6. Add Androind NDK path into the Eclipse Android Preferences:

Open the Eclipse Preference (menu -> Window->Preferences), navigate to Android->Native Development then enter the path (yes, the same path as in step 5 again — frankly I am not sure if just doing this step without doing step 5 is enough, so just do both). If you don’t see this option on the Eclipse Preference, restart Eclipse.

6. Review

Now we’re done with installing Eclipse stuff.  To review, here’s my Eclipse configuration (click the image to zoom in).  You can ignore the PDT and PHP plug-ins, I have them just because I’m doing PHP for other stuff.

7. Install Cygwin

Go here, download and run the setup.exe.  I am not 100% sure which components to install but you should just install all the Default components.

IMPORTANT: One component that is not on the default list is the “make” component, under Devel category, make sure to include that when you install.
After installing, add the bin of the folder where you installed cygwin into the OS environment variable (for example: C:\cygwin\bin).

8. Restart Eclipse so that all these changes are known by Eclipse.

Creating A Test Project

Now that we’re done with those ridiculous effort to get the environment set up, we are ready for some fun.  I still recommend to brace yourself for some surprises and cryptic errors, but it’ll be worth it once you got it running.

1. Create a New Android project.

Select API level of at least 9.  Do not use <space> in the project name or Android NDK may complain later.

2. Add Native Support

This is where Sequoyah do its action.

Right click the project on Eclipse Workspace, then select Android Tools -> Add Native Support.

This dialog should come up:

Just leave the default values as they are.  (But if the NDK location is wrong then set it to the path where you installed the Android NDK.)

What this process does is create a Makefile and a stub C++ file for you.  You should see a folder named jni which has been automatically created for you as a subfolder inside your project folder. Inside the jni folder, you should see an Android.mk and a .cpp file.

The cpp file is empty right now but you should take a look at it just for fun.  We’re are finally ready to test building something.  So do Build Project.

Examine the Eclipse Console (to open it, use menu: Window->Show View->Console if it’s not visible already).  You should see something like this:

[c]
**** Build of configuration Default for project TestJNI ****
bash C:\android-ndk-r5c\ndk-build V=1
cygwin warning:
 MS-DOS style path detected: C:\PERMADI_WORKSPACE\TestJNI
 Preferred POSIX equivalent is: /cygdrive/c/PERMADI_WORKSPACE/TestJNI
 CYGWIN environment variable option "nodosfilewarning" turns off this warning.
 Consult the user's guide for more details about POSIX paths:

http://cygwin.com/cygwin-ug-net/using.html#using-pathnames

rm -f /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi/lib*.so /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi-v7a/lib*.so /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/x86/lib*.so
rm -f /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi/gdbserver /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi-v7a/gdbserver /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/x86/gdbserver
rm -f /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi/gdb.setup /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi-v7a/gdb.setup /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/x86/gdb.setup
Install        : libTestJNI.so => libs/armeabi/libTestJNI.so
mkdir -p /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi
install -p /cygdrive/c/PERMADI_WORKSPACE/TestJNI/obj/local/armeabi/libTestJNI.so /cygdrive/c/PERMADI_WORKSPACE/TestJNI/libs/armeabi/libTestJNI.so
/cygdrive/c/android-ndk-r5c/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-strip --strip-unneeded C:/PERMADI_WORKSPACE/TestJNI/libs/armeabi/libTestJNI.so
**** Build Finished ****
[/c]

Pay close attention because errors are not always obviously marked (they are highlighted with a faint red background in the Console. If there is no error, then congratulations.  Most of the hard part are done and the set-up is working.  If there’s any error, try making sure all steps are done; or have a look at the Sequoyah manual (it may have more hints); or check the bottom section of the next tutorial to see if any of the errors apply. There’s one common errors that I would mention here, which is below:

**** Build of configuration Default for project TestNDK ****
ndk-build V=1
Error: Cannot run program "ndk-build": Launching failed
**** Build Finished ****

To solve this, add the full path to the ndk-build command in the Project settings.  For instance, since I have the NDK at C:\android-ndk-r5c\, I entered bash c:\android-ndk-r5c\ndk-build.

In the next part, we will add some C++ code to call from Android: http://www.permadi.com/blog/2011/09/creating-your-first-android-jnindk-project-in-eclipse-with-sequoyah/.

17 Responses to “Setting Up Android JNI/NDK Projects in Windows Eclipse – And Sequoyah”

  1. [...] Setting Up Android JNI Projects in Windows Eclipse – And Sequoyah [...]

  2. Many thanks for this. One little detail left out – add the cygwin binaries folder to PATH as well.

  3. Thanks Dan,
    I have added a note about it.

  4. [...] Setting Up Android JNI Projects in Windows Eclipse – And Sequoyah [...]

  5. [...] I didn't find any infrormation on "Why" this is required. I found a great tutorial here: Setting Up Android JNI Projects in Windows Eclipse – And Sequoyah It helps you also install an extra plugin which helps you get NDK support on your Android [...]

  6. Thank you so much for posting this. It’s the most straightforward tutorial I could find on setting this up. I wanted to not that I came across a make error 258 and had to modify my build command in the C/C++ Build setting further. I changed it to bash C:/Android/android-ndk-r5c/ndk-build NDK_PROJECT_PATH=C:/source/eclipse_workspace/TestJNI

  7. i have been follow your instruction,
    but i got some error when i build project in eclipse

    **** Build of configuration Default for project helloJni ****

    (Cannot run program “ndk-build”: The system cannot find the file specified.
    )

    can you help me..
    thank you very much

  8. Do you see the last paragraph on the article? It talks about this error.

  9. Thanks a lot for this tuto. In step 3, I have got the following error in Eclipse when trying to install teh Sequoyah plugin:

    Cannot complete the install because of a conflicting dependency.
    Software being installed: Sequoyah Android Native Code Support 1.1.2.N20110726-1041 (org.eclipse.sequoyah.android.cdt.feature.feature.group 1.1.2.N20110726-1041)
    Software currently installed: Eclipse C/C++ Development Tools 6.0.0.200909110608 (org.eclipse.cdt.feature.group 6.0.0.200909110608)
    Only one of the following can be installed at once:
    CDT Build System Core 7.0.1.201009141542 (org.eclipse.cdt.managedbuilder.core 7.0.1.201009141542)
    CDT Build System Core 7.0.2.201102110609 (org.eclipse.cdt.managedbuilder.core 7.0.2.201102110609)
    CDT Build System Core 6.0.0.200909110608 (org.eclipse.cdt.managedbuilder.core 6.0.0.200909110608)
    CDT Build System Core 6.0.0.201002161416 (org.eclipse.cdt.managedbuilder.core 6.0.0.201002161416)
    CDT Build System Core 7.0.0.201006141710 (org.eclipse.cdt.managedbuilder.core 7.0.0.201006141710)
    Cannot satisfy dependency:
    From: Eclipse C/C++ Development Tools 6.0.0.200909110608 (org.eclipse.cdt.feature.group 6.0.0.200909110608)
    To: org.eclipse.cdt.platform.feature.group [6.0.0.200909110608]
    Cannot satisfy dependency:
    From: Eclipse C/C++ Development Platform 6.0.0.200909110608 (org.eclipse.cdt.platform.feature.group 6.0.0.200909110608)
    To: org.eclipse.cdt.managedbuilder.core [6.0.0.200909110608]
    Cannot satisfy dependency:
    From: Sequoyah Android Native Support UI 1.1.2.N20110726-1041 (org.eclipse.sequoyah.android.cdt.build.ui 1.1.2.N20110726-1041)
    To: bundle org.eclipse.cdt.managedbuilder.core 7.0.0
    Cannot satisfy dependency:
    From: Sequoyah Android Native Code Support 1.1.2.N20110726-1041 (org.eclipse.sequoyah.android.cdt.feature.feature.group 1.1.2.N20110726-1041)
    To: org.eclipse.sequoyah.android.cdt.build.ui [1.1.2.N20110726-1041]

    Any idea to solve this issue ? Thanks !

  10. I have not experienced that, but this post may help you:
    http://stackoverflow.com/questions/9163285/sequoyah-eclipse-plugin-cannot-complete-the-install-because-of-a-conflicting-d

  11. Also you should check this out…

    http://stackoverflow.com/questions/5954330/hello-jni-ndk-sample-ndk-build-fails

    AND this…

    http://stackoverflow.com/questions/8384213/android-ndk-revision-7-host-awk-tool-is-outdated-error

  12. I am getting this error when I build the project …
    bash D:\Swapnil\android-ndk-r7-windows\android-ndk-r7\ndk-build V=1

    Cannot run program “bash”: Launching failed
    Error: Program “bash” is not found in PATH

    PATH=[D:\Swapnil\android-ndk-r7-windows\android-ndk-r7;E:/Program Files/Java/jre7/bin/client;E:/Program Files/Java/jre7/bin;E:/Program Files/Java/jre7/lib/i386;E:\WINDOWS\system32;E:\WINDOWS;E:\WINDOWS\System32\Wbem;D:\Swapnil\eclipse-java-indigo-SR1-win32(1)\eclipse]

    **** Build Finished ****
    pls help …

  13. Have you installed Cygwin? Make sure to add the Cygwin path onto the Environment variables.

  14. Don’t forget that you’ll need to restart eclipse once the OS PATH environmental has been changed.

    Great article, many thanks.

  15. Important note about Cygwin.
    It is not required step at all.
    Sequoyah plugin really initialize project to use bash unix shell.
    But NDK contains windows cmd script ndk-build.cmd which behave same as unix script ndk-build.
    So we do not need really to install Cygwin under Windows.
    Just after creating project and adding NDK support to it we go to it’s property page and modify build command from:
    bash … ndk-build
    to:
    cmd … ndk-build.cmd
    or just:
    \ndk-build.cmd
    (you can see this property page on the last screenshot)

    That’s all. I tested it and it works.

    Sorry for bad english.

  16. I have no Android section under the preferences?

  17. nvm, ADT was not installed correctly.

Leave a Reply

*