Add android CMake support
Change-Id: I78b4794786cc1b03946b6b15aa93e46a4303a39c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ffcb2b..f9a6f08 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -153,6 +153,9 @@
option(BUILD_EXAMPLES "Build examples" ON)
option(BUILD_BENCHMARKS "Build Ceres benchmarking suite" ON)
option(BUILD_SHARED_LIBS "Build Ceres as a shared library." OFF)
+if (ANDROID)
+ option(ANDROID_STRIP_DEBUG_SYMBOLS "Strip debug symbols from Android builds (reduces file sizes)" ON)
+endif()
if (MSVC)
option(MSVC_USE_STATIC_CRT
"MS Visual Studio: Use static C-Run Time Library in place of shared." OFF)
@@ -341,6 +344,17 @@
message(" ===============================================================")
endif(NOT SUITESPARSE AND NOT CXSPARSE AND NOT EIGENSPARSE)
+# ANDROID define is set by the Android CMake toolchain file.
+if (ANDROID AND ANDROID_STRIP_DEBUG_SYMBOLS)
+ # Strip debug information unconditionally to avoid +200MB library file sizes.
+ set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s" )
+ set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s" )
+ message(" ================================================================")
+ message(" Please note: When building Ceres for Android, debug information ")
+ message(" is stripped from the Ceres library by default.")
+ message(" ================================================================")
+endif(ANDROID AND ANDROID_STRIP_DEBUG_SYMBOLS)
+
# GFlags.
if (GFLAGS)
# Don't search with REQUIRED as we can continue without gflags.
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
index b80dc25..55bda82 100644
--- a/docs/source/installation.rst
+++ b/docs/source/installation.rst
@@ -41,7 +41,7 @@
more details.
- `CMake <http://www.cmake.org>`_ 3.5 or later.
- **Required on all platforms except for Android.**
+ **Required on all platforms except for legacy Android.**
- `glog <https://github.com/google/glog>`_ 0.3.1 or
later. **Recommended**
@@ -56,17 +56,16 @@
to get more and more verbose and detailed information about Ceres
internals.
- Unfortunately, the current version of `google-glog
- <https://github.com/google/glog>`_ does not build using the Android
- NDK. So, Ceres also ships with a minimal replacement of ``glog``
- called ``miniglog`` that can be enabled with the ``MINIGLOG`` build
- option.
+ Ceres also ships with a minimal replacement of ``glog`` called
+ ``miniglog`` that can be enabled with the ``MINIGLOG`` build option.
+ ``miniglog`` is supplied for platforms which do not support the full
+ version of ``glog``.
- So, in an attempt to reduce dependencies, it is tempting to use
- `miniglog` on platforms other than Android. While there is nothing
- preventing the user from doing so, we strongly recommend against
- it. ``miniglog`` has worse performance than ``glog`` and is much
- harder to control and use.
+ In an attempt to reduce dependencies, it may be tempting to use
+ ``miniglog`` on platforms which already support ``glog``. While
+ there is nothing preventing the user from doing so, we strongly
+ recommend against it. ``miniglog`` has worse performance than
+ ``glog`` and is much harder to control and use.
.. NOTE ::
@@ -495,6 +494,61 @@
Android
=======
+.. NOTE::
+
+ You will need Android NDK r15 or higher to build Ceres solver.
+
+To build Ceres for Android, we need to force ``CMake`` to find
+the toolchains from the Android NDK instead of using the standard
+ones. For example, assuming you have specified ``$NDK_DIR``:
+
+.. code-block:: bash
+
+ cmake \
+ -DCMAKE_TOOLCHAIN_FILE=\
+ $NDK_DIR/build/cmake/android.toolchain.cmake \
+ -DEIGEN_INCLUDE_DIR=/path/to/eigen/header \
+ -DANDROID_ABI=armeabi-v7a \
+ -DANDROID_STL=c++_shared \
+ -DANDROID_NATIVE_API_LEVEL=android-24 \
+ -DBUILD_SHARED_LIBS=ON \
+ -DMINIGLOG=ON \
+ <PATH_TO_CERES_SOURCE>
+
+You can build for any Android STL or ABI, but the c++_shared STL
+and the armeabi-v7a or arm64-v8a ABI are recommended for 32bit
+and 64bit architectures, respectively. Several API levels may
+be supported, but it is recommended that you use the highest
+level that is suitable for your Android project.
+
+.. NOTE::
+
+ You must always use the same API level and STL library for
+ your Android project and the Ceres binaries.
+
+After building, you get a ``libceres.so`` library, which you can
+link in your Android build system by using a
+``PREBUILT_SHARED_LIBRARY`` target in your build script.
+
+If you are building any Ceres samples and would like to verify
+your library, you will need to place them in an executable public
+directory together with ``libceres.so`` on your Android device
+(e.g. in /data/local/tmp) and ensure that the STL library from
+your NDK is present in that same directory. You may then execute
+the sample by running for example:
+
+.. code-block:: bash
+ adb shell
+ cd /data/local/tmp
+ LD_LIBRARY_PATH=/data/local/tmp ./helloworld
+
+Note that any solvers or other shared dependencies you include in
+your project must also be present in your android build config and
+your test directory on Android.
+
+Legacy Android
+==============
+
Download the ``Android NDK`` version ``r9d`` or later. Run
``ndk-build`` from inside the ``jni`` directory. Use the
``libceres.a`` that gets created.
diff --git a/internal/ceres/CMakeLists.txt b/internal/ceres/CMakeLists.txt
index 71996b6..9d8b923 100644
--- a/internal/ceres/CMakeLists.txt
+++ b/internal/ceres/CMakeLists.txt
@@ -164,6 +164,9 @@
if (MINIGLOG)
file(GLOB MINIGLOG_HDRS miniglog/glog/*.h)
list(APPEND CERES_INTERNAL_HDRS ${MINIGLOG_HDRS})
+ if (ANDROID)
+ list(APPEND CERES_LIBRARY_PUBLIC_DEPENDENCIES log)
+ endif()
endif()
# Depend also on public headers so they appear in IDEs.