diff --git a/CMakeLists.txt b/CMakeLists.txt index a43ecc362..bdfd653e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,7 +215,21 @@ if(RS_LIBRETROSHARE_SHARED) set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif(RS_LIBRETROSHARE_SHARED) -set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) +if(RS_ANDROID) + # As of today Android NDK libc++ doesn't support std::filesystem properly, + # in a very confusing manner the headers have the function declarations but + # then the shared object file doesn't have the implementetion. + # This fools the compiler which doesn't report any error but then at runtime + # we get a crash with this error: + # java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol + # "_ZNSt6__ndk14__fs10filesystem20__create_directoriesERKNS1_4pathEPNS_10error_codeE" + # referenced by "/data/app/==/lib/arm64/libretroshare.so + # So set maximum supported C++ version to 14 to workaround this Android bug + # https://github.com/android/ndk/issues/609 + set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14) +else() + set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) +endif() ## As of today libretroshare doesn't hide implementation details properly so it ## is necessary to flag all implementation headers as public @@ -606,3 +620,18 @@ endif(V_VERSION_SET) ################################################################################ +# TODO: Use generator expressions instead of CMAKE_BUILD_TYPE see +# https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#build-configurations +# https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html#manual:cmake-generator-expressions(7) + +## On Android all symbols except for the few ones used called via JNI can be +## kept hidden allowing for more optimization, and reduced binary size +if(RS_ANDROID AND CMAKE_BUILD_TYPE STREQUAL "Release") + set_property(TARGET ${PROJECT_NAME} PROPERTY C_VISIBILITY_PRESET hidden) + set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_VISIBILITY_PRESET hidden) + set_property(TARGET ${PROJECT_NAME} PROPERTY VISIBILITY_INLINES_HIDDEN ON) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION ON) +endif() diff --git a/build.gradle b/build.gradle index c7f16d61c..938daa099 100644 --- a/build.gradle +++ b/build.gradle @@ -159,7 +159,8 @@ ext.stripLib = { toolchainPath, libDir, - libFile -> + libFile, + stripOptions = "" -> def stripCmd = "$toolchainPath/bin/llvm-strip" assert file(stripCmd).exists() @@ -168,7 +169,7 @@ ext.stripLib = exec { workingDir libDir - commandLine stripCmd, '--strip-unneeded', libFile + commandLine stripCmd, stripOptions, libFile } } @@ -257,9 +258,9 @@ ext.buildLibretroshareNativeLib = * section of this file */ if(pBuildType.equalsIgnoreCase("Release")) { - stripLib(currToolchainPath, currAbiLibDir, "libretroshare.so") - stripLib(currToolchainPath, currAbiLibDir, "libc++_shared.so") - stripLib(currToolchainPath, currAbiLibDir, "liblog.so") + stripLib(currToolchainPath, currAbiLibDir, "libretroshare.so", "--strip-unneeded") + stripLib(currToolchainPath, currAbiLibDir, "libc++_shared.so", "--strip-debug") + stripLib(currToolchainPath, currAbiLibDir, "liblog.so", "--strip-debug") } def bdbootAssetDir = "${getAssetsDir()}/values" diff --git a/misc/Android/GitlabCI_images_prepare.sh b/misc/Android/GitlabCI_images_prepare.sh index 9457b2f3a..05b1916f9 100755 --- a/misc/Android/GitlabCI_images_prepare.sh +++ b/misc/Android/GitlabCI_images_prepare.sh @@ -40,7 +40,7 @@ define_default_value GRADLE_FULL_TASK "build" # set to "none" to disable define_default_value GRADLE_SPLIT_TASKS "bundleDebugAar bundleReleaseAar" -function buildDetachPushAndClean() +function buildDetachPush() { IMAGE_NAME="$1" @@ -48,32 +48,34 @@ function buildDetachPushAndClean() --build-arg ANDROID_MIN_API_LEVEL=${ANDROID_MIN_API_LEVEL} \ --build-arg LIBRETROSHARE_SOURCE_VERSION="$LIBRETROSHARE_SOURCE_VERSION" \ --build-arg GRADLE_BUILD_TASK="$GRADLE_BUILD_TASK" \ - --build-arg JNI_NATIVE_LIBS_ARCHS="$JNI_NATIVE_LIBS_ARCHS" \ + --build-arg JNI_NATIVE_LIBS_ARCHS="$CURR_JNI_NATIVE_LIBS_ARCHS" \ --file misc/Android/Dockerfile . - # Push and clean in parallel with other builds - ((docker push "$IMAGE_NAME" && docker system prune --force)&) + # Start pushing in parallel with other build + ((sleep 1m ; docker push "$IMAGE_NAME")&) } for mApiLevel in $(shuf --echo $ANDROID_MIN_API_LEVELS) ; do ANDROID_MIN_API_LEVEL=$mApiLevel - [ "$mApiLevel" -gt "16" ] || JNI_NATIVE_LIBS_ARCHS="armeabi-v7a" + CURR_JNI_NATIVE_LIBS_ARCHS="$JNI_NATIVE_LIBS_ARCHS" + [ "$mApiLevel" -gt "16" ] || CURR_JNI_NATIVE_LIBS_ARCHS="armeabi-v7a" [ "$GRADLE_FULL_TASK" == "none" ] || { GRADLE_BUILD_TASK="$GRADLE_FULL_TASK" CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_aar_base_${ANDROID_MIN_API_LEVEL}" - buildDetachPushAndClean "$CI_IMAGE_NAME" + buildDetachPush "$CI_IMAGE_NAME" } - for mArch in $(shuf --echo $JNI_NATIVE_LIBS_ARCHS) ; do + [ "$GRADLE_SPLIT_TASKS" == "none" ] || + for mArch in $(shuf --echo $CURR_JNI_NATIVE_LIBS_ARCHS) ; do for mTask in $(shuf --echo $GRADLE_SPLIT_TASKS); do GRADLE_BUILD_TASK=$mTask - JNI_NATIVE_LIBS_ARCHS=$mArch - CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_aar_base_${ANDROID_MIN_API_LEVEL}_${JNI_NATIVE_LIBS_ARCHS}_${GRADLE_BUILD_TASK}" + CURR_JNI_NATIVE_LIBS_ARCHS=$mArch + CI_IMAGE_NAME="registry.gitlab.com/retroshare/retroshare:android_aar_base_${ANDROID_MIN_API_LEVEL}_${CURR_JNI_NATIVE_LIBS_ARCHS}_${GRADLE_BUILD_TASK}" - buildDetachPushAndClean "$CI_IMAGE_NAME" + buildDetachPush "$CI_IMAGE_NAME" done done done diff --git a/misc/Android/prepare-toolchain-clang.sh b/misc/Android/prepare-toolchain-clang.sh index 7e5dbf8a5..9cf4bf9df 100755 --- a/misc/Android/prepare-toolchain-clang.sh +++ b/misc/Android/prepare-toolchain-clang.sh @@ -111,7 +111,6 @@ define_default_value TOOLCHAIN_BUILD_TYPE "" cArch="" eABI="" -cmakeABI="" case "${ANDROID_NDK_ARCH}" in "arm") @@ -139,10 +138,12 @@ export CC="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang export CXX="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-clang++" export AR="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ar" export RANLIB="${NATIVE_LIBS_TOOLCHAIN_PATH}/bin/${cArch}-linux-android${eABI}-ranlib" +# More interesting GNU Make variables at http://www.gnu.org/software/make/manual/make.html#Implicit-Variables # Used to instruct cmake to explicitely ignore host libraries export HOST_IGNORE_PREFIX="/usr/" +export ARMv7_OPTIMIZATION_FLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfp" ## $1 filename, $2 sha256 hash function check_sha256() @@ -191,6 +192,8 @@ function andro_cmake() case "${ANDROID_NDK_ARCH}" in "arm") cmakeProc="armv7-a" + export CFLAGS="$ARMv7_OPTIMIZATION_FLAGS" + export CXXFLAGS="$ARMv7_OPTIMIZATION_FLAGS" ;; "arm64") cmakeProc="aarch64" @@ -213,6 +216,12 @@ function andro_cmake() [ "$TOOLCHAIN_BUILD_TYPE" == "" ] || cmakeBuildType="-DCMAKE_BUILD_TYPE=$TOOLCHAIN_BUILD_TYPE" + cmakeOptimizationsOpt="" + [ "$TOOLCHAIN_BUILD_TYPE" != "Release" ] || + { + cmakeOptimizationsOpt="-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON" + } + cmake \ $cmakeBuildType \ -DCMAKE_SYSTEM_PROCESSOR=$cmakeProc \ @@ -429,10 +438,13 @@ build_openssl() ## non neglegible security concerns. oBits="32" [[ ${ANDROID_NDK_ARCH} =~ .*64.* ]] && oBits=64 + + armOptimizationFlags="" + [[ "${ANDROID_NDK_ARCH}" != "arm" ]] || armOptimizationFlags="$ARMv7_OPTIMIZATION_FLAGS" ANDROID_NDK="${ANDROID_NDK_PATH}" PATH="${SYSROOT}/bin/:${PATH}" \ - ./Configure linux-generic${oBits} -fPIC --prefix="${PREFIX}" \ - --openssldir="${SYSROOT}/etc/ssl" + ./Configure linux-generic${oBits} -fPIC $armOptimizationFlags \ + --prefix="${PREFIX}" --openssldir="${SYSROOT}/etc/ssl" # sed -i 's/LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \\/LIBNAME=$$i \\/g' Makefile # sed -i '/LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \\/d' Makefile @@ -828,9 +840,9 @@ build_libretroshare() -D RS_BRODCAST_DISCOVERY=ON -D RS_EXPORT_JNI_ONLOAD=ON \ -D RS_SQLCIPHER=OFF -D RS_DH_PRIME_INIT_CHECK=OFF \ -D RS_FORUM_DEEP_INDEX=ON -D RS_JSON_API=ON \ - $RS_EXTRA_CMAKE_OPTS || return $? - make -j${HOST_NUM_CPU} || return $? - make install || return $? + $RS_EXTRA_CMAKE_OPTS + make -j${HOST_NUM_CPU} + make install popd )}