From 341e65f7d51e7acc0bf73893317251adc4d23cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Mon, 20 Feb 2017 19:24:21 +0100 Subject: [build] use system-provided Android NDK when available and fall back to Mason if it isn't --- Makefile | 86 ++++++++++++++++++------------- platform/android/bitrise.yml | 29 ----------- platform/android/config.cmake | 12 +++-- platform/android/scripts/ndk.sh | 111 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 68 deletions(-) create mode 100755 platform/android/scripts/ndk.sh diff --git a/Makefile b/Makefile index 30a5ade7ba..c0c495335f 100644 --- a/Makefile +++ b/Makefile @@ -9,12 +9,12 @@ endif ifeq ($(shell uname -s), Darwin) HOST_PLATFORM = macos HOST_PLATFORM_VERSION = $(shell uname -m) - NINJA ?= platform/macos/ninja + export NINJA = platform/macos/ninja export JOBS ?= $(shell sysctl -n hw.ncpu) else ifeq ($(shell uname -s), Linux) HOST_PLATFORM = linux HOST_PLATFORM_VERSION = $(shell uname -m) - NINJA ?= platform/linux/ninja + export NINJA = platform/linux/ninja export JOBS ?= $(shell grep --count processor /proc/cpuinfo) else $(error Cannot determine host platform) @@ -465,12 +465,19 @@ test-node: node #### Android targets ########################################################### -MBGL_ANDROID_ABIS = arm-v5-9 arm-v7-9 arm-v8-21 x86-9 x86-64-21 mips-9 +MBGL_ANDROID_ABIS = arm-v5;armeabi;9 +MBGL_ANDROID_ABIS += arm-v7;armeabi-v7a;9 +MBGL_ANDROID_ABIS += arm-v8;arm64-v8a;21 +MBGL_ANDROID_ABIS += x86;x86;9 +MBGL_ANDROID_ABIS += x86-64;x86_64;21 +MBGL_ANDROID_ABIS += mips;mips;9 + +MBGL_ANDROID_BUILD_DIR = build/android-$1-$3/$(BUILDTYPE) MBGL_ANDROID_LOCAL_WORK_DIR = /data/local/tmp/core-tests -MBGL_ANDROID_LIBDIR = lib$(if $(filter arm-v8-21 x86-64-21,$1),64) -MBGL_ANDROID_DALVIKVM = dalvikvm$(if $(filter arm-v8-21 x86-64-21,$1),64,32) +MBGL_ANDROID_LIBDIR = lib$(if $(filter arm-v8 x86-64,$1),64) +MBGL_ANDROID_DALVIKVM = dalvikvm$(if $(filter arm-v8 x86-64,$1),64,32) MBGL_ANDROID_APK_SUFFIX = $(if $(filter Release,$(BUILDTYPE)),release-unsigned,debug) -MBGL_ANDROID_CORE_TEST_DIR = build/android-$1/$(BUILDTYPE)/core-tests +MBGL_ANDROID_CORE_TEST_DIR = $(MBGL_ANDROID_BUILD_DIR)/core-tests .PHONY: android-help android-help: @@ -500,26 +507,39 @@ android-style-code: style-code: android-style-code define ANDROID_RULES - -build/android-$1/$(BUILDTYPE)/build.ninja: $(BUILD_DEPS) platform/android/config.cmake - @mkdir -p build/android-$1/$(BUILDTYPE) - export MASON_XC_ROOT=`scripts/mason.sh PREFIX android-ndk VERSION $1-r13b` && \ - cd build/android-$1/$(BUILDTYPE) && cmake ../../.. -G Ninja \ - -DMASON_XC_ROOT="$$$${MASON_XC_ROOT}" \ - -DCMAKE_TOOLCHAIN_FILE="$$$${MASON_XC_ROOT}/toolchain.cmake" \ - -DCMAKE_BUILD_TYPE=$(BUILDTYPE) \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ - -DMBGL_PLATFORM=android \ - -DMASON_PLATFORM=android \ - -DMASON_PLATFORM_VERSION=$1 +# $1 = arm-v7 (short arch) +# $2 = armeabi-v7a (internal arch) +# $3 = 9 (platform version) + +$(MBGL_ANDROID_BUILD_DIR)/env.sh: $(BUILD_DEPS) platform/android/scripts/ndk.sh + @mkdir -p $(MBGL_ANDROID_BUILD_DIR) + platform/android/scripts/ndk.sh $1 $2 $3 > $(MBGL_ANDROID_BUILD_DIR)/env.sh.tmp && \ + mv $(MBGL_ANDROID_BUILD_DIR)/env.sh.tmp $(MBGL_ANDROID_BUILD_DIR)/env.sh + +$(MBGL_ANDROID_BUILD_DIR)/build.ninja: $(MBGL_ANDROID_BUILD_DIR)/env.sh platform/android/config.cmake + # Invoke CMake twice to fix issues from double inclusion of toolchain.cmake on the first run. + . $(MBGL_ANDROID_BUILD_DIR)/env.sh && \ + ([ -f $(MBGL_ANDROID_BUILD_DIR)/build.ninja ] || $$$${CMAKE} \ + -H. \ + -B"$(MBGL_ANDROID_BUILD_DIR)" \ + -G"$$$${CMAKE_GENERATOR}" \ + $$$${CMAKE_ARGS} \ + -DCMAKE_BUILD_TYPE=$(BUILDTYPE) \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ + -DMBGL_PLATFORM=android \ + -DMASON_PLATFORM=android \ + -DMASON_PLATFORM_VERSION=$1-$3) && \ + $$$${CMAKE} \ + -H. \ + -B"$(MBGL_ANDROID_BUILD_DIR)" .PHONY: android-test-lib-$1 -android-test-lib-$1: build/android-$1/$(BUILDTYPE)/build.ninja - $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C build/android-$1/$(BUILDTYPE) mbgl-test +android-test-lib-$1: $(MBGL_ANDROID_BUILD_DIR)/build.ninja + . $(MBGL_ANDROID_BUILD_DIR)/env.sh && $$$${CMAKE} --build $(MBGL_ANDROID_BUILD_DIR) -- $(NINJA_ARGS) -j$(JOBS) mbgl-test .PHONY: android-lib-$1 -android-lib-$1: build/android-$1/$(BUILDTYPE)/build.ninja - $(NINJA) $(NINJA_ARGS) -j$(JOBS) -C build/android-$1/$(BUILDTYPE) mapbox-gl example-custom-layer +android-lib-$1: $(MBGL_ANDROID_BUILD_DIR)/build.ninja + . $(MBGL_ANDROID_BUILD_DIR)/env.sh && $$$${CMAKE} --build $(MBGL_ANDROID_BUILD_DIR) -- $(NINJA_ARGS) -j$(JOBS) mapbox-gl example-custom-layer .PHONY: android-$1 android-$1: android-lib-$1 @@ -551,8 +571,8 @@ run-android-core-test-$1-%: android-core-test-$1 # Push all needed files to the device adb push $(MBGL_ANDROID_CORE_TEST_DIR)/test.jar $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1 adb push test/fixtures $(MBGL_ANDROID_LOCAL_WORK_DIR)/test > /dev/null 2>&1 - adb push build/android-$1/$(BUILDTYPE)/stripped/libmapbox-gl.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1 - adb push build/android-$1/$(BUILDTYPE)/stripped/libmbgl-test.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1 + adb push $(MBGL_ANDROID_BUILD_DIR)/stripped/libmapbox-gl.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1 + adb push $(MBGL_ANDROID_BUILD_DIR)/stripped/libmbgl-test.so $(MBGL_ANDROID_LOCAL_WORK_DIR) > /dev/null 2>&1 # Kick off the tests adb shell "export LD_LIBRARY_PATH=/system/$(MBGL_ANDROID_LIBDIR):$(MBGL_ANDROID_LOCAL_WORK_DIR) && cd $(MBGL_ANDROID_LOCAL_WORK_DIR) && $(MBGL_ANDROID_DALVIKVM) -cp $(MBGL_ANDROID_LOCAL_WORK_DIR)/test.jar Main --gtest_filter=$$*" @@ -574,22 +594,18 @@ run-android-$1: android-$1 apackage: android-lib-$1 endef -$(foreach abi,$(MBGL_ANDROID_ABIS),$(eval $(call ANDROID_RULES,$(abi)))) +# Explodes the arguments into individual variables +define ANDROID_RULES_INVOKER +$(call ANDROID_RULES,$(word 1,$1),$(word 2,$1),$(word 3,$1)) +endef -# Backwards compatibility -%-arm-v5: %-arm-v5-9 ; -%-arm-v7: %-arm-v7-9 ; -%-arm-v8: %-arm-v8-21 ; -%-mips: %-mips-9 ; -%-mips-64: %-mips-64-21 ; -%-x86: %-x86-9 ; -%-x86-64: %-x86-64-21 ; +$(foreach abi,$(MBGL_ANDROID_ABIS),$(eval $(call ANDROID_RULES_INVOKER,$(subst ;, ,$(abi))))) .PHONY: android -android: android-arm-v7-9 +android: android-arm-v7 .PHONY: run-android -run-android: run-android-arm-v7-9 +run-android: run-android-arm-v7 .PHONY: run-android-unit-test run-android-unit-test: diff --git a/platform/android/bitrise.yml b/platform/android/bitrise.yml index 8599a9359d..aadcba79be 100644 --- a/platform/android/bitrise.yml +++ b/platform/android/bitrise.yml @@ -27,14 +27,6 @@ workflows: else envman add --key SKIPCI --value false fi - - script: - title: Configure GL-native build environement - run_if: '{{enveq "SKIPCI" "false"}}' - inputs: - - content: |- - #!/bin/bash - set -eu -o pipefail - sudo apt-get install -y pkg-config cmake - script: title: Run Checkstyle run_if: '{{enveq "SKIPCI" "false"}}' @@ -164,13 +156,6 @@ workflows: - icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png scheduled: steps: - - script: - title: Configure GL-native build environement - inputs: - - content: |- - #!/bin/bash - set -eu -o pipefail - sudo apt-get install -y pkg-config cmake - script: title: Configure AWS-CLI inputs: @@ -220,13 +205,6 @@ workflows: - icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png devicefarmUpload: steps: - - script: - title: Configure GL-native build environement - inputs: - - content: |- - #!/bin/bash - set -eu -o pipefail - sudo apt-get install -y pkg-config cmake - script: title: Build release inputs: @@ -269,13 +247,6 @@ workflows: - icon_url_on_error: https://bitrise-public-content-production.s3.amazonaws.com/slack/bitrise-slack-error-icon-128.png nightly-release: steps: - - script: - title: Configure GL-native build environement - inputs: - - content: |- - #!/bin/bash - set -eu -o pipefail - sudo apt-get install -y pkg-config cmake - script: title: Configure AWS-CLI inputs: diff --git a/platform/android/config.cmake b/platform/android/config.cmake index bda2c27e78..27f538b95e 100644 --- a/platform/android/config.cmake +++ b/platform/android/config.cmake @@ -27,6 +27,10 @@ set(ANDROID_JNI_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/jniLibs/${ANDROID set(ANDROID_ASSETS_TARGET_DIR ${ANDROID_SDK_PROJECT_DIR}/src/main/assets) set(ANDROID_TEST_APP_JNI_TARGET_DIR ${CMAKE_SOURCE_DIR}/platform/android/MapboxGLAndroidSDKTestApp/src/main/jniLibs/${ANDROID_ABI}) +if (NOT DEFINED ANDROID_TOOLCHAIN_PREFIX) + set(ANDROID_TOOLCHAIN_PREFIX "${MASON_XC_ROOT}/bin/${ANDROID_TOOLCHAIN}-") +endif() + ## mbgl core ## macro(mbgl_platform_core) @@ -205,7 +209,7 @@ target_link_libraries(mapbox-gl # Create a stripped version of the library and copy it to the JNIDIR. add_custom_command(TARGET mapbox-gl POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_JNI_TARGET_DIR} - COMMAND ${STRIP_COMMAND} $ -o ${ANDROID_JNI_TARGET_DIR}/$) + COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $ -o ${ANDROID_JNI_TARGET_DIR}/$) ## Test library ## @@ -266,8 +270,8 @@ target_add_mason_package(mbgl-test PRIVATE geojsonvt) add_custom_command(TARGET mbgl-test POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/stripped - COMMAND ${STRIP_COMMAND} $ -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$ - COMMAND ${STRIP_COMMAND} $ -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$) + COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $ -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$ + COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $ -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$) ## Custom layer example ## @@ -289,4 +293,4 @@ target_link_libraries(example-custom-layer add_custom_command(TARGET example-custom-layer POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${ANDROID_TEST_APP_JNI_TARGET_DIR} - COMMAND ${STRIP_COMMAND} $ -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}/$) + COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $ -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}/$) diff --git a/platform/android/scripts/ndk.sh b/platform/android/scripts/ndk.sh new file mode 100755 index 0000000000..96a314a3c2 --- /dev/null +++ b/platform/android/scripts/ndk.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +set -e +set -o pipefail +set -u + +# This script produces an env.sh file, which contains the paths to CMake, and the flags required to +# create a build. It first tries to use the Android NDK, but falls back to installing it via Mason. + +function error { >&2 echo -e "\033[1m\033[31m$@\033[0m"; } +function warning { >&2 echo -e "\033[1m\033[33m$@\033[0m"; } +function status { >&2 echo -e "\033[1m\033[36m$@\033[0m"; } +function info { >&2 echo -e "\033[1m\033[32m$@\033[0m"; } + +if [ "$#" -ne 3 ]; then + error "Usage: $0 " +fi + +NDK_ANDROID_VERSION=$1-$3 +ANDROID_NATIVE_API_LEVEL=$3 +ANDROID_ABI=$2 + +function mason_ndk { + local CMAKE=${CMAKE:-cmake} + MASON_XC_ROOT="`${CMAKE} -P cmake/mason.cmake PREFIX android-ndk VERSION ${NDK_ANDROID_VERSION}-r13b`" + + local TOOLCHAIN="${MASON_XC_ROOT}/toolchain.cmake" + if [ ! -f "${TOOLCHAIN}" ]; then + error "Can't find CMake toolchain file at ${TOOLCHAIN}." + exit 1 + fi + + info "Using Mason-provided Android NDK at ${MASON_XC_ROOT}" + echo CMAKE=\"${CMAKE}\" + echo CMAKE_GENERATOR=\"Ninja\" + echo CMAKE_ARGS=\" \ + -DCMAKE_MAKE_PROGRAM=`pwd`/${NINJA} \ + -DMASON_XC_ROOT=${MASON_XC_ROOT} \ + -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} \ + \" +} + +function system_ndk { + if [[ ${USE_MASON_NDK:-} ]]; then + return 1 + fi + + if [ -f platform/android/local.properties ]; then + local SDK_DIR=$(sed -n -e 's/^sdk.dir=\(.*\)$/\1/p' platform/android/local.properties) + fi + + if [ ! -d "${SDK_DIR:-}" ]; then + if [ ! -z "${ANDROID_HOME:-}" ]; then + local SDK_DIR="${ANDROID_HOME}" + else + error "Can't find the Android SDK. Set \$ANDROID_HOME to the SDK path." + exit 1 + fi + fi + + local NDK_DIR="${ANDROID_NDK_HOME:-${SDK_DIR}/ndk-bundle}" + if [ ! -d "${NDK_DIR}" ]; then + warning "Can't find the Android NDK. If it is installed, set \$ANDROID_NDK_HOME to the NDK path." + return 1 + fi + + # Try to install CMake if it's not installed yet. + mkdir -p "${SDK_DIR}/cmake" + local CMAKE_VERSION=/$(ls "${SDK_DIR}/cmake" | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | tail -n 1) + local CMAKE="${SDK_DIR}/cmake${CMAKE_VERSION:-}/bin/cmake" + if [ ! -f "${CMAKE}" ]; then + status "Trying to install CMake..." + mkdir -p "${SDK_DIR}/licenses" + echo "8933bad161af4178b1185d1a37fbf41ea5269c55" > "${SDK_DIR}/licenses/android-sdk-license" + "${SDK_DIR}/tools/bin/sdkmanager" --list | grep cmake | tail -n 1 | cut -d \| -f 1 | xargs "${SDK_DIR}/tools/bin/sdkmanager" >&2 + CMAKE_VERSION=/$(ls "${SDK_DIR}/cmake" | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n | tail -n 1) + CMAKE="${SDK_DIR}/cmake${CMAKE_VERSION:-}/bin/cmake" + if [ ! -f "${CMAKE}" ]; then + error "Can't find CMake at ${CMAKE}." + return 1 + fi + fi + + local NINJA="${SDK_DIR}/cmake${CMAKE_VERSION:-}/bin/ninja" + if [ ! -f "${NINJA}" ]; then + error "Can't find Ninja at ${NINJA}." + return 1 + fi + + local TOOLCHAIN="${NDK_DIR}/build/cmake/android.toolchain.cmake" + if [ ! -f "${TOOLCHAIN}" ]; then + error "Can't find CMake toolchain file at ${TOOLCHAIN}." + return 1 + fi + + info "Using system-provided Android NDK at ${NDK_DIR}" + echo CMAKE=\"${CMAKE}\" + echo CMAKE_GENERATOR=\"Android Gradle - Ninja\" + echo CMAKE_ARGS=\" \ + -DANDROID_ABI=${ANDROID_ABI} \ + -DANDROID_NDK=${NDK_DIR} \ + -DCMAKE_MAKE_PROGRAM=${NINJA} \ + -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} \ + -DANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} \ + -DANDROID_TOOLCHAIN=clang \ + -DANDROID_STL=c++_static \ + -DANDROID_CPP_FEATURES=rtti\;exceptions \ + \" +} + +system_ndk || mason_ndk -- cgit v1.2.1