[android] Add platform android and install deps
authorJihoon Lee <jhoon.it.lee@samsung.com>
Fri, 22 Oct 2021 03:37:10 +0000 (12:37 +0900)
committerJijoong Moon <jijoong.moon@samsung.com>
Tue, 26 Oct 2021 00:04:49 +0000 (09:04 +0900)
This patch add platform android and install deps according to it

**Self evaluation:**
1. Build test: [X]Passed [ ]Failed [ ]Skipped
2. Run test: [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: Jihoon Lee <jhoon.it.lee@samsung.com>
jni/Android.mk.in [new file with mode: 0644]
jni/meson.build [new file with mode: 0644]
jni/prepare_iniparser.sh
jni/prepare_ml-api.sh
jni/prepare_openblas.sh
jni/prepare_tflite.sh
meson.build
meson_options.txt

diff --git a/jni/Android.mk.in b/jni/Android.mk.in
new file mode 100644 (file)
index 0000000..0088dc2
--- /dev/null
@@ -0,0 +1,315 @@
+# ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk -j2
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+ENABLE_TFLITE_BACKBONE := 1
+ENABLE_TFLITE_INTERPRETER := 1
+ENABLE_BLAS := 1
+
+NEED_TF_LITE := 0
+
+ifeq ($(ENABLE_TFLITE_BACKBONE), 1)
+NEED_TF_LITE := 1
+else ifeq ($(ENABLE_TFLITE_INTERPRETER), 1)
+NEED_TF_LITE := 1
+endif
+
+ifndef NNTRAINER_ROOT
+NNTRAINER_ROOT := $(LOCAL_PATH)/..
+endif
+
+ifndef NDK_LIBS_OUT
+NDK_LIBS_OUT := $(NDK_PROJECT_PATH)
+endif
+
+ifndef NDK_INCLUDES_OUT
+NDK_INCLUDES_OUT := $(NDK_PROJECT_PATH)
+endif
+
+include $(CLEAR_VARS)
+
+ifndef INIPARSER_ROOT
+ifneq ($(MAKECMDGOALS),clean)
+$(warning INIPARSER_ROOT is not defined!)
+$(warning INIPARSER SRC is going to be downloaded!)
+
+INIPARSER_ROOT :=$(NDK_LIBS_OUT)/iniparser
+
+$(info $(shell ($(LOCAL_PATH)/prepare_iniparser.sh $(NDK_LIBS_OUT))))
+
+endif #MAKECMDGOALS
+endif #INIPARSER_ROOT
+
+include $(CLEAR_VARS)
+
+NNTRAINER_JNI_ROOT := $(NNTRAINER_ROOT)/jni
+
+# Build tflite if its backbone is enabled
+ifeq ($(NEED_TF_LITE),1)
+$(warning BUILDING TFLITE BACKBONE !)
+TENSORFLOW_VERSION := 2.3.0
+
+ifndef TENSORFLOW_ROOT
+ifneq ($(MAKECMDGOALS),clean)
+$(warning TENSORFLOW_ROOT is not defined!)
+$(warning TENSORFLOW SRC is going to be downloaded!)
+
+TENSORFLOW_ROOT := $(NDK_LIBS_OUT)/tensorflow-$(TENSORFLOW_VERSION)/tensorflow-lite
+
+$(info $(shell ($(NNTRAINER_JNI_ROOT)/prepare_tflite.sh $(TENSORFLOW_VERSION) $(NDK_LIBS_OUT))))
+
+$(info $(shell (flatc -c $(NNTRAINER_ROOT)/nntrainer/compiler/tf_schema.fbs)))
+$(info $(shell (mv tf_schema_generated.h $(NNTRAINER_ROOT)/nntrainer/compiler)))
+
+endif #MAKECMDGOALS
+endif #TENSORFLOW_ROOT
+
+LOCAL_MODULE := tensorflow-lite
+LIB_ := arm64
+
+ifeq ($(APP_ABI), armeabi-v7a)
+       LIB_ := armv7
+endif
+LOCAL_SRC_FILES := $(TENSORFLOW_ROOT)/lib/$(LIB_)/libtensorflow-lite.a
+LOCAL_EXPORT_C_INCLUDES := $(TENSORFLOW_ROOT)/include
+LOCAL_EXPORT_LDLIBS := -lEGL -lGLESv2
+
+include $(PREBUILT_STATIC_LIBRARY)
+
+endif #NEED_TF_LITE
+
+ifeq ($(ENABLE_BLAS), 1)
+include $(CLEAR_VARS)
+
+## prepare openblas if nothing present
+ifndef OPENBLAS_ROOT
+ifneq ($(MAKECMDGOALS),clean)
+
+OPENBLAS_ROOT := $(NDK_LIBS_OUT)/openblas
+$(info $(shell $(NNTRAINER_JNI_ROOT)/prepare_openblas.sh $(NDK_LIBS_OUT)))
+
+endif #MAKECMDGOALS
+endif #OPENBLAS_ROOT
+
+LOCAL_MODULE := openblas
+LOCAL_SRC_FILES := $(OPENBLAS_ROOT)/lib/libopenblas.a
+LOCAL_EXPORT_C_INCLUDES := $(OPENBLAS_ROOT)/include
+LOCAL_EXPORT_CFLAGS += -DUSE_BLAS=1
+
+include $(PREBUILT_STATIC_LIBRARY)
+include $(CLEAR_VARS)
+
+endif #ENABLE_BLAS
+
+## prepare ml common api if nothing present
+ifndef ML_API_COMMON_ROOT
+ifneq ($(MAKECMDGOALS),clean)
+
+ML_API_COMMON_ROOT := $(NDK_INCLUDES_OUT)/ml_api_common
+$(info $(shell ($(NNTRAINER_JNI_ROOT)/prepare_ml-api.sh $(ML_API_COMMON_ROOT))))
+
+endif #MAKECMDGOALS
+endif #ML_API_COMMON_ROOT
+
+ML_API_COMMON_INCLUDES := $(ML_API_COMMON_ROOT)/include
+
+LOCAL_MODULE := ml-api-inference
+LOCAL_SRC_FILES := $(ML_API_COMMON_ROOT)/lib/arm64-v8a/libnnstreamer-native.so
+LOCAL_EXPORT_C_INCLUDES := $(ML_API_COMMON_ROOT)/include
+LOCAL_EXPORT_CFLAGS += -DUSE_BLAS=1
+
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+NNTRAINER_SRCS := $(NNTRAINER_ROOT)/nntrainer/models/neuralnet.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/models/model_loader.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/models/model_common_properties.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/models/dynamic_training_optimization.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/iteration_queue.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/databuffer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/data_iteration.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/databuffer_factory.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/func_data_producer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/random_data_producers.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/dataset/raw_file_data_producer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/tensor.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/lazy_tensor.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/manager.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/var_grad.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/weight.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/tensor_dim.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/tensor_pool.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/memory_pool.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/basic_planner.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/optimized_v1_planner.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/tensor/blas_interface.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/layer_node.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/layer_context.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/input_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/multiout_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/fc_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/bn_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/loss/loss_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/loss/mse_loss_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/loss/cross_entropy_sigmoid_loss_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/loss/cross_entropy_softmax_loss_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/loss/constant_derivative_loss_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/conv2d_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/conv1d_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/pooling2d_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/activation_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/flatten_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/reshape_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/addition_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/attention_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/concat_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/preprocess_flip_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/preprocess_translate_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/preprocess_l2norm_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/embedding.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/rnn.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/lstm.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/gru.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/time_dist.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/dropout.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/permute_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/centroid_knn.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/acti_func.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/split_layer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/common_properties.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/layers/layer_impl.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/graph/network_graph.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/graph/graph_core.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/optimizers/optimizer_context.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/optimizers/optimizer_devel.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/optimizers/optimizer_impl.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/optimizers/adam.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/optimizers/sgd.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/util_func.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/ini_wrapper.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/profiler.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/node_exporter.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/utils/base_properties.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/ini_interpreter.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/flatten_realizer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/recurrent_realizer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/remap_realizer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/slice_realizer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/input_realizer.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/app_context.cpp
+
+ifeq ($(ENABLE_TFLITE_INTERPRETER), 1)
+NNTRAINER_SRCS += $(NNTRAINER_ROOT)/nntrainer/compiler/tflite_opnode.cpp \
+                  $(NNTRAINER_ROOT)/nntrainer/compiler/tflite_interpreter.cpp
+endif #ENABLE_TFLITE_INTERPRETER
+
+# Add tflite backbone building
+ifeq ($(ENABLE_TFLITE_BACKBONE),1)
+NNTRAINER_SRCS += $(NNTRAINER_ROOT)/nntrainer/layers/tflite_layer.cpp
+endif #ENABLE_TFLITE_BACKBONE
+
+NNTRAINER_INCLUDES := $(NNTRAINER_ROOT)/nntrainer \
+                      $(NNTRAINER_ROOT)/nntrainer/dataset \
+                      $(NNTRAINER_ROOT)/nntrainer/layers \
+                      $(NNTRAINER_ROOT)/nntrainer/layers/loss \
+                      $(NNTRAINER_ROOT)/nntrainer/models \
+                      $(NNTRAINER_ROOT)/nntrainer/tensor \
+                      $(NNTRAINER_ROOT)/nntrainer/optimizers \
+                      $(NNTRAINER_ROOT)/nntrainer/utils \
+                      $(NNTRAINER_ROOT)/nntrainer/graph \
+                      $(NNTRAINER_ROOT)/nntrainer/utils \
+                      $(NNTRAINER_ROOT)/nntrainer/compiler \
+                      $(NNTRAINER_ROOT)/api \
+                      $(NNTRAINER_ROOT)/api/ccapi/include
+
+INIPARSER_SRCS := $(INIPARSER_ROOT)/src/iniparser.c \
+                  $(INIPARSER_ROOT)/src/dictionary.c
+
+INIPARSER_INCLUDES := $(INIPARSER_ROOT)/src
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -pthread -fexceptions
+LOCAL_CXXFLAGS      += -std=c++17 -frtti -fexceptions
+LOCAL_MODULE_TAGS   := optional
+
+LOCAL_LDLIBS        := -llog -landroid
+
+LOCAL_MODULE        := nntrainer
+LOCAL_SRC_FILES     := $(NNTRAINER_SRCS) $(INIPARSER_SRCS)
+LOCAL_C_INCLUDES    := $(NNTRAINER_INCLUDES) $(INIPARSER_INCLUDES) $(ML_API_COMMON_INCLUDES)
+
+# Add tflite backbone building
+ifeq ($(ENABLE_TFLITE_BACKBONE),1)
+LOCAL_STATIC_LIBRARIES += tensorflow-lite
+LOCAL_CFLAGS += -DENABLE_TFLITE_BACKBONE=1
+endif #ENABLE_TFLITE_BACKBONE
+
+ifeq ($(ENABLE_TFLITE_INTERPRETER), 1)
+LOCAL_CFLAGS += -DENABLE_TFLITE_INTERPRETER
+endif #ENABLE_TFLITE_INTERPRETER
+
+# Enable Profile
+ifeq ($(ENABLE_PROFILE), 1)
+LOCAL_CFLAGS += -DPROFILE=1
+endif #ENABLE_PROFILE
+
+ifeq ($(ENABLE_BLAS), 1)
+LOCAL_STATIC_LIBRARIES += openblas
+endif #ENABLE_BLAS
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+CCAPI_NNTRAINER_SRCS := $(NNTRAINER_ROOT)/api/ccapi/src/factory.cpp
+
+CCAPI_NNTRAINER_INCLUDES := $(NNTRAINER_ROOT)/nntrainer \
+                      $(NNTRAINER_ROOT)/nntrainer/dataset \
+                      $(NNTRAINER_ROOT)/nntrainer/layers \
+                      $(NNTRAINER_ROOT)/nntrainer/models \
+                      $(NNTRAINER_ROOT)/nntrainer/tensor \
+                      $(NNTRAINER_ROOT)/nntrainer/graph \
+                      $(NNTRAINER_ROOT)/nntrainer/optimizers \
+                      $(NNTRAINER_ROOT)/nntrainer/utils \
+                      $(NNTRAINER_ROOT)/api \
+                      $(NNTRAINER_ROOT)/api/ccapi/include
+
+LOCAL_SHARED_LIBRARIES := nntrainer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -pthread -fexceptions
+LOCAL_CXXFLAGS      += -std=c++17 -frtti -fexceptions
+LOCAL_MODULE_TAGS   := optional
+
+LOCAL_LDLIBS        := -llog -landroid
+
+LOCAL_MODULE        := ccapi-nntrainer
+LOCAL_SRC_FILES     := $(CCAPI_NNTRAINER_SRCS)
+LOCAL_C_INCLUDES    := $(CCAPI_NNTRAINER_INCLUDES) $(ML_API_COMMON_INCLUDES)
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+CAPI_NNTRAINER_SRCS := $(NNTRAINER_ROOT)/api/capi/src/nntrainer.cpp
+
+CAPI_NNTRAINER_INCLUDES := $(NNTRAINER_ROOT)/nntrainer \
+                      $(NNTRAINER_ROOT)/api \
+                      $(NNTRAINER_ROOT)/api/ccapi/include \
+                      $(NNTRAINER_ROOT)/api/capi/include
+
+LOCAL_SHARED_LIBRARIES := ccapi-nntrainer ml-api-inference nntrainer
+
+LOCAL_ARM_NEON      := true
+LOCAL_CFLAGS        += -pthread -fexceptions
+LOCAL_CXXFLAGS      += -std=c++17 -frtti -fexceptions
+LOCAL_MODULE_TAGS   := optional
+
+LOCAL_LDLIBS        := -llog -landroid
+
+LOCAL_MODULE        := capi-nntrainer
+LOCAL_SRC_FILES     := $(CAPI_NNTRAINER_SRCS)
+LOCAL_C_INCLUDES    := $(CAPI_NNTRAINER_INCLUDES) $(ML_API_COMMON_INCLUDES)
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/meson.build b/jni/meson.build
new file mode 100644 (file)
index 0000000..b865388
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+configure_file(input: 'Android.mk.in', output: 'Android.mk',
+  # install_dir: nntrainer_libdir / 'pkgconfig',
+  configuration: nntrainer_conf
+)
index 2e6bde2..f547802 100755 (executable)
@@ -1,5 +1,6 @@
 #!/usr/bin/env bash
 TARGET=$1
+set -e
 
 if [ ! -d ${TARGET} ]; then
   mkdir -p ${TARGET}
index 3c0d772..0bfe364 100755 (executable)
@@ -10,6 +10,7 @@
 #
 # usage: ./prepare_ml-api-common.sh target
 
+set -e
 TARGET=$1
 # Note: zip name can be nnstreamer-native-*.zip but this file is heavier to download
 FILE_PREFIX=nnstreamer-lite-native
index a39867f..8845c8e 100755 (executable)
@@ -10,6 +10,7 @@
 #
 # usage: ./prepare_openblas.sh target
 
+set -e
 TARGET=$1
 TAR_PREFIX=openblas
 TAR_NAME=${TAR_PREFIX}-0.2.20.tar.gz
index e10004a..de5cf99 100755 (executable)
@@ -2,6 +2,7 @@
 VERSION=$1
 TARGET=$2
 
+set -e
 echo "PREPARING TENSORFLOW ${VERSION} at ${TARGET}"
 
 if [ ! -d ${TARGET} ]; then
index 30062f4..dc784b3 100644 (file)
@@ -96,6 +96,7 @@ nntrainer_conf.set('INCLUDE_INSTALL_DIR', nntrainer_includedir)
 nntrainer_conf.set('CAPI_ML_COMMON_DEP', get_option('capi-ml-common-actual'))
 
 dummy_dep = dependency('', required: false)
+found_dummy_dep = declare_dependency() # dummy dep to use if found
 
 blas_dep = dummy_dep
 # Dependencies
@@ -107,6 +108,10 @@ if get_option('enable-blas')
   add_project_arguments('-DUSE_BLAS=1', language:['c','cpp'])
   if get_option('platform') == 'tizen' or get_option('platform') == 'yocto'
     blas_dep = dependency('openblas')
+  elif get_option('platform') == 'android'
+    message('preparing blas')
+    run_command(meson.source_root() / 'jni' / 'prepare_openblas.sh', meson.build_root(), check: true)
+    blas_dep = found_dummy_dep
   else
     blas_dep = dependency('blas-openblas', required:false)
     # for Ubuntu 20.04
@@ -150,6 +155,12 @@ libdl_dep = cxx.find_library('dl') # DL library
 thread_dep = dependency('threads') # pthread for tensorflow-lite
 
 iniparser_dep = dependency('iniparser', required : false, version : '>=4.1') # iniparser
+if get_option('platform') == 'android'
+  message('preparing iniparser')
+  run_command(meson.source_root() / 'jni' / 'prepare_iniparser.sh', meson.build_root(), check: true)
+  iniparser_dep = found_dummy_dep
+endif
+
 if not iniparser_dep.found()
   message('falling back to find libiniparser library and header files')
   libiniparser_dep = cxx.find_library('iniparser')
@@ -187,13 +198,30 @@ if nnstreamer_capi_dep.found()
   endif
 endif
 
-ml_api_common_dep = dependency(get_option('capi-ml-common-actual'), required: true)
+ml_api_common_dep = dummy_dep
+
+if get_option('platform') != 'android'
+  ml_api_common_dep = dependency(get_option('capi-ml-common-actual'), required: true)
+else
+  message('preparing ml api')
+  run_command(meson.source_root() / 'jni' / 'prepare_ml-api.sh', meson.build_root(), check: true)
+  ml_api_common_dep = found_dummy_dep
+endif
 
 if get_option('enable-nnstreamer-backbone')
   add_project_arguments('-DENABLE_NNSTREAMER_BACKBONE=1', language:['c','cpp'])
 endif
 
-tflite_dep = dependency('tensorflow2-lite', required: false)
+tflite_dep = dummy_dep
+
+if get_option('platform') != 'android'
+  tflite_dep = dependency('tensorflow2-lite', required: false)
+else
+  message('preparing tflite')
+  run_command(meson.source_root() / 'jni' / 'prepare_tflite.sh', '2.3.0', meson.build_root(), check: true)
+  tflite_dep = found_dummy_dep
+endif
+
 if get_option('enable-tflite-backbone')
   add_project_arguments('-DENABLE_TFLITE_BACKBONE=1', language:['c','cpp'])
 endif
@@ -298,3 +326,11 @@ if get_option('enable-android')
   )
 
 endif
+
+if get_option('platform') == 'android'
+  subdir('jni')
+endif
+
+if get_option('platform') != 'none'
+  message('building for ' + get_option('platform'))
+endif
index 28f180b..480b7c4 100644 (file)
@@ -1,4 +1,4 @@
-option('platform', type: 'combo', choices: ['none', 'tizen', 'yocto'], value: 'none')
+option('platform', type: 'combo', choices: ['none', 'tizen', 'yocto', 'android'], value: 'none')
 option('enable-app', type: 'boolean', value: true)
 option('install-app', type: 'boolean', value: true)
 option('use_gym', type: 'boolean', value: false)