Android NDK



Introduction

Android Quickstart with a HelloWorld Example. HelloWorld is a simple image classification application that demonstrates how to use PyTorch Android API. This application runs TorchScript serialized TorchVision pretrained resnet18 model on static image which is packaged inside the app as android asset. Download and install the Android NDK. Go to and download the appropriate NDK for your OS. Follow the instructions to extract and install the NDK on your computer. Set up your build environment. Modify your path environment variable to indicate the location of the NDK directory.

Libraries and test apps are often written in C/C++ for testing hardware and software features on Windows*. When these same features are added to an Android* platform, rewriting these libraries and tests in Java* is a large task. It would be preferable to simply port the existing C/C++ code, but many believe that these libraries and tests need to be accessed as Java-based Android applications. But that’s not always the case. If the code to be ported is written in ANSI C/C++ and doesn’t have any OS-specific dependencies, it can be rebuilt using the Android NDK build tools and run from the command line in a shell in much the same way you can run command-line apps from the command prompt in Windows.

If you are using the IL2CPP scripting back end for Android, you need the Android Native Development Kit (NDK). It contains the toolchains (such as compiler and linker) needed to build the necessary libraries, and finally produce the output package (APK). NDK or Native Development Kit is a toolset that is provided by Android to use C or C code in our Android application. So, if you are using Android Studio version 2.2 or higher then you can use C or C in your Android application.

This article shows how to write a simple “Hello World” application and run it on an Android device using a remote shell.

Setting up your development environment

Download and install the Android NDK

Go to https://developer.android.com/ndk/downloads/index.html and download the appropriate NDK for your OS. Follow the instructions to extract and install the NDK on your computer.

Set up your build environment

Modify your path environment variable to indicate the location of the NDK directory. This allows you to run the NDK build tools from any other location on your computer without having to specify the tool’s entire path.

On Linux*, you can modify the variable for your local shell with the following command:

If you’d like the change to be permanent and present in each shell upon opening, add the following line to your ~/.profile or /etc/profile:

Figure 1. Modify the path environment variable.

Android sdk 24

On Windows, you can modify your environment variables by opening the Control Panel > System and Security > System > Advanced system settings > Environment Variables. Find your path variable in the System variables list, and then click Edit. Add a semicolon to the end of the last path, and then add your NDK path to the end. Click OK on each dialog.

Figure 2. Modify the environment variables.

Writing the code and build scripts

Creating your makefiles

To build for Android, you need to have at least two makefiles: Android.mk and Application.mk. Android.mk is similar to the makefiles you might be familiar with for building on Linux from the command line. In this file you can define the source files to build, the header include directories, compiler flag options, libraries and their locations, the module name, and much more. Application.mk is for specifying Android-specific properties, such as the target Android platform, SDK version, and platform architecture.

Figure 3. The Android.mk makefile.

In Android.mk (Figure 3), you can see that a LOCAL_PATH directory is specified. This is initialized to the current directory so that you can use relative paths to other files and directories in the build environment.

The line that includes CLEAR_VARS clears existing local variables that might have been set from previous builds or more complex builds that have multiple makefiles.

The LOCAL_MODULE variable specifies the output name of the binary you’re creating.

The LOCAL_C_INCLUDES variable specifies the directories you want the preprocessor to search for additional include files.

The LOCAL_SRC_FILES variable specifies the specific source files you’d like to be built for this application/library. Place your .c or .cpp files here.

The final line is the key portion to indicate the building of an executable instead of a library. Most native code is built into libraries for Android applications, but changing the value to $(BUILD_EXECUTABLE) in Android.mk will result in an executable.

Figure 4. The Application.mk makefile.

In Application.mk (Figure 4), the first line indicates a build for x86 versus ARM. This tells the NDK to use the correct tool-chain for x86 target architecture.

The second line specifies the platform to build for. In this case, it is version 21, which is for Android 5.0 also known as Lollipop*.

The third line indicates the use of the static version of the standard library runtime.

Ndk

The final line indicates the name of the main makefile for this application.

Writing your application

A command-line application in Android is written in the same way, regardless of the platform. Figure 5 shows an example of a simple “Hello World” application. The cout function is used to print to the screen, and myPrint() is defined in another file.

Figure 5. An example of a simple “Hello World” application.

Android Ndk Tutorial

Figure 6 shows the layout of the folder structure for the project and source files.

Figure 6. The layout of the folder structure for the project and source files.

Building your application

To have the ndk-build script build an application, first create a project folder. In the folder, create a folder named jni. In the jni folder, place the Android.mk file, Application.mk file, and source files.

Then navigate to the project folder in a terminal and execute ndk-build. ndk-build is a script that resides in the root folder of your NDK installation directory. The ndk-build script will parse the project directory and its subfolders and build the application.

Since this example is about building a command-line application, the structure of having it built under a jni folder doesn’t make much sense since there is no Java code or any code to interface with Java. However, removing the jni folder results in two additional steps that must be taken in the build process.

The first step is to specify the NDK project path. Here, it is set to dot (.) for the current working directory.

Then navigate to the project directory and use the ndk-build script. The second step is to specify where the Application.mk file is. Place it in the project directory, so the build command looks like this:

This prints your compile steps, executable creation, and where it “installs” your app. In this case, it creates a libs directory under your project directory. In the libs directory, it will create an x86 directory and place your executable in there.

Figure 7. The build command.

Below is the project tree with the source code and output from the build.

Figure 8. The project tree with the source code and output from the build.

Deploying the application

Installing your application

In order to install your application, you’re going to need a host machine and an adb (Android debug bridge) connection to the Android device from it. You’ll need to use adb to connect to the device. The adb application comes with the Android SDK and can be downloaded as part of the platform tools bundle. Move your application to your host machine (main.out, in this instance). Using adb in a command prompt, you can push the file to your Android device.

Figure 9. Using adb in a command prompt.

Now the main.out executable is on your Android device in the folder you specified.

Running your application

To run your application, first you need to open a shell to your device. You do this with the adb shell command. Now you have a Unix*-like shell open.

Change to the directory where you stored your sample. You can’t yet execute it though. On Unix systems, a file needs to be marked as executable for you to be able to run it. You can do this with the chmod command.

Now you’re ready to run your command line app. Execute it by typing ./<filename> or in this instance: ./main.out.

Figure 10. Running the application.

Congratulations! You can now build and run a command-line application on an Android device.

Author bio and photo

Gideon Eaton is a member of the Intel® Software and Services Group and works with independent software vendors to help them optimize their software for Intel® Atom™ processors. In the past he worked on a team that wrote Linux* graphics drivers for platforms running the Android OS.

The Android NDK is a companion tool to the Android SDK that lets you buildperformance-critical portions of your apps in native code. It provides headers andlibraries that allow you to build activities, handle user input, use hardware sensors,access application resources, and more, when programming in C or C++. If you writenative code, your applications are still packaged into an .apk file and they still runinside of a virtual machine on the device. The fundamental Android application modeldoes not change.

Using native code does not result in an automatic performance increase, but always increases application complexity. If you have not run into any limitationsusing the Android framework APIs, you probably do not need the NDK. Read What is the NDK? for more information about whatthe NDK offers and whether it will be useful to you.

The NDK is designed for use only in conjunction with theAndroid SDK. If you have not already installed and setup the Android SDK, pleasedo so before downloading the NDK.

PlatformPackageSizeMD5 Checksum
Windowsandroid-ndk-r5b-windows.zip61299831 bytes87745ada305ab639399161ab4faf684c
Mac OS X (intel)android-ndk-r5b-darwin-x86.tar.bz250210863 bytes019a14622a377b3727ec789af6707037
Linux 32/64-bit (x86)android-ndk-r5b-linux-x86.tar.bz244138539 bytes4c0045ddc2bfd657be9d5177d0e0b7e7

Revisions

The sections below provide information and notes about successive releases ofthe NDK, as denoted by revision number.

Android NDK, Revision 5b(January 2011)

This release of the NDK does not include any new features compared to r5. The r5b release addresses the following problems in the r5 release:

  • The r5 binaries required glibc 2.11, but the r5b binaries are generated with a special toolchain that targets glibc 2.7 or higher instead. The Linux toolchain binaries now run on Ubuntu 8.04 or higher.
  • Fixes a compiler bug in the arm-linux-androideabi-4.4.3 toolchain. The previous binary generated invalid thumb instruction sequences when dealing with signed chars.
  • Adds missing documentation for the 'gnustl_static' value for APP_STL, that allows you to link against a static library version of GNU libstdc++.
  • The following ndk-build issues are fixed:
    • A bug that created inconsistent dependency files when a compilation error occured on Windows. This prevented a proper build after the error was fixed in the source code.
    • A Cygwin-specific bug where using very short paths for the Android NDK installation or the project path led to the generation of invalid dependency files. This made incremental builds impossible.
    • A typo that prevented the cpufeatures library from working correctly with the new NDK toolchain.
    • Builds in Cygwin are faster by avoiding calls to cygpath -m from GNU Make for every source or object file, which caused problems with very large source trees. In case this doesn't work properly, define NDK_USE_CYGPATH=1 in your environment to use cygpath -m again.
    • The Cygwin installation now notifies the user of invalid installation paths that contain spaces. Previously, an invalid path would output an error that complained about an incorrect version of GNU Make, even if the right one was installed.
  • Fixed a typo that prevented the NDK_MODULE_PATH environment variable from working properly when it contained multiple directories separated with a colon.
  • The prebuilt-common.sh script contains fixes to check the compiler for 64-bit generated machine code, instead of relying on the host tag, which allows the 32-bit toolchain to rebuild properly on Snow Leopard. The toolchain rebuild scripts now also support using a 32-bit host toolchain.
  • A missing declaration for INET_ADDRSTRLEN was added to <netinet/in.h>.
  • Missing declarations for IN6_IS_ADDR_MC_NODELOCAL and IN6_IS_ADDR_MC_GLOBAL were added to <netinet/in6.h>.
  • 'asm' was replaced with '__asm__' in <asm/byteorder.h> to allow compilation with -std=c99.
Android NDK, Revision 5(December 2010)

This release of the NDK includes many new APIs, most of which are introduced to support the development of games and similar applications that make extensive use of native code. Using the APIs, developers have direct native access to events, audio, graphics and window management, assets, and storage. Developers can also implement the Android application lifecycle in native code with help from the new NativeActivity class. For detailed information describing the changes in this release, read the CHANGES.HTML document included in the downloaded NDK package.

General notes:
  • Adds support for native activities, which allows you to implement the Android application lifecycle in native code.
  • Adds native support for the following:
    • Input subsystem (such as the keyboard and touch screen)
    • Access to sensor data (accelerometer, compass, gyroscope, etc).
    • Event loop APIs to wait for things such as input and sensor events.
    • Window and surface subsystem
    • Audio APIs based on the OpenSL ES standard that support playback and recording as well as control over platform audio effects
    • Access to assets packaged in an .apk file.
  • Includes a new toolchain (based on GCC 4.4.3), which generates better code, and can also now be used as a standalone cross-compiler, for people who want to build their stuff with ./configure && make. See docs/STANDALONE-TOOLCHAIN.html for the details. The binaries for GCC 4.4.0 are still provided, but the 4.2.1 binaries were removed.
  • Adds support for prebuilt static and shared libraries (docs/PREBUILTS.html) and module exports and imports to make sharing and reuse of third-party modules much easier (docs/IMPORT-MODULE.html explains why).
  • Provides a default C++ STL implementation (based on STLport) as a helper module. It can be used either as a static or shared library (details and usage examples are in sources/android/stlport/README). Prebuilt binaries for STLport (static or shared) and GNU libstdc++ (static only) are also provided if you choose to compile against those libraries instead of the default C++ STL implementation. C++ Exceptions and RTTI are not supported in the default STL implementation. For more information, see docs/CPLUSPLUS-SUPPORT.HTML.
  • Includes improvements to the cpufeatures helper library that improves reporting of the CPU type (some devices previously reported ARMv7 CPU when the device really was an ARMv6). We recommend developers that use this library to rebuild their applications then upload to Market to benefit from the improvements.
  • Adds an EGL library that lets you create and manage OpenGL ES textures and services.
  • Adds new sample applications, native-plasma and native-activity, to demonstrate how to write a native activity.
  • Includes many bugfixes and other small improvements; see docs/CHANGES.html for a more detailed list of changes.
Android NDK, Revision 4b

Android Ndk 17

(June 2010)
NDK r4b notes:

Includes fixes for several issues in the NDK build and debugging scripts — if you are using NDK r4, we recommend downloading the NDK r4b build. For detailed information describing the changes in this release, read the CHANGES.TXT document included in the downloaded NDK package.

General notes:
Android
  • Provides a simplified build system through the new ndk-build build command.
  • Adds support for easy native debugging of generated machine code on production devices through the new ndk-gdb command.
  • Adds a new Android-specific ABI for ARM-based CPU architectures, armeabi-v7a. The new ABI extends the existing armeabi ABI to include these CPU instruction set extensions:
    • Thumb-2 instructions
    • VFP hardware FPU instructions (VFPv3-D16)
    • Optional support for ARM Advanced SIMD (NEON) GCC intrinsics and VFPv3-D32. Supported by devices such as Verizon Droid by Motorola, Google Nexus One, and others.
  • Adds a new cpufeatures static library (with sources) that lets your app detect the host device's CPU features at runtime. Specifically, applications can check for ARMv7-A support, as well as VFPv3-D32 and NEON support, then provide separate code paths as needed.
  • Adds a sample application, hello-neon, that illustrates how to use the cpufeatures library to check CPU features and then provide an optimized code path using NEON instrinsics, if supported by the CPU.
  • Lets you generate machine code for either or both of the instruction sets supported by the NDK. For example, you can build for both ARMv5 and ARMv7-A architectures at the same time and have everything stored to your application's final .apk.
  • To ensure that your applications are available to users only if their devices are capable of running them, Android Market now filters applications based on the instruction set information included in your application — no action is needed on your part to enable the filtering. Additionally, the Android system itself also checks your application at install time and allows the installation to continue only if the application provides a library that is compiled for the device's CPU architecture.
  • Adds support for Android 2.2, including a new stable API for accessing the pixel buffers of Bitmap objects from native code.
Android NDK, Revision 3Android NDK(March 2010)
General notes:
  • Adds OpenGL ES 2.0 native library support.
  • Adds a sample application,hello-gl2, that illustrates the use of OpenGL ES 2.0 vertex and fragment shaders.
  • The toolchain binaries have been refreshed for this release with GCC 4.4.0, which should generate slightly more compact and efficient machine code than the previous one (4.2.1). The NDK also still provides the 4.2.1 binaries, which you can optionally use to build your machine code.
Android NDK, Revision 2(September 2009)

Originally released as 'Android 1.6 NDK, Release 1'.

General notes:
  • Adds OpenGL ES 1.1 native library support.
  • Adds a sample application, san-angeles, that renders 3D graphics through the native OpenGL ES APIs, while managing activity lifecycle with a GLSurfaceView object.
Android NDK, Revision 1(June 2009)

Originally released as 'Android 1.5 NDK, Release 1'.

Android Ndk Example

General notes:
  • Includes compiler support (GCC) for ARMv5TE instructions, including Thumb-1 instructions.
  • Includes system headers for stable native APIs, documentation, and sample applications.

Installing the NDK

Installing the NDK on your development computer is straightforward and involves extracting the NDK from its download package.

Before you get started make sure that you have downloaded the latest Android SDK and upgraded your applications and environment as needed. The NDK is compatible with older platform versions but not older versions of the SDK tools. Also, take a moment to review the System andSoftware Requirements for the NDK, if you haven't already.

To install the NDK, follow these steps:

  1. From the table at the top of this page, select the NDK package that is appropriate for your development computer and download the package.
  2. Uncompress the NDK download package using tools available on your computer. When uncompressed, the NDK files are contained in a directory called android-ndk-<version>. You can rename the NDK directory if necessary and you can move it to any location on your computer. This documentation refers to the NDK directory as <ndk>.

You are now ready to start working with the NDK.

Getting Started with the NDK

Once you've installed the NDK successfully, take a few minutes to read the documentation included in the NDK. You can find the documentation in the <ndk>/docs/ directory. In particular, please read the OVERVIEW.HTML document completely, so that you understand the intent of the NDK and how to use it.

If you used a previous version of the NDK, take a moment to review the list of NDK changes in the CHANGES.HTML document.

Here's the general outline of how you work with the NDK tools:

  1. Place your native sources under <project>/jni/...
  2. Create <project>/jni/Android.mk to describe your native sources to the NDK build system
  3. Optional: Create <project>/jni/Application.mk.
  4. Build your native code by running the 'ndk-build' script from your project's directory. It is located in the top-level NDK directory:

    The build tools copy the stripped, shared libraries needed by your application to the proper location in the application's project directory.

  5. Finally, compile your application using the SDK tools in the usual way. The SDK build tools will package the shared libraries in the application's deployable .apk file.

For complete information on all of the steps listed above, please see the documentation included with the NDK package.

Sample Applications

The NDK includes sample Android applications that illustrate how to use native code in your Android applications. For more information, see Sample Applications.

Discussion Forum and Mailing List

If you have questions about the NDK or would like to read or contribute to discussions about it, please visit the android-ndk group and mailing list.