Support more Android arch in Makefile build (#12806)

* Support more Android arch in Makefile build

* update Makefile

* fix MARCH_OPTION

* persist multiple architectures across builds

* persist multiple architectures across builds

* persist multiple architectures across builds

* persistence bug fix

* persistence bug fix

* persistence bug fix

* add -latomic to linker flags for benchmark

* Change ANDROID_OS_ARCH to ANDROID_HOST_OS_ARCH
This commit is contained in:
resec 2017-11-02 01:01:15 +08:00 committed by gunan
parent 16b0bb0952
commit 37370d98f4
3 changed files with 100 additions and 34 deletions

View File

@ -11,6 +11,8 @@
# the first for the host (the machine you're compiling on) and the second for
# the target (the machine you want the program to run on).
SHELL := /bin/bash
# Host compilation settings
# Find where we're running from, so we can store generated files here.
@ -63,6 +65,8 @@ else
endif
endif
HOST_ARCH := $(shell if [[ $(shell uname -m) =~ i[345678]86 ]]; then echo x86_32; else echo $(shell uname -m); fi)
# Where compiled objects are stored.
HOST_OBJDIR := $(MAKEFILE_DIR)/gen/host_obj/
HOST_BINDIR := $(MAKEFILE_DIR)/gen/host_bin/
@ -235,43 +239,93 @@ ifeq ($(TARGET),ANDROID)
# NDK_ROOT=/path/to/your/ndk
# You need to have an Android version of the protobuf libraries compiled to link
# in. The compile_android_protobuf.sh script may help.
# TODO(satok): Support all CPU architectures (Currently only armv7 is supported)
OS_PATH :=
ANDROID_HOST_OS_ARCH :=
ifeq ($(HOST_OS),LINUX)
OS_PATH=linux
ANDROID_HOST_OS_ARCH=linux
endif
ifeq ($(HOST_OS),OSX)
OS_PATH=darwin
ANDROID_HOST_OS_ARCH=darwin
endif
ifeq ($(HOST_OS),WINDOWS)
$(error "windows is not supported.")
endif
ifeq ($(HOST_ARCH),x86_32)
ANDROID_HOST_OS_ARCH := $(ANDROID_HOST_OS_ARCH)-x86
else
ANDROID_HOST_OS_ARCH := $(ANDROID_HOST_OS_ARCH)-$(HOST_ARCH)
endif
ifndef ANDROID_ARCH
ANDROID_ARCH := armeabi-v7a
endif
ifeq ($(ANDROID_ARCH),arm64-v8a)
TOOLCHAIN := aarch64-linux-android-4.9
SYSROOT_ARCH := arm64
BIN_PREFIX := aarch64-linux-android
MARCH_OPTION :=
endif
ifeq ($(ANDROID_ARCH),armeabi)
TOOLCHAIN := arm-linux-androideabi-4.9
SYSROOT_ARCH := arm
BIN_PREFIX := arm-linux-androideabi
MARCH_OPTION :=
endif
ifeq ($(ANDROID_ARCH),armeabi-v7a)
TOOLCHAIN := arm-linux-androideabi-4.9
SYSROOT_ARCH := arm
BIN_PREFIX := arm-linux-androideabi
MARCH_OPTION := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
endif
ifeq ($(ANDROID_ARCH),mips)
TOOLCHAIN := mipsel-linux-android-4.9
SYSROOT_ARCH := mips
BIN_PREFIX := mipsel-linux-android
MARCH_OPTION :=
endif
ifeq ($(ANDROID_ARCH),mips64)
TOOLCHAIN := mips64el-linux-android-4.9
SYSROOT_ARCH := mips64
BIN_PREFIX := mips64el-linux-android
MARCH_OPTION :=
endif
ifeq ($(ANDROID_ARCH),x86)
TOOLCHAIN := x86-4.9
SYSROOT_ARCH := x86
BIN_PREFIX := i686-linux-android
MARCH_OPTION :=
endif
ifeq ($(ANDROID_ARCH),x86_64)
TOOLCHAIN := x86_64-4.9
SYSROOT_ARCH := x86_64
BIN_PREFIX := x86-64-linux-android
MARCH_OPTION :=
endif
ifndef NDK_ROOT
$(error "NDK_ROOT is not defined.")
endif
CXX := $(CC_PREFIX) $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(OS_PATH)-x86_64/bin/arm-linux-androideabi-g++
CC := $(CC_PREFIX) $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(OS_PATH)-x86_64/bin/arm-linux-androideabi-gcc
CXX := $(CC_PREFIX) $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-g++
CC := $(CC_PREFIX) $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-gcc
CXXFLAGS +=\
--sysroot $(NDK_ROOT)/platforms/android-21/arch-arm \
--sysroot $(NDK_ROOT)/platforms/android-21/arch-$(SYSROOT_ARCH) \
-Wno-narrowing \
-fomit-frame-pointer \
-march=armv7-a \
-mfloat-abi=softfp \
-mfpu=neon \
$(MARCH_OPTION) \
-fPIE
INCLUDES = \
-I$(NDK_ROOT)/sources/android/support/include \
-I$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/include \
-I$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include \
-I$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(ANDROID_ARCH)/include \
-I. \
-I$(MAKEFILE_DIR)/downloads/ \
-I$(MAKEFILE_DIR)/downloads/eigen \
-I$(MAKEFILE_DIR)/downloads/gemmlowp \
-I$(MAKEFILE_DIR)/downloads/nsync/public \
-I$(MAKEFILE_DIR)/downloads/fft2d \
-I$(MAKEFILE_DIR)/gen/protobuf/include \
-I$(MAKEFILE_DIR)/gen/protobuf_android/$(ANDROID_ARCH)/include \
-I$(PROTOGENDIR) \
-I$(PBTGENDIR)
@ -282,19 +336,20 @@ $(TARGET_NSYNC_LIB) \
-llog \
-lz \
-lm \
-ldl
-ldl \
-latomic
LD := $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(OS_PATH)-x86_64/arm-linux-androideabi/bin/ld
LD := $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/$(BIN_PREFIX)/bin/ld
LDFLAGS := \
-march=armv7-a \
-L$(MAKEFILE_DIR)/gen/protobuf/lib \
-L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a \
$(MARCH_OPTION) \
-L$(MAKEFILE_DIR)/gen/protobuf_android/$(ANDROID_ARCH)/lib \
-L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(ANDROID_ARCH) \
-fPIE \
-pie \
-v
AR := $(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/$(OS_PATH)-x86_64/bin/arm-linux-androideabi-ar
AR := $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-ar
ARFLAGS := r
LIBFLAGS += -Wl,--allow-multiple-definition -Wl,--whole-archive
@ -318,6 +373,11 @@ $(TARGET_NSYNC_LIB) \
ifdef ENABLE_EXPERIMENTAL_HEXNN_OPS
CXXFLAGS += -DENABLE_EXPERIMENTAL_HEXNN_OPS
endif
OBJDIR := $(OBJDIR)android_$(ANDROID_ARCH)/
LIBDIR := $(LIBDIR)android_$(ANDROID_ARCH)/
BINDIR := $(BINDIR)android_$(ANDROID_ARCH)/
DEPDIR := $(DEPDIR)android_$(ANDROID_ARCH)/
endif # ANDROID
# LINT.ThenChange(//tensorflow/contrib/android/cmake/CMakeLists.txt)
@ -660,12 +720,12 @@ clean:
# Gets rid of all generated files except protobuf libs generated
# before calling make. This allows users not to recompile proto libs everytime.
clean_except_protobuf_libs:
find $(MAKEFILE_DIR)/gen -mindepth 1 -maxdepth 1 ! -name "protobuf" ! -name "protobuf-host" -exec rm -r "{}" \;
find $(MAKEFILE_DIR)/gen -mindepth 1 -maxdepth 1 ! -name "protobuf*" -exec rm -r "{}" \;
rm -rf tensorflow/core/util/version_info.cc
# Gets rid of target files only, leaving the host alone. Also leaves the lib
# directory untouched deliberately, so we can persist multiple architectures
# across builds for iOS.
# across builds for iOS and Android.
cleantarget:
rm -rf $(OBJDIR)
rm -rf $(BINDIR)

View File

@ -18,12 +18,15 @@
set -e
usage() {
echo "Usage: NDK_ROOT=<path to ndk root> $(basename "$0") [-s:t:Tx:X]"
echo "Usage: NDK_ROOT=<path to ndk root> $(basename "$0") [-Es:t:Tx:a:X]"
echo "-E enable experimental hexnn ops"
echo "-s [sub_makefiles] sub makefiles separated by white space"
echo "-t [build_target] build target for Android makefile [default=all]"
echo "-T only build tensorflow"
echo "-x [hexagon library path] copy and hexagon libraries in the specified path"
echo "-a [architecture] Architecture of target android [default=armeabi-v7a] \
(supported architecture list: \
arm64-v8a armeabi armeabi-v7a mips mips64 x86 x86_64)"
exit 1
}
@ -32,13 +35,16 @@ if [[ -z "${NDK_ROOT}" ]]; then
exit 1
fi
while getopts "Es:t:Tx:" opt_name; do
ARCH=armeabi-v7a
while getopts "Es:t:Tx:a:" opt_name; do
case "$opt_name" in
E) ENABLE_EXPERIMENTAL_HEXNN_OPS="true";;
s) SUB_MAKEFILES="${OPTARG}";;
t) BUILD_TARGET="${OPTARG}";;
T) ONLY_MAKE_TENSORFLOW="true";;
x) HEXAGON_LIB_PATH="${OPTARG}";;
a) ARCH="${OPTARG}";;
*) usage;;
esac
done
@ -53,25 +59,23 @@ JOB_COUNT="${JOB_COUNT:-$(get_job_count)}"
HEXAGON_DOWNLOAD_PATH="tensorflow/contrib/makefile/downloads/hexagon"
# Remove any old files first.
make -f tensorflow/contrib/makefile/Makefile cleantarget
if [[ "${ONLY_MAKE_TENSORFLOW}" != "true" ]]; then
# Remove any old files first.
make -f tensorflow/contrib/makefile/Makefile clean
rm -rf tensorflow/contrib/makefile/downloads
# Pull down the required versions of the frameworks we need.
tensorflow/contrib/makefile/download_dependencies.sh
# Compile protobuf for the target Android device architectures.
CC_PREFIX="${CC_PREFIX}" NDK_ROOT="${NDK_ROOT}" \
tensorflow/contrib/makefile/compile_android_protobuf.sh -c
else
# Only clean files generated by make
make -f tensorflow/contrib/makefile/Makefile clean_except_protobuf_libs
tensorflow/contrib/makefile/compile_android_protobuf.sh -c -a ${ARCH}
fi
# Compile nsync for the host and the target Android device architecture.
# Don't use export var=`something` syntax; it swallows the exit status.
HOST_NSYNC_LIB=`tensorflow/contrib/makefile/compile_nsync.sh`
TARGET_NSYNC_LIB=`CC_PREFIX="${CC_PREFIX}" NDK_ROOT="${NDK_ROOT}" \
tensorflow/contrib/makefile/compile_nsync.sh -t android -a armeabi-v7a`
tensorflow/contrib/makefile/compile_nsync.sh -t android -a ${ARCH}`
export HOST_NSYNC_LIB TARGET_NSYNC_LIB
if [[ ! -z "${HEXAGON_LIB_PATH}" ]]; then
@ -98,7 +102,8 @@ fi
if [[ -z "${BUILD_TARGET}" ]]; then
make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
TARGET=ANDROID NDK_ROOT="${NDK_ROOT}" CC_PREFIX="${CC_PREFIX}" \
TARGET=ANDROID NDK_ROOT="${NDK_ROOT}" ANDROID_ARCH="${ARCH}" \
CC_PREFIX="${CC_PREFIX}" \
HOST_NSYNC_LIB="$HOST_NSYNC_LIB" TARGET_NSYNC_LIB="$TARGET_NSYNC_LIB" \
HEXAGON_LIBS="${HEXAGON_LIBS}" HEXAGON_INCLUDE="${HEXAGON_INCLUDE}" \
SUB_MAKEFILES="${SUB_MAKEFILES}" ${EXTRA_MAKE_ARGS[@]}
@ -106,7 +111,8 @@ else
# BUILD_TARGET explicitly uncommented to allow multiple targets to be
# passed to make in a single build_all_android.sh invocation.
make -j"${JOB_COUNT}" -f tensorflow/contrib/makefile/Makefile \
TARGET=ANDROID NDK_ROOT="${NDK_ROOT}" CC_PREFIX="${CC_PREFIX}" \
TARGET=ANDROID NDK_ROOT="${NDK_ROOT}" ANDROID_ARCH="${ARCH}" \
CC_PREFIX="${CC_PREFIX}" \
HOST_NSYNC_LIB="$HOST_NSYNC_LIB" TARGET_NSYNC_LIB="$TARGET_NSYNC_LIB" \
HEXAGON_LIBS="${HEXAGON_LIBS}" HEXAGON_INCLUDE="${HEXAGON_INCLUDE}" \
SUB_MAKEFILES="${SUB_MAKEFILES}" ${EXTRA_MAKE_ARGS[@]} ${BUILD_TARGET}

View File

@ -71,10 +71,10 @@ then
exit 1
fi
GENDIR="$(pwd)/gen/protobuf"
GENDIR="$(pwd)/gen/protobuf_android"
HOST_GENDIR="$(pwd)/gen/protobuf-host"
mkdir -p "${GENDIR}"
mkdir -p "${HOST_GENDIR}"
mkdir -p "${GENDIR}/${ARCHITECTURE}"
if [[ ! -f "./downloads/protobuf/autogen.sh" ]]; then
echo "You need to download dependencies before running this script." 1>&2
@ -153,7 +153,7 @@ then
exit 1
fi
./configure --prefix="${GENDIR}" \
./configure --prefix="${GENDIR}/${ARCHITECTURE}" \
--host="${bin_prefix}" \
--with-sysroot="${SYSROOT}" \
--disable-shared \