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