From ff1ac8ab5a62505adb10a12442a8018248a03dad Mon Sep 17 00:00:00 2001 From: Alex Ames Date: Mon, 26 Jan 2015 14:51:01 -0800 Subject: [PATCH] Added new Android build target and makefile utils. Previously Android.mk only had a rule for the Flatbuffers test. There is now an empty module definition so that flatbuffers can be included as an Android module in other projects. Additionally, android/jni/include.mk has been added which contains some utility functions that can be used by projects using Flatbuffers to generate header build rules and set up dependencies. A sample project has been added to the samples directory to demonstrate how to use flatbuffers with Android. Tested by compiling Android project on Linux. Change-Id: I25d6da40f6531777b22f7371187e0a2f4e903ad4 --- android/build_apk.sh | 18 ++- android/jni/Android.mk | 25 ++-- android/jni/include.mk | 172 +++++++++++++++++++++++++ samples/android/jni/Android.mk | 56 ++++++++ samples/android/jni/Application.mk | 22 ++++ samples/android/jni/main.cpp | 28 ++++ samples/android/jni/schemas/animal.fbs | 22 ++++ 7 files changed, 333 insertions(+), 10 deletions(-) create mode 100644 android/jni/include.mk create mode 100755 samples/android/jni/Android.mk create mode 100755 samples/android/jni/Application.mk create mode 100644 samples/android/jni/main.cpp create mode 100644 samples/android/jni/schemas/animal.fbs diff --git a/android/build_apk.sh b/android/build_apk.sh index 3520626dd..94a7275fa 100755 --- a/android/build_apk.sh +++ b/android/build_apk.sh @@ -235,8 +235,18 @@ select_android_build_target() { local android_build_target= for android_target in $(echo "${android_targets_installed}" | \ awk -F- '{ print $2 }' | sort -n); do - if [[ $((android_target)) -ge \ + local isNumber='^[0-9]+$' + # skip preview API releases e.g. 'android-L' + if [[ $android_target =~ $isNumber ]]; then + if [[ $((android_target)) -ge \ $((BUILDAPK_ANDROID_TARGET_MINVERSION)) ]]; then + android_build_target="android-${android_target}" + break + fi + else + # The API version is a letter + # Letters are sorted to the end by 'sort -n' + # so we're out of numbered platforms. Use this one. android_build_target="android-${android_target}" break fi @@ -415,14 +425,18 @@ main() { local build_package=1 for opt; do case ${opt} in + # NDK_DEBUG=0 tells ndk-build to build this as debuggable but to not + # modify the underlying code whereas NDK_DEBUG=1 also builds as debuggable + # but does modify the code NDK_DEBUG=1) ant_target=debug ;; + NDK_DEBUG=0) ant_target=debug ;; ADB_DEVICE*) adb_device="$(\ echo "${opt}" | sed -E 's/^ADB_DEVICE=([^ ]+)$/-s \1/;t;s/.*//')" ;; BUILD=0) disable_build=1 ;; DEPLOY=0) disable_deploy=1 ;; RUN_DEBUGGER=1) run_debugger=1 ;; LAUNCH=0) launch=0 ;; - clean) build_package=0 ;; + clean) build_package=0 disable_deploy=1 launch=0 ;; -h|--help|help) usage ;; esac done diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 47f2a87bb..01e1141c6 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -16,16 +16,25 @@ LOCAL_PATH := $(call my-dir) +# Empty static library so that other projects can include FlatBuffers as a +# module. include $(CLEAR_VARS) +LOCAL_MODULE := flatbuffers +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include +LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix +include $(BUILD_STATIC_LIBRARY) -LOCAL_MODULE := FlatBufferTest -LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include -LOCAL_SRC_FILES := main.cpp ../../tests/test.cpp ../../src/idl_parser.cpp ../../src/idl_gen_text.cpp ../../src/idl_gen_fbs.cpp -LOCAL_LDLIBS := -llog -landroid -LOCAL_STATIC_LIBRARIES := android_native_app_glue -LOCAL_ARM_MODE:=arm -LOCAL_CPPFLAGS += -std=c++11 -fexceptions -Wall -Wno-literal-suffix - +# FlatBuffers test +include $(CLEAR_VARS) +LOCAL_MODULE := FlatBufferTest +LOCAL_SRC_FILES := main.cpp \ + ../../tests/test.cpp \ + ../../src/idl_parser.cpp \ + ../../src/idl_gen_text.cpp \ + ../../src/idl_gen_fbs.cpp +LOCAL_LDLIBS := -llog -landroid +LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers +LOCAL_ARM_MODE := arm include $(BUILD_SHARED_LIBRARY) $(call import-module,android/native_app_glue) diff --git a/android/jni/include.mk b/android/jni/include.mk new file mode 100644 index 000000000..d1a373cfa --- /dev/null +++ b/android/jni/include.mk @@ -0,0 +1,172 @@ +# Copyright 2014 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file contains utility functions for Android projects using Flatbuffers. +# To use this file, include it in your project's Android.mk by calling near the +# top of your android makefile like so: +# +# include $(FLATBUFFERS_DIR)/android/jni/include.mk +# +# You will also need to import the flatbuffers module using the standard +# import-module function. +# +# The main functionality this file provides are the following functions: +# flatbuffers_fbs_to_h: Converts flatbuffer schema paths to header paths. +# flatbuffers_header_build_rule: +# Creates a build rule for a schema's generated header. This build rule +# has a dependency on the flatc compiler which will be built if necessary. +# flatbuffers_header_build_rules: +# Creates build rules for generated headers for each schema listed and sets +# up depenedendies. +# +# More information and example usage can be found in the comments preceeding +# each function. + +# Targets to build the Flatbuffers compiler as well as some utility definitions +ifeq (,$(FLATBUFFERS_INCLUDE_MK_)) +FLATBUFFERS_INCLUDE_MK_ := 1 + +PROJECT_OS := $(OS) +ifeq (,$(OS)) +PROJECT_OS := $(shell uname -s) +else +ifneq ($(findstring Windows,$(PROJECT_OS)),) +PROJECT_OS := Windows +endif +endif + +# The following block generates build rules which result in headers being +# rebuilt from flatbuffers schemas. + +# Directory that contains the FlatBuffers compiler. +FLATBUFFERS_FLATC_PATH?=$(CURDIR)/bin +ifeq (Windows,$(PROJECT_OS)) +FLATBUFFERS_FLATC := $(FLATBUFFERS_FLATC_PATH)/Debug/flatc.exe +endif +ifeq (Linux,$(PROJECT_OS)) +FLATBUFFERS_FLATC := $(FLATBUFFERS_FLATC_PATH)/flatc +endif +ifeq (Darwin,$(PROJECT_OS)) +FLATBUFFERS_FLATC := $(FLATBUFFERS_FLATC_PATH)/Debug/flatc +endif + +# Search for cmake. +CMAKE_ROOT := $(realpath $(LOCAL_PATH)/../../../../../../prebuilts/cmake) +ifeq (,$(CMAKE)) +ifeq (Linux,$(PROJECT_OS)) +CMAKE := $(wildcard $(CMAKE_ROOT)/linux-x86/current/bin/cmake*) +endif +ifeq (Darwin,$(PROJECT_OS)) +CMAKE := \ + $(wildcard $(CMAKE_ROOT)/darwin-x86_64/current/*.app/Contents/bin/cmake) +endif +ifeq (Windows,$(PROJECT_OS)) +CMAKE := $(wildcard $(CMAKE_ROOT)/windows/current/bin/cmake*) +endif +endif +ifeq (,$(CMAKE)) +CMAKE := cmake +endif + +# Generate a host build rule for the flatbuffers compiler. +FLATBUFFERS_CMAKELISTS_DIR := \ + $(realpath $(dir $(lastword $(MAKEFILE_LIST)))/../..) +ifeq (Windows,$(PROJECT_OS)) +define build_flatc_recipe + cd & jni\build_flatc.bat $(CMAKE) +endef +endif +ifeq (Linux,$(PROJECT_OS)) +define build_flatc_recipe + mkdir -p bin && cd bin && $(CMAKE) $(FLATBUFFERS_CMAKELISTS_DIR) \ + && $(MAKE) flatc +endef +endif +ifeq (Darwin,$(PROJECT_OS)) +define build_flatc_recipe + cd $(FLATBUFFERS_CMAKELISTS_DIR) && "$(CMAKE)" -GXcode . && \ + xcodebuild -target flatc +endef +endif +ifeq (,$(build_flatc_recipe)) +ifeq (,$(FLATBUFFERS_FLATC)) +$(error flatc binary not found!) +endif +endif + +# Generate a build rule for flatc. +ifeq ($(strip $(FLATBUFFERS_FLATC)),) +flatc_target := build_flatc +.PHONY: $(flatc_target) +else +flatc_target := $(FLATBUFFERS_FLATC) +endif +$(flatc_target): + $(call build_flatc_recipe) + +# $(flatbuffers_fbs_to_h schema_dir,output_dir,path) +# +# Convert the specified schema path to a Flatbuffers generated header path. +# For example: +# +# $(call flatbuffers_fbs_to_h,$(MY_PROJ_DIR)/schemas,\ +# $(MY_PROJ_DIR)/gen/include,$(MY_PROJ_DIR)/schemas/example.fbs) +# +# This will convert the file path `$(MY_PROJ_DIR)/schemas/example.fbs)` to +# `$(MY_PROJ_DIR)/gen/include/example_generated.h` +define flatbuffers_fbs_to_h +$(subst $(1),$(2),$(patsubst %.fbs,%_generated.h,$(3))) +endef + +# $(flatbuffers_header_build_rule schema_file,schema_dir,output_dir,\ +# schema_include_dirs) +# +# Generate a build rule that will convert a Flatbuffers schema to a generated +# header derived from the schema filename using flatbuffers_fbs_to_h. For +# example: +# +# $(call flatbuffers_header_build_rule,$(MY_PROJ_DIR)/schemas/example.fbs,\ +# $(MY_PROJ_DIR)/schemas,$(MY_PROJ_DIR)/gen/include) +# +# The final argument, schema_include_dirs, is optional and is only needed when +# the schema files depend on other schema files outside their own directory. +define flatbuffers_header_build_rule +$(eval \ + $(call flatbuffers_fbs_to_h,$(2),$(3),$(1)): $(1) $(flatc_target) + $(call host-echo-build-step,generic,Generate) \ + $(subst $(LOCAL_PATH)/,,$(call flatbuffers_fbs_to_h,$(2),$(3),$(1))) + $(hide) $$(FLATBUFFERS_FLATC) --gen-includes \ + $(foreach include,$(4),-I $(include)) -o $$(dir $$@) -c $$<) +endef + +# $(flatbuffers_header_build_rules schema_files,schema_dir,output_dir,\ +# schema_include_dirs,src_files)) +# +# Use this in your own Android.mk file to generate build rules that will +# generate header files for your flatbuffer schemas as well as automatically +# set your source files to be dependent on the generated headers. For example: +# +# $(call flatbuffers_header_build_rules,$(MY_PROJ_SCHEMA_FILES),\ +# $(MY_PROJ_SCHEMA_DIR),$(MY_PROJ_GENERATED_OUTPUT_DIR), +# $(MY_PROJ_SCHEMA_INCLUDE_DIRS),$(LOCAL_SRC_FILES)) +define flatbuffers_header_build_rules +$(foreach schema,$(1),\ + $(call flatbuffers_header_build_rule,$(schema),$(2),$(3),$(4)))\ +$(foreach src,$(5),\ + $(eval $(LOCAL_PATH)/$$(src): \ + $(foreach schema,$(1),$(call flatbuffers_fbs_to_h,$(2),$(3),$(schema))))) +endef + +endif # FLATBUFFERS_INCLUDE_MK_ + diff --git a/samples/android/jni/Android.mk b/samples/android/jni/Android.mk new file mode 100755 index 000000000..b9c7a1952 --- /dev/null +++ b/samples/android/jni/Android.mk @@ -0,0 +1,56 @@ +# Copyright (c) 2013 Google, Inc. +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. + +LOCAL_PATH := $(call my-dir) +FLATBUFFERS_ROOT_DIR := $(LOCAL_PATH)/../../.. + +# FlatBuffers test +include $(CLEAR_VARS) + +# Include the FlatBuffer utility function to generate header files from schemas. +include $(FLATBUFFERS_ROOT_DIR)/android/jni/include.mk + +LOCAL_MODULE := sample_android_project + +# Set up some useful variables to identify schema and output directories and +# schema files. +ANDROID_SAMPLE_GENERATED_OUTPUT_DIR := $(LOCAL_PATH)/gen/include +ANDROID_SAMPLE_SCHEMA_DIR := $(LOCAL_PATH)/schemas +ANDROID_SAMPLE_SCHEMA_FILES := $(ANDROID_SAMPLE_SCHEMA_DIR)/animal.fbs + +LOCAL_C_INCLUDES := $(ANDROID_SAMPLE_GENERATED_OUTPUT_DIR) + +$(info $(LOCAL_C_INCLUDES)) + +LOCAL_SRC_FILES := main.cpp + +LOCAL_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix +LOCAL_LDLIBS := -llog -landroid +LOCAL_ARM_MODE := arm +LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers + +ifeq (,$(ANDROID_SAMPLE_RUN_ONCE)) +ANDROID_SAMPLE_RUN_ONCE := 1 +$(call flatbuffers_header_build_rules,$(ANDROID_SAMPLE_SCHEMA_FILES),$(ANDROID_SAMPLE_SCHEMA_DIR),$(ANDROID_SAMPLE_GENERATED_OUTPUT_DIR),,$(LOCAL_SRC_FILES)) +endif + +include $(BUILD_SHARED_LIBRARY) + +# Path to Flatbuffers root directory. +$(call import-add-path,$(FLATBUFFERS_ROOT_DIR)/..) + +$(call import-module,flatbuffers/android/jni) +$(call import-module,android/native_app_glue) diff --git a/samples/android/jni/Application.mk b/samples/android/jni/Application.mk new file mode 100755 index 000000000..56952fc96 --- /dev/null +++ b/samples/android/jni/Application.mk @@ -0,0 +1,22 @@ +# Copyright (c) 2014 Google, Inc. +# +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the authors be held liable for any damages +# arising from the use of this software. +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. +APP_PLATFORM := android-10 +APP_PROJECT_PATH := $(call my-dir)/.. +APP_STL := gnustl_static + +APP_ABI := armeabi-v7a +NDK_TOOLCHAIN_VERSION := 4.8 +APP_CPPFLAGS += -std=c++11 diff --git a/samples/android/jni/main.cpp b/samples/android/jni/main.cpp new file mode 100644 index 000000000..d03655ca5 --- /dev/null +++ b/samples/android/jni/main.cpp @@ -0,0 +1,28 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "android_native_app_glue.h" +#include "animal_generated.h" +#include "flatbuffers/flatbuffers.h" + +void android_main(android_app *app) { + app_dummy(); + + flatbuffers::FlatBufferBuilder builder; + auto name = builder.CreateString("Dog"); + auto sound = builder.CreateString("Bark"); + auto animal_buffer = sample::CreateAnimal(builder, name, sound); + builder.Finish(animal_buffer); +} + diff --git a/samples/android/jni/schemas/animal.fbs b/samples/android/jni/schemas/animal.fbs new file mode 100644 index 000000000..d1bd38d55 --- /dev/null +++ b/samples/android/jni/schemas/animal.fbs @@ -0,0 +1,22 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace sample; + +table Animal { + name:string; + sound:string; +} + +root_type Animal;