Home | History | Annotate | Download | only in jni
      1 # Copyright 2014 Google Inc. All rights reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 # This file contains utility functions for Android projects using Flatbuffers.
     16 # To use this file, include it in your project's Android.mk by calling near the
     17 # top of your android makefile like so:
     18 #
     19 #     include $(FLATBUFFERS_DIR)/android/jni/include.mk
     20 #
     21 # You will also need to import the flatbuffers module using the standard
     22 # import-module function.
     23 #
     24 # The main functionality this file provides are the following functions:
     25 # flatbuffers_fbs_to_h: Converts flatbuffer schema paths to header paths.
     26 # flatbuffers_header_build_rule:
     27 #     Creates a build rule for a schema's generated header. This build rule
     28 #     has a dependency on the flatc compiler which will be built if necessary.
     29 # flatbuffers_header_build_rules:
     30 #     Creates build rules for generated headers for each schema listed and sets
     31 #     up depenedendies.
     32 #
     33 # More information and example usage can be found in the comments preceeding
     34 # each function.
     35 
     36 # Targets to build the Flatbuffers compiler as well as some utility definitions
     37 ifeq (,$(FLATBUFFERS_INCLUDE_MK_))
     38 FLATBUFFERS_INCLUDE_MK_ := 1
     39 
     40 # Portable version of $(realpath) that omits drive letters on Windows.
     41 realpath-portable = $(join $(filter %:,$(subst :,: ,$1)),\
     42                       $(realpath $(filter-out %:,$(subst :,: ,$1))))
     43 
     44 PROJECT_OS := $(OS)
     45 ifeq (,$(OS))
     46 PROJECT_OS := $(shell uname -s)
     47 else
     48 ifneq ($(findstring Windows,$(PROJECT_OS)),)
     49 PROJECT_OS := Windows
     50 endif
     51 endif
     52 
     53 # The following block generates build rules which result in headers being
     54 # rebuilt from flatbuffers schemas.
     55 
     56 FLATBUFFERS_CMAKELISTS_DIR := \
     57   $(call realpath-portable,$(dir $(lastword $(MAKEFILE_LIST)))/../..)
     58 
     59 # Directory that contains the FlatBuffers compiler.
     60 ifeq (Windows,$(PROJECT_OS))
     61 FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
     62 FLATBUFFERS_FLATC := $(lastword \
     63                        $(wildcard $(FLATBUFFERS_FLATC_PATH)/*/flatc.exe) \
     64                        $(wildcard $(FLATBUFFERS_FLATC_PATH)/flatc.exe))
     65 endif
     66 ifeq (Linux,$(PROJECT_OS))
     67 FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
     68 FLATBUFFERS_FLATC := $(FLATBUFFERS_FLATC_PATH)/flatc
     69 endif
     70 ifeq (Darwin,$(PROJECT_OS))
     71 FLATBUFFERS_FLATC_PATH?=$(FLATBUFFERS_CMAKELISTS_DIR)
     72 FLATBUFFERS_FLATC := $(lastword \
     73                        $(wildcard $(FLATBUFFERS_FLATC_PATH)/*/flatc) \
     74                        $(wildcard $(FLATBUFFERS_FLATC_PATH)/flatc))
     75 endif
     76 
     77 FLATBUFFERS_FLATC_ARGS?=
     78 
     79 # Search for cmake.
     80 CMAKE_ROOT := \
     81   $(call realpath-portable,$(LOCAL_PATH)/../../../../../../prebuilts/cmake)
     82 ifeq (,$(CMAKE))
     83 ifeq (Linux,$(PROJECT_OS))
     84 CMAKE := $(wildcard $(CMAKE_ROOT)/linux-x86/current/bin/cmake*)
     85 endif
     86 ifeq (Darwin,$(PROJECT_OS))
     87 CMAKE := \
     88   $(wildcard $(CMAKE_ROOT)/darwin-x86_64/current/*.app/Contents/bin/cmake)
     89 endif
     90 ifeq (Windows,$(PROJECT_OS))
     91 CMAKE := $(wildcard $(CMAKE_ROOT)/windows/current/bin/cmake*)
     92 endif
     93 endif
     94 ifeq (,$(CMAKE))
     95 CMAKE := cmake
     96 endif
     97 
     98 # Windows friendly portable local path.
     99 # GNU-make doesn't like : in paths, must use relative paths on Windows.
    100 ifeq (Windows,$(PROJECT_OS))
    101 PORTABLE_LOCAL_PATH =
    102 else
    103 PORTABLE_LOCAL_PATH = $(LOCAL_PATH)/
    104 endif
    105 
    106 # Generate a host build rule for the flatbuffers compiler.
    107 ifeq (Windows,$(PROJECT_OS))
    108 define build_flatc_recipe
    109 	$(FLATBUFFERS_CMAKELISTS_DIR)\android\jni\build_flatc.bat \
    110         $(CMAKE) $(FLATBUFFERS_CMAKELISTS_DIR)
    111 endef
    112 endif
    113 ifeq (Linux,$(PROJECT_OS))
    114 define build_flatc_recipe
    115 	+cd $(FLATBUFFERS_CMAKELISTS_DIR) && \
    116       $(CMAKE) . && \
    117       $(MAKE) flatc
    118 endef
    119 endif
    120 ifeq (Darwin,$(PROJECT_OS))
    121 define build_flatc_recipe
    122 	cd $(FLATBUFFERS_CMAKELISTS_DIR) && "$(CMAKE)" -GXcode . && \
    123         xcodebuild -target flatc
    124 endef
    125 endif
    126 ifeq (,$(build_flatc_recipe))
    127 ifeq (,$(FLATBUFFERS_FLATC))
    128 $(error flatc binary not found!)
    129 endif
    130 endif
    131 
    132 # Generate a build rule for flatc.
    133 ifeq ($(strip $(FLATBUFFERS_FLATC)),)
    134 flatc_target := build_flatc
    135 .PHONY: $(flatc_target)
    136 FLATBUFFERS_FLATC := \
    137   python $(FLATBUFFERS_CMAKELISTS_DIR)/android/jni/run_flatc.py \
    138     $(FLATBUFFERS_CMAKELISTS_DIR)
    139 else
    140 flatc_target := $(FLATBUFFERS_FLATC)
    141 endif
    142 $(flatc_target):
    143 	$(call build_flatc_recipe)
    144 
    145 # $(flatbuffers_fbs_to_h schema_dir,output_dir,path)
    146 #
    147 # Convert the specified schema path to a Flatbuffers generated header path.
    148 # For example:
    149 #
    150 # $(call flatbuffers_fbs_to_h,$(MY_PROJ_DIR)/schemas,\
    151 #   $(MY_PROJ_DIR)/gen/include,$(MY_PROJ_DIR)/schemas/example.fbs)
    152 #
    153 # This will convert the file path `$(MY_PROJ_DIR)/schemas/example.fbs)` to
    154 # `$(MY_PROJ_DIR)/gen/include/example_generated.h`
    155 define flatbuffers_fbs_to_h
    156 $(subst $(1),$(2),$(patsubst %.fbs,%_generated.h,$(3)))
    157 endef
    158 
    159 # $(flatbuffers_header_build_rule schema_file,schema_dir,output_dir,\
    160 #   schema_include_dirs)
    161 #
    162 # Generate a build rule that will convert a Flatbuffers schema to a generated
    163 # header derived from the schema filename using flatbuffers_fbs_to_h. For
    164 # example:
    165 #
    166 # $(call flatbuffers_header_build_rule,$(MY_PROJ_DIR)/schemas/example.fbs,\
    167 #   $(MY_PROJ_DIR)/schemas,$(MY_PROJ_DIR)/gen/include)
    168 #
    169 # The final argument, schema_include_dirs, is optional and is only needed when
    170 # the schema files depend on other schema files outside their own directory.
    171 define flatbuffers_header_build_rule
    172 $(eval \
    173   $(call flatbuffers_fbs_to_h,$(2),$(3),$(1)): $(1) $(flatc_target)
    174 	$(call host-echo-build-step,generic,Generate) \
    175       $(subst $(LOCAL_PATH)/,,$(call flatbuffers_fbs_to_h,$(2),$(3),$(1)))
    176 	$(hide) $$(FLATBUFFERS_FLATC) $(FLATBUFFERS_FLATC_ARGS) \
    177       $(foreach include,$(4),-I $(include)) -o $$(dir $$@) -c $$<)
    178 endef
    179 
    180 # TODO: Remove when the LOCAL_PATH expansion bug in the NDK is fixed.
    181 # Override the default behavior of local-source-file-path to workaround
    182 # a bug which prevents the build of deeply nested projects when NDK_OUT is
    183 # set.
    184 local-source-file-path=\
    185 $(if $(call host-path-is-absolute,$1),$1,$(call \
    186     realpath-portable,$(LOCAL_PATH)/$1))
    187 
    188 
    189 # $(flatbuffers_header_build_rules schema_files,schema_dir,output_dir,\
    190 #   schema_include_dirs,src_files,[build_target],[dependencies]))
    191 #
    192 # $(1) schema_files: Space separated list of flatbuffer schema files.
    193 # $(2) schema_dir: Directory containing the flatbuffer schemas.
    194 # $(3) output_dir: Where to place the generated files.
    195 # $(4) schema_include_dirs: Directories to include when generating schemas.
    196 # $(5) src_files: Files that should depend upon the headers generated from the
    197 #   flatbuffer schemas.
    198 # $(6) build_target: Name of a build target that depends upon all generated
    199 #   headers.
    200 # $(7) dependencies: Space seperated list of additional build targets src_files
    201 #   should depend upon.
    202 #
    203 # Use this in your own Android.mk file to generate build rules that will
    204 # generate header files for your flatbuffer schemas as well as automatically
    205 # set your source files to be dependent on the generated headers. For example:
    206 #
    207 # $(call flatbuffers_header_build_rules,$(MY_PROJ_SCHEMA_FILES),\
    208 #   $(MY_PROJ_SCHEMA_DIR),$(MY_PROJ_GENERATED_OUTPUT_DIR),
    209 #   $(MY_PROJ_SCHEMA_INCLUDE_DIRS),$(LOCAL_SRC_FILES))
    210 #
    211 # NOTE: Due problesm with path processing in ndk-build when presented with
    212 # deeply nested projects must redefine LOCAL_PATH after include this makefile
    213 # using:
    214 #
    215 # LOCAL_PATH := $(call realpath-portable,$(LOCAL_PATH))
    216 #
    217 define flatbuffers_header_build_rules
    218 $(foreach schema,$(1),\
    219   $(call flatbuffers_header_build_rule,\
    220     $(schema),$(strip $(2)),$(strip $(3)),$(strip $(4))))\
    221 $(foreach src,$(strip $(5)),\
    222   $(eval $(call local-source-file-path,$(src)): \
    223     $(foreach schema,$(strip $(1)),\
    224       $(call flatbuffers_fbs_to_h,$(strip $(2)),$(strip $(3)),$(schema)))))\
    225 $(if $(6),\
    226   $(foreach schema,$(strip $(1)),\
    227     $(eval $(6): \
    228       $(call flatbuffers_fbs_to_h,$(strip $(2)),$(strip $(3)),$(schema)))),)\
    229 $(if $(7),\
    230   $(foreach src,$(strip $(5)),\
    231       $(eval $(call local-source-file-path,$(src)): $(strip $(7)))),)\
    232 $(if $(7),\
    233   $(foreach dependency,$(strip $(7)),\
    234       $(eval $(6): $(dependency))),)
    235 endef
    236 
    237 endif  # FLATBUFFERS_INCLUDE_MK_
    238