Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[build] use system-provided Android NDK when available
Browse files Browse the repository at this point in the history
and fall back to Mason if it isn't
  • Loading branch information
kkaefer committed Feb 22, 2017
1 parent 586ae94 commit 341e65f
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 68 deletions.
86 changes: 51 additions & 35 deletions Makefile
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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=$$*"
Expand All @@ -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:
Expand Down
29 changes: 0 additions & 29 deletions platform/android/bitrise.yml
Expand Up @@ -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"}}'
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
12 changes: 8 additions & 4 deletions platform/android/config.cmake
Expand Up @@ -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)
Expand Down Expand Up @@ -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} $<TARGET_FILE:mapbox-gl> -o ${ANDROID_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:mapbox-gl>)
COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $<TARGET_FILE:mapbox-gl> -o ${ANDROID_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:mapbox-gl>)

## Test library ##

Expand Down Expand Up @@ -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} $<TARGET_FILE:mapbox-gl> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mapbox-gl>
COMMAND ${STRIP_COMMAND} $<TARGET_FILE:mbgl-test> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mbgl-test>)
COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $<TARGET_FILE:mapbox-gl> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mapbox-gl>
COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $<TARGET_FILE:mbgl-test> -o ${CMAKE_CURRENT_BINARY_DIR}/stripped/$<TARGET_FILE_NAME:mbgl-test>)

## Custom layer example ##

Expand All @@ -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} $<TARGET_FILE:example-custom-layer> -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:example-custom-layer>)
COMMAND ${ANDROID_TOOLCHAIN_PREFIX}strip $<TARGET_FILE:example-custom-layer> -o ${ANDROID_TEST_APP_JNI_TARGET_DIR}/$<TARGET_FILE_NAME:example-custom-layer>)
111 changes: 111 additions & 0 deletions 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 <short arch> <long arch> <api level>"
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

0 comments on commit 341e65f

Please sign in to comment.