diff --git a/CMakeLists.txt b/CMakeLists.txt index 73893bd8f..4152ecc34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -479,9 +479,10 @@ IF ("${UNIX}" AND NOT ${BUILD_ANDROID}) ENDIF ("${UNIX}" AND NOT ${BUILD_ANDROID}) # Disable threads in mutex.h. Someday, after there is OpenMP support in -# Android, this can get removed. +# Android, this can get removed. Also turn on a workaround for an NDK bug. IF (${BUILD_ANDROID}) ADD_DEFINITIONS(-DCERES_NO_THREADS) + ADD_DEFINITIONS(-DCERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG) ENDIF (${BUILD_ANDROID}) OPTION(DISABLE_TR1 diff --git a/internal/ceres/schur_eliminator_impl.h b/internal/ceres/schur_eliminator_impl.h index a916de089..6120db9b0 100644 --- a/internal/ceres/schur_eliminator_impl.h +++ b/internal/ceres/schur_eliminator_impl.h @@ -532,7 +532,29 @@ ChunkOuterProduct(const CompressedRowBlockStructure* bs, // like the Matrix class does. Eigen::Block block(m, r, c, block1_size, block2_size); - block.noalias() -= b1_transpose_inverse_ete * b2; +#ifdef CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG + // Removing the ".noalias()" annotation on the following statement is + // necessary to produce a correct build with the Android NDK, including + // versions 6, 7, 8, and 8b, when built with STLPort and the + // non-standalone toolchain (i.e. ndk-build). This appears to be a + // compiler bug; if the workaround is not in place, the line + // + // block.noalias() -= b1_transpose_inverse_ete * b2; + // + // gets compiled to + // + // block.noalias() += b1_transpose_inverse_ete * b2; + // + // which breaks schur elimination. Introducing a temporary by removing the + // .noalias() annotation causes the issue to disappear. Tracking this + // issue down was tricky, since the test suite doesn't run when built with + // the non-standalone toolchain. + // + // TODO(keir): Make a reproduction case for this and send it upstream. + block -= b1_transpose_inverse_ete * b2; +#else + block.noalias() -= b1_transpose_inverse_ete * b2; +#endif // CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG } } } diff --git a/jni/Android.mk b/jni/Android.mk index dcd247e66..eaccb2930 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -87,7 +87,8 @@ LOCAL_CFLAGS := $(CERES_EXTRA_DEFINES) \ -DCERES_NO_GFLAGS \ -DCERES_NO_THREADS \ -DCERES_NO_CXSPARSE \ - -DCERES_NO_TR1 + -DCERES_NO_TR1 \ + -DCERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG LOCAL_SRC_FILES := $(CERES_SRC_PATH)/array_utils.cc \ $(CERES_SRC_PATH)/block_evaluate_preparer.cc \