<== Chapter 9 -- Chapter 11 ==>
Chapter 10 - The Makefiles
ndk-build
- So it is possible to use CMake or ndk-build for building your project.
- We will be using ndk-build in this tutorial.
- CMake is definitely the "newer" choice to use as it is compatible with various other platforms.
- Since Tango is a Android platform specific project, I feel justified to use ndk-build.
- Honesty: I don't know how to build NDK in CMake and anyone who does please add it!
Now that we have our code, we need to make sure that everything gets built correctly so we can package the APK to the device. These two files will be used when ndk-build
is ran which should be placed in a your Module build.gradle
file.
externalNativeBuild {
ndkBuild {
path 'src/main/cpp/Android.mk'
}
}
Applicaiton.mk
- This file is where all the more hardware specific options are set
APP_ABI := armeabi-v7a arm64-v8a
- List all the different ISA to build for, you will see a build for each on listed.
- armeabi-v7a is used by the dev kit.
- arm64-v8a is used by the Lenovo Phab 2 Pro.
- (armeabi-v7a == 32-bit system)
- ( arm64-v8a == 64-bit system)
- The Android OS will only install the correct version of the compiled build so unless needed, its suggested to keep all main types listed.
- List all the different ISA to build for, you will see a build for each on listed.
APP_STL := gnustl_static
- The system runtime is the default if there is no APP_STL definition.
- You can only select a single C++ runtime that all your code will depend on.
- It is not possible to mix shared libraries compiled against different C++ runtimes.
- A list of Android C++ Library Support
APP_PLATFORM := android-19
- Tells the ndk-build the minimum version of Android SDK API to build for.
Android.mk
- This file is used to tell which libraries, flags, directories, etc. to use
- The main part to take away from it now is that file is what controls the compiling of your native code
- Really good in depth source of details on Anroid.mk files can be found here
- ALSO here is the official guide sheet from Google
In-depth
- This is where you list all the files you want to compile.
- If you add other files, like
tango_gl
in this case, you need to include its source and headers. - Let's take an example and break it down:
LOCAL_PATH := $(call my-dir)
PROJECT_ROOT_FROM_JNI := ../../../../..
PROJECT_ROOT := $(LOCAL_PATH)/$(PROJECT_ROOT_FROM_JNI)
include $(CLEAR_VARS)
LOCAL_MODULE := libcpp_plane_fitting_example
LOCAL_SHARED_LIBRARIES := tango_client_api tango_support_api
LOCAL_STATIC_LIBRARIES := png
LOCAL_CFLAGS := -std=c++11
LOCAL_C_INCLUDES := $(PROJECT_ROOT)/tango_gl/include \
$(PROJECT_ROOT)/third_party/glm \
$(PROJECT_ROOT)/third_party/libpng/include/
LOCAL_SRC_FILES := jni_interface.cc \
plane_fitting.cc \
plane_fitting_application.cc \
point_cloud_renderer.cc \
$(PROJECT_ROOT_FROM_JNI)/tango_gl/bounding_box.cc \
$(PROJECT_ROOT_FROM_JNI)/tango_gl/camera.cc \
...
...
$(PROJECT_ROOT_FROM_JNI)/tango_gl/obj_loader.cc
LOCAL_LDLIBS := -lGLESv2 -llog -L$(SYSROOT)/usr/lib -lz -landroid
include $(BUILD_SHARED_LIBRARY)
$(call import-add-path,$(PROJECT_ROOT))
$(call import-add-path,$(PROJECT_ROOT)/third_party)
$(call import-module,libpng)
$(call import-module,tango_client_api)
$(call import-module,tango_support_api)
- First not that the
\
is used to continue the line and make the file more readable than having one super long line. - The
$(call _______)
is a way to call special instructions followed by a parameter if valid - So first let's start with with
LOCAL_PATH := $(call my-dir)
This sets the variableLOCAL_PATH
to the directory where theAndroid.mk
file is held. PROJECT_ROOT_FROM_JNI := ../../../../..
is just a way to go up to the top directory five folders up and set it to *PROJECT_ROOT_FROM_JNI
Then we combine the two variables and get the root of the project withPROJECT_ROOT := $(LOCAL_PATH)/$(PROJECT_ROOT_FROM_JNI)
- The
include $(CLEAR_VARS)
variable is provided by the build system and points to a special GNU Makefile that will clear many LOCAL_XXX variables for you with the exception of LOCAL_PATH. - The
LOCAL_MODULE
variable must be defined to identify each module you describe in yourAndroid.mk
. The name must be unique and not contain any spaces. LOCAL_SHARED_LIBRARIES := tango_client_api tango_support_api
- The list of shared libraries modules this module depends on at runtime.LOCAL_STATIC_LIBRARIES := png
- The list of static libraries modules (built withBUILD_STATIC_LIBRARY
) that should be linked to this module. This only makes sense in shared library modules.LOCAL_CFLAGS := -std=c++11
- where we set flags and in this case declare C++ 11LOCAL_C_INCLUDES
- Additional directories to instruct the C/C++ compilers to look for header files in.- The build system looks at
LOCAL_SRC_FILES
to know what source files to compile, make sure you have them all that you need! LOCAL_LDLIBS
The list of additional linker flags to be used when building your module. NOTE you will need -landroid to use the asset_manager library which is part of the<android/asset_manager.h>
file- The
BUILD_SHARED_LIBRARY
is a variable provided by the build system that will start building your shared libraries... I know shocker right? $(call import-add-path,$(PROJECT_ROOT))
will go and take yourPROJECT_ROOT
folder and add it to your path list for the next part$(call import-module,<name>)
A function that allows you to find and include the Android.mk of another module by name. A typical example is. This will look for the module tagged<name>
in the list of directories referenced by yourNDK_MODULE_PATH
environment variable, and include itsAndroid.mk
automatically for you.
<== Chapter 9 -- Chapter 11 ==>