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.