From d830573111c34b0d789eaecfaec423da63a8ad0c Mon Sep 17 00:00:00 2001 From: Fritz Koenig Date: Fri, 6 Jan 2012 11:50:05 -0800 Subject: Add makefile for building libvpx for Android. Android.mk file for using the Android NDK build system to compile. Adds option for SDK path to use the compiler that comes with android for testing compiler compliance. Change-Id: I5fd17cb76e3ed631758d3f392e62ae1a050d0d10 --- README | 2 + build/make/Android.mk | 193 ++++++++++++++++++++++++++++++++++++++++++++++ build/make/configure.sh | 53 +++++++++++-- configure | 3 + vpx_ports/arm_cpudetect.c | 30 ++++++- 5 files changed, 275 insertions(+), 6 deletions(-) create mode 100644 build/make/Android.mk diff --git a/README b/README index d5ef59823..0dfb0fe18 100644 --- a/README +++ b/README @@ -42,11 +42,13 @@ COMPILING THE APPLICATIONS/LIBRARIES: --help output of the configure script. As of this writing, the list of available targets is: + armv5te-android-gcc armv5te-linux-rvct armv5te-linux-gcc armv6-darwin-gcc armv6-linux-rvct armv6-linux-gcc + armv7-android-gcc armv7-linux-rvct armv7-linux-gcc mips32-linux-gcc diff --git a/build/make/Android.mk b/build/make/Android.mk new file mode 100644 index 000000000..9dbbac9b7 --- /dev/null +++ b/build/make/Android.mk @@ -0,0 +1,193 @@ +## +## Copyright (c) 2012 The WebM project authors. All Rights Reserved. +## +## Use of this source code is governed by a BSD-style license +## that can be found in the LICENSE file in the root of the source +## tree. An additional intellectual property rights grant can be found +## in the file PATENTS. All contributing project authors may +## be found in the AUTHORS file in the root of the source tree. +## + +# +# This file is to be used for compiling libvpx for Android using the NDK. +# In an Android project place a libvpx checkout in the jni directory. +# Run the configure script from the jni directory. Base libvpx +# encoder/decoder configuration will look similar to: +# ./libvpx/configure --target=armv7-android-gcc --disable-examples \ +# --sdk-path=/opt/android-ndk-r6b/ +# +# When targeting Android, realtime-only is enabled by default. This can +# be overridden by adding the command line flag: +# --disable-realtime-only +# +# This will create .mk files that contain variables that contain the +# source files to compile. +# +# Place an Android.mk file in the jni directory that references the +# Android.mk file in the libvpx directory: +# LOCAL_PATH := $(call my-dir) +# include $(CLEAR_VARS) +# include libvpx/build/make/Android.mk +# +# There are currently two TARGET_ARCH_ABI targets for ARM. +# armeabi and armeabi-v7a. armeabi-v7a is selected by creating an +# Application.mk in the jni directory that contains: +# APP_ABI := armeabi-v7a +# +# To change to building armeabi, run ./libvpx/configure again, but with +# --target=arm5te-android-gcc and and modify the Application.mk file to +# set APP_ABI := armeabi +# +# Running ndk-build will build libvpx and include it in your project. +# + +CONFIG_DIR := $(LOCAL_PATH) +LIBVPX_PATH := $(LOCAL_PATH)/libvpx +ASM_CNV_PATH_LOCAL := $(TARGET_ARCH_ABI)/ads2gas +ASM_CNV_PATH := $(LOCAL_PATH)/$(ASM_CNV_PATH_LOCAL) + +# Makefiles created by the libvpx configure process +# This will need to be fixed to handle x86. +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + include $(CONFIG_DIR)/libs-armv7-android-gcc.mk +else + include $(CONFIG_DIR)/libs-armv5te-android-gcc.mk +endif + +# Rule that is normally in Makefile created by libvpx +# configure. Used to filter out source files based on configuration. +enabled=$(filter-out $($(1)-no),$($(1)-yes)) + +# Override the relative path that is defined by the libvpx +# configure process +SRC_PATH_BARE := $(LIBVPX_PATH) + +# Include the list of files to be built +include $(LIBVPX_PATH)/libs.mk + +# Want arm, not thumb, optimized +LOCAL_ARM_MODE := arm +LOCAL_CFLAGS := -O3 + +# ----------------------------------------------------------------------------- +# Template : asm_offsets_template +# Arguments : 1: assembly offsets file to be created +# 2: c file to base assembly offsets on +# Returns : None +# Usage : $(eval $(call asm_offsets_template,, +# Rationale : Create offsets at compile time using for structures that are +# defined in c, but used in assembly functions. +# ----------------------------------------------------------------------------- +define asm_offsets_template + +_SRC:=$(2) +_OBJ:=$(ASM_CNV_PATH)/$$(notdir $(2)).S + +_FLAGS = $$($$(my)CFLAGS) \ + $$(call get-src-file-target-cflags,$(2)) \ + $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(CONFIG_DIR)) \ + $$(LOCAL_CFLAGS) \ + $$(NDK_APP_CFLAGS) \ + $$(call host-c-includes,$$($(my)C_INCLUDES)) \ + -DINLINE_ASM \ + -S \ + +_TEXT = "Compile $$(call get-src-file-text,$(2))" +_CC = $$(TARGET_CC) + +$$(eval $$(call ev-build-file)) + +$(1) : $$(_OBJ) $(2) + @mkdir -p $$(dir $$@) + @grep -w EQU $$< | tr -d '\#' | $(CONFIG_DIR)/$(ASM_CONVERSION) > $$@ +endef + +# Use ads2gas script to convert from RVCT format to GAS format. This passes +# puts the processed file under $(ASM_CNV_PATH). Local clean rule +# to handle removing these +ASM_CNV_OFFSETS_DEPEND = $(ASM_CNV_PATH)/asm_com_offsets.asm +ifeq ($(CONFIG_VP8_DECODER), yes) + ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/asm_dec_offsets.asm +endif +ifeq ($(CONFIG_VP8_ENCODER), yes) + ASM_CNV_OFFSETS_DEPEND += $(ASM_CNV_PATH)/asm_enc_offsets.asm +endif + +.PRECIOUS: %.asm.s +$(ASM_CNV_PATH)/libvpx/%.asm.s: $(LIBVPX_PATH)/%.asm $(ASM_CNV_OFFSETS_DEPEND) + @mkdir -p $(dir $@) + @$(CONFIG_DIR)/$(ASM_CONVERSION) <$< > $@ + + +LOCAL_SRC_FILES += vpx_config.c + +# Remove duplicate entries +CODEC_SRCS_UNIQUE = $(sort $(CODEC_SRCS)) + +# Pull out C files. vpx_config.c is in the immediate directory and +# so it does not need libvpx/ prefixed like the rest of the source files. +CODEC_SRCS_C = $(filter %.c, $(CODEC_SRCS_UNIQUE)) +LOCAL_CODEC_SRCS_C = $(filter-out vpx_config.c, $(CODEC_SRCS_C)) + +LOCAL_SRC_FILES += $(foreach file, $(LOCAL_CODEC_SRCS_C), libvpx/$(file)) + +# Pull out assembly files, splitting NEON from the rest. This is +# done to specify that the NEON assembly files use NEON assembler flags. +CODEC_SRCS_ASM_ALL = $(filter %.asm.s, $(CODEC_SRCS_UNIQUE)) +CODEC_SRCS_ASM = $(foreach v, \ + $(CODEC_SRCS_ASM_ALL), \ + $(if $(findstring neon,$(v)),,$(v))) +CODEC_SRCS_ASM_ADS2GAS = $(patsubst %.s, \ + $(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \ + $(CODEC_SRCS_ASM)) +LOCAL_SRC_FILES += $(CODEC_SRCS_ASM_ADS2GAS) + +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + CODEC_SRCS_ASM_NEON = $(foreach v, \ + $(CODEC_SRCS_ASM_ALL),\ + $(if $(findstring neon,$(v)),$(v),)) + CODEC_SRCS_ASM_NEON_ADS2GAS = $(patsubst %.s, \ + $(ASM_CNV_PATH_LOCAL)/libvpx/%.s, \ + $(CODEC_SRCS_ASM_NEON)) + LOCAL_SRC_FILES += $(patsubst %.s, \ + %.s.neon, \ + $(CODEC_SRCS_ASM_NEON_ADS2GAS)) +endif + +LOCAL_CFLAGS += \ + -DHAVE_CONFIG_H=vpx_config.h \ + -I$(LIBVPX_PATH) \ + -I$(ASM_CNV_PATH) + +LOCAL_MODULE := libvpx + +LOCAL_LDLIBS := -llog + +LOCAL_STATIC_LIBRARIES := cpufeatures + +.PHONY: clean +clean: + @echo "Clean: ads2gas files [$(TARGET_ARCH_ABI)]" + @$(RM) $(CODEC_SRCS_ASM_ADS2GAS) $(CODEC_SRCS_ASM_NEON_ADS2GAS) + @$(RM) $(patsubst %.asm, %.*, $(ASM_CNV_OFFSETS_DEPEND)) + @$(RM) -r $(ASM_CNV_PATH) + +include $(BUILD_SHARED_LIBRARY) + +$(eval $(call asm_offsets_template,\ + $(ASM_CNV_PATH)/asm_com_offsets.asm, \ + $(LIBVPX_PATH)/vp8/common/asm_com_offsets.c)) + +ifeq ($(CONFIG_VP8_DECODER), yes) + $(eval $(call asm_offsets_template,\ + $(ASM_CNV_PATH)/asm_dec_offsets.asm, \ + $(LIBVPX_PATH)/vp8/decoder/asm_dec_offsets.c)) +endif + +ifeq ($(CONFIG_VP8_ENCODER), yes) + $(eval $(call asm_offsets_template,\ + $(ASM_CNV_PATH)/asm_enc_offsets.asm, \ + $(LIBVPX_PATH)/vp8/encoder/asm_enc_offsets.c)) +endif + +$(call import-module,cpufeatures) diff --git a/build/make/configure.sh b/build/make/configure.sh index 6039a5066..cbf000b70 100755 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -477,7 +477,11 @@ process_common_cmdline() { --libdir=*) libdir="${optval}" ;; - --libc|--as|--prefix|--libdir) + --sdk-path=*) + [ -d "${optval}" ] || die "Not a directory: ${optval}" + sdk_path="${optval}" + ;; + --libc|--as|--prefix|--libdir|--sdk-path) die "Option ${opt} requires argument" ;; --help|-h) show_help @@ -728,8 +732,45 @@ process_common_toolchain() { disable multithread disable os_support ;; + + android*) + SDK_PATH=${sdk_path} + COMPILER_LOCATION=`find "${SDK_PATH}" \ + -name "arm-linux-androideabi-gcc*" -print -quit` + TOOLCHAIN_PATH=${COMPILER_LOCATION%/*}/arm-linux-androideabi- + CC=${TOOLCHAIN_PATH}gcc + AR=${TOOLCHAIN_PATH}ar + LD=${TOOLCHAIN_PATH}gcc + AS=${TOOLCHAIN_PATH}as + STRIP=${TOOLCHAIN_PATH}strip + NM=${TOOLCHAIN_PATH}nm + + if [ -z "${alt_libc}" ]; then + alt_libc=`find "${SDK_PATH}" -name arch-arm -print | \ + awk '{n = split($0,a,"/"); \ + split(a[n-1],b,"-"); \ + print $0 " " b[2]}' | \ + sort -g -k 2 | \ + awk '{ print $1 }' | tail -1` + fi + + add_cflags "--sysroot=${alt_libc}" + add_ldflags "--sysroot=${alt_libc}" + + enable pic + soft_enable realtime_only + if enabled armv7 + then + enable runtime_cpu_detect + fi + ;; + darwin*) - SDK_PATH=/Developer/Platforms/iPhoneOS.platform/Developer + if [ -z "${sdk_path}" ]; then + SDK_PATH=/Developer/Platforms/iPhoneOS.platform/Developer + else + SDK_PATH=${sdk_path} + fi TOOLCHAIN_PATH=${SDK_PATH}/usr/bin CC=${TOOLCHAIN_PATH}/gcc AR=${TOOLCHAIN_PATH}/ar @@ -747,10 +788,11 @@ process_common_toolchain() { add_cflags -arch ${tgt_isa} add_ldflags -arch_only ${tgt_isa} - add_cflags "-isysroot ${SDK_PATH}/SDKs/iPhoneOS5.0.sdk" + if [ -z "${alt_libc}" ]; then + alt_libc=${SDK_PATH}/SDKs/iPhoneOS5.0.sdk + fi - # This should be overridable - alt_libc=${SDK_PATH}/SDKs/iPhoneOS5.0.sdk + add_cflags "-isysroot ${alt_libc}" # Add the paths for the alternate libc for d in usr/include; do @@ -976,6 +1018,7 @@ EOF if enabled multithread; then case ${toolchain} in *-win*);; + *-android-gcc);; *) check_header pthread.h && add_extralibs -lpthread esac fi diff --git a/configure b/configure index 68708907b..6195b2d9f 100755 --- a/configure +++ b/configure @@ -25,6 +25,7 @@ Advanced options: ${toggle_unit_tests} build unit tests --libc=PATH path to alternate libc --as={yasm|nasm|auto} use specified assembler [auto, yasm preferred] + --sdk-path=PATH path to root of sdk (iOS, android builds only) ${toggle_fast_unaligned} don't use unaligned accesses, even when supported by hardware [auto] ${toggle_codec_srcs} in/exclude codec library source code @@ -80,6 +81,7 @@ EOF # all_platforms is a list of all supported target platforms. Maintain # alphabetically by architecture, generic-gnu last. +all_platforms="${all_platforms} armv5te-android-gcc" all_platforms="${all_platforms} armv5te-linux-rvct" all_platforms="${all_platforms} armv5te-linux-gcc" all_platforms="${all_platforms} armv5te-none-rvct" @@ -87,6 +89,7 @@ all_platforms="${all_platforms} armv6-darwin-gcc" all_platforms="${all_platforms} armv6-linux-rvct" all_platforms="${all_platforms} armv6-linux-gcc" all_platforms="${all_platforms} armv6-none-rvct" +all_platforms="${all_platforms} armv7-android-gcc" #neon Cortex-A8 all_platforms="${all_platforms} armv7-darwin-gcc" #neon Cortex-A8 all_platforms="${all_platforms} armv7-linux-rvct" #neon Cortex-A8 all_platforms="${all_platforms} armv7-linux-gcc" #neon Cortex-A8 diff --git a/vpx_ports/arm_cpudetect.c b/vpx_ports/arm_cpudetect.c index 4109924cf..08496e4d0 100644 --- a/vpx_ports/arm_cpudetect.c +++ b/vpx_ports/arm_cpudetect.c @@ -100,6 +100,34 @@ int arm_cpu_caps(void) } #elif defined(__linux__) +#if defined(__ANDROID__) +#include + +int arm_cpu_caps(void) +{ + int flags; + int mask; + uint64_t features; + if (!arm_cpu_env_flags(&flags)) + { + return flags; + } + mask = arm_cpu_env_mask(); + features = android_getCpuFeatures(); + +#if defined(HAVE_ARMV5TE) + flags |= HAS_EDSP; +#endif +#if defined(HAVE_ARMV6) + flags |= HAS_MEDIA; +#endif +#if defined(HAVE_ARMV7) + if (features & ANDROID_CPU_ARM_FEATURE_NEON) + flags |= HAS_NEON; +#endif + return flags & mask; +} +#else // !defined(__ANDROID__) #include int arm_cpu_caps(void) @@ -160,7 +188,7 @@ int arm_cpu_caps(void) } return flags & mask; } - +#endif // defined(__linux__) #elif !CONFIG_RUNTIME_CPU_DETECT int arm_cpu_caps(void) -- cgit v1.2.3