1# Copyright 2020 The TensorFlow Authors. 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 16ifneq (3.82,$(firstword $(sort $(MAKE_VERSION) 3.82))) 17 $(error "Requires make version 3.82 or later (current is $(MAKE_VERSION))") 18endif 19 20# root directory of tensorflow 21TENSORFLOW_ROOT := 22MAKEFILE_DIR := tensorflow/lite/micro/tools/make 23 24# Override this on make command line to parse third party downloads during project generation 25# make -f tensorflow/lite/micro/tools/make/Makefile PARSE_THIRD_PARTY=true TARGET=apollo3evb generate_hello_world_make_project 26PARSE_THIRD_PARTY := 27 28 29# Pull in some convenience functions. 30include $(MAKEFILE_DIR)/helper_functions.inc 31 32# Try to figure out the host system 33HOST_OS := 34ifeq ($(OS),Windows_NT) 35 HOST_OS = windows 36else 37 UNAME_S := $(shell uname -s) 38 ifeq ($(UNAME_S),Linux) 39 HOST_OS := linux 40 endif 41 ifeq ($(UNAME_S),Darwin) 42 HOST_OS := osx 43 endif 44endif 45 46# Determine the host architecture, with any ix86 architecture being labelled x86_32 47HOST_ARCH := $(shell if uname -m | grep -Eq 'i[345678]86'; then echo x86_32; else echo $(shell uname -m); fi) 48 49# Override these on the make command line to target a specific architecture. For example: 50# make -f tensorflow/lite/Makefile TARGET=rpi TARGET_ARCH=armv7l 51TARGET := $(HOST_OS) 52TARGET_ARCH := $(HOST_ARCH) 53 54# Default compiler and tool names: 55TOOLCHAIN:=gcc 56CXX_TOOL := g++ 57CC_TOOL := gcc 58AR_TOOL := ar 59 60ifneq ($(TAGS),) 61 $(error The TAGS command line option is no longer supported in the TFLM Makefile.) 62endif 63 64# Specify which specialized kernel implementation should be pulled in. 65OPTIMIZED_KERNEL_DIR := 66 67# Specify which co-processor's kernel implementation should be pulled in. 68# If the same kernel is implemented in both kernels/OPTIMIZED_KERNEL_DIR and 69# kernels/CO_PROCESSOR, then the implementation from kernels/CO_PROCESSOR will 70# be used. 71CO_PROCESSOR := 72 73# This is obviously horrible. We need to generate these 3 versions of the 74# include directories from one source. 75INCLUDES := \ 76-I. \ 77-I$(MAKEFILE_DIR)/downloads/gemmlowp \ 78-I$(MAKEFILE_DIR)/downloads/flatbuffers/include \ 79-I$(MAKEFILE_DIR)/downloads/ruy 80 81# Same list of paths, but now relative to the generated project files. 82GENERATED_PROJECT_INCLUDES := \ 83-I. \ 84-I./third_party/gemmlowp \ 85-I./third_party/flatbuffers/include \ 86-I./third_party/ruy 87 88# Same list of paths, but now in the format the generate_keil_project.py 89# script expects them. 90PROJECT_INCLUDES := \ 91. \ 92third_party/gemmlowp \ 93third_party/flatbuffers/include \ 94third_party/ruy 95 96TEST_SCRIPT := 97 98MICROLITE_LIBS := -lm 99 100# For the target, optimized_kernel_dir, and co-processor as specified on the 101# command line we add -D<tag> to the cflags to allow for #idefs in the code. 102# 103# We apply the following transformations (via the tr command): 104# 1. Convert to uppercase (TARGET=xtensa -> -DXTENSA) 105 106ADDITIONAL_DEFINES := -D$(shell echo $(TARGET) | tr [a-z] [A-Z]) 107 108ifneq ($(OPTIMIZED_KERNEL_DIR),) 109 ADDITIONAL_DEFINES += -D$(shell echo $(OPTIMIZED_KERNEL_DIR) | tr [a-z] [A-Z]) 110endif 111 112ifneq ($(CO_PROCESSOR),) 113 ADDITIONAL_DEFINES += -D$(shell echo $(CO_PROCESSOR) | tr [a-z] [A-Z]) 114endif 115 116OPTIMIZATION_LEVEL := -O3 117 118CC_WARNINGS := \ 119 -Werror \ 120 -Wsign-compare \ 121 -Wdouble-promotion \ 122 -Wshadow \ 123 -Wunused-variable \ 124 -Wmissing-field-initializers \ 125 -Wunused-function \ 126 -Wswitch \ 127 -Wvla \ 128 -Wall \ 129 -Wextra \ 130 -Wstrict-aliasing \ 131 -Wno-unused-parameter 132 133COMMON_FLAGS := \ 134 -fno-unwind-tables \ 135 -ffunction-sections \ 136 -fdata-sections \ 137 -fmessage-length=0 \ 138 -DTF_LITE_STATIC_MEMORY \ 139 -DTF_LITE_DISABLE_X86_NEON \ 140 $(OPTIMIZATION_LEVEL) \ 141 $(CC_WARNINGS) \ 142 $(ADDITIONAL_DEFINES) 143 144ifeq ($(TARGET), $(HOST_OS)) 145 # If we are not doing a cross-compilation then -DTF_LITE_USE_CTIME is what we 146 # want to have by default. 147 COMMON_FLAGS += -DTF_LITE_USE_CTIME 148endif 149 150CXXFLAGS := \ 151 -std=c++11 \ 152 -fno-rtti \ 153 -fno-exceptions \ 154 -fno-threadsafe-statics \ 155 $(COMMON_FLAGS) 156 157CCFLAGS := \ 158 -std=c11 \ 159 $(COMMON_FLAGS) 160 161ARFLAGS := -r 162 163ifeq ($(TOOLCHAIN), gcc) 164 ifneq ($(TARGET), osx) 165 # GCC on MacOS uses an LLVM backend so we avoid the additional linker flags 166 # that are unsupported with LLVM. 167 LDFLAGS += \ 168 -Wl,--fatal-warnings \ 169 -Wl,--gc-sections 170 endif 171endif 172 173# override these in the makefile.inc for specific compiler targets 174TARGET_TOOLCHAIN_PREFIX := 175TARGET_TOOLCHAIN_ROOT := 176 177# Specifying BUILD_TYPE=<blah> as part of the make command gives us a few 178# options to choose from. 179# 180# If BUILD_TYPE is not specified, the default build (which should be suitable 181# most of the time) has all of the error checking logic at the expense of a 182# latency increase of ~5-10% relative to BUILD_TYPE=release_with_logs. 183# 184# This default build is most suited for usual development and testing as is 185# highlighted by the discussion on this github pull request: 186# https://github.com/tensorflow/tensorflow/pull/42314#issuecomment-694360567 187BUILD_TYPE := default 188ifeq ($(BUILD_TYPE), debug) 189 # Specifying BUILD_TYPE=debug adds debug symbols to the binary (and makes it 190 # larger) and should be used to run a binary with gdb. 191 CXXFLAGS += -g 192 CCFLAGS += -g 193else ifeq ($(BUILD_TYPE), release) 194 # The 'release' build results in the smallest binary (by virtue of removing 195 # strings from log messages, DCHECKs ...). 196 # 197 # The down-side is that we currently do not have a good mechanism to allow 198 # for logging that is not related to errors (e.g. profiling information, or 199 # logs that help determine if tests pass or fail). As a result, we are unable 200 # to run tests or benchmarks with BUILD_TYPE=release (which is a bit 201 # counter-intuitive). TODO(b/158205789): A global error reporter might help. 202 # 203 # For a close approximation of the release build use 204 # BUILD_TYPE=release_with_logs. 205 CXXFLAGS += -DNDEBUG -DTF_LITE_STRIP_ERROR_STRINGS 206 CCFLAGS += -DNDEBUG -DTF_LITE_STRIP_ERROR_STRINGS 207else ifeq ($(BUILD_TYPE), release_with_logs) 208 # The latency with BUILD_TYPE=release_with_logs will be close to the 'release' 209 # build and there will still be error logs. This build type may be preferable 210 # for profiling and benchmarking. 211 CXXFLAGS += -DNDEBUG 212 CCFLAGS += -DNDEBUG 213else ifeq ($(BUILD_TYPE), no_tf_lite_static_memory) 214 # This build should not be used to run any binaries/tests since 215 # TF_LITE_STATIC_MEMORY should be defined for all micro builds. However, 216 # having a build without TF_LITE_STATIC_MEMORY is useful to catch errors in 217 # code that is shared between TfLite Mobile and TfLite Micro. See this issue 218 # for more details: 219 # https://github.com/tensorflow/tensorflow/issues/43076 220 CXXFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CXXFLAGS)) 221 CCFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CCFLAGS)) 222endif 223 224# This library is the main target for this makefile. It will contain a minimal 225# runtime that can be linked in to other programs. 226MICROLITE_LIB_NAME := libtensorflow-microlite.a 227 228# These two must be defined before we include the target specific Makefile.inc 229# because we filter out the examples that are not supported for those targets. 230# See targets/xtensa_xpg_makefile.inc for an example. 231# 232# We limit max depth of directories to search to not include target specific 233# Makefiles that are included directly by the main example Makefile. See 234# examples/micro_speech/Makefile.inc for an example. At the same time, we 235# search till an arbitrary depth for files named Makefile_internal.inc as a way 236# to bypass this check and allow for deeper directory structures. 237MICRO_LITE_EXAMPLE_TESTS := $(shell find tensorflow/lite/micro/examples/ -maxdepth 2 -name Makefile.inc) 238MICRO_LITE_EXAMPLE_TESTS += $(shell find tensorflow/lite/micro/examples/ -name Makefile_internal.inc) 239MICRO_LITE_BENCHMARKS := $(wildcard tensorflow/lite/micro/benchmarks/Makefile.inc) 240 241# TODO(b/152645559): move all benchmarks to benchmarks directory. 242MICROLITE_BENCHMARK_SRCS := \ 243$(wildcard tensorflow/lite/micro/benchmarks/*benchmark.cc) 244 245MICROLITE_TEST_SRCS := \ 246tensorflow/lite/micro/memory_arena_threshold_test.cc \ 247tensorflow/lite/micro/memory_helpers_test.cc \ 248tensorflow/lite/micro/micro_allocator_test.cc \ 249tensorflow/lite/micro/micro_error_reporter_test.cc \ 250tensorflow/lite/micro/micro_interpreter_test.cc \ 251tensorflow/lite/micro/micro_mutable_op_resolver_test.cc \ 252tensorflow/lite/micro/micro_string_test.cc \ 253tensorflow/lite/micro/micro_time_test.cc \ 254tensorflow/lite/micro/micro_utils_test.cc \ 255tensorflow/lite/micro/recording_micro_allocator_test.cc \ 256tensorflow/lite/micro/recording_simple_memory_allocator_test.cc \ 257tensorflow/lite/micro/simple_memory_allocator_test.cc \ 258tensorflow/lite/micro/testing_helpers_test.cc \ 259tensorflow/lite/micro/kernels/activations_test.cc \ 260tensorflow/lite/micro/kernels/add_test.cc \ 261tensorflow/lite/micro/kernels/arg_min_max_test.cc \ 262tensorflow/lite/micro/kernels/batch_to_space_nd_test.cc \ 263tensorflow/lite/micro/kernels/cast_test.cc \ 264tensorflow/lite/micro/kernels/ceil_test.cc \ 265tensorflow/lite/micro/kernels/circular_buffer_test.cc \ 266tensorflow/lite/micro/kernels/comparisons_test.cc \ 267tensorflow/lite/micro/kernels/concatenation_test.cc \ 268tensorflow/lite/micro/kernels/conv_test.cc \ 269tensorflow/lite/micro/kernels/depthwise_conv_test.cc \ 270tensorflow/lite/micro/kernels/dequantize_test.cc \ 271tensorflow/lite/micro/kernels/detection_postprocess_test.cc \ 272tensorflow/lite/micro/kernels/elementwise_test.cc \ 273tensorflow/lite/micro/kernels/exp_test.cc \ 274tensorflow/lite/micro/kernels/floor_test.cc \ 275tensorflow/lite/micro/kernels/fully_connected_test.cc \ 276tensorflow/lite/micro/kernels/hard_swish_test.cc \ 277tensorflow/lite/micro/kernels/l2norm_test.cc \ 278tensorflow/lite/micro/kernels/logical_test.cc \ 279tensorflow/lite/micro/kernels/logistic_test.cc \ 280tensorflow/lite/micro/kernels/maximum_minimum_test.cc \ 281tensorflow/lite/micro/kernels/mul_test.cc \ 282tensorflow/lite/micro/kernels/neg_test.cc \ 283tensorflow/lite/micro/kernels/pack_test.cc \ 284tensorflow/lite/micro/kernels/pad_test.cc \ 285tensorflow/lite/micro/kernels/pooling_test.cc \ 286tensorflow/lite/micro/kernels/prelu_test.cc \ 287tensorflow/lite/micro/kernels/quantization_util_test.cc \ 288tensorflow/lite/micro/kernels/quantize_test.cc \ 289tensorflow/lite/micro/kernels/reduce_test.cc \ 290tensorflow/lite/micro/kernels/reshape_test.cc \ 291tensorflow/lite/micro/kernels/resize_nearest_neighbor_test.cc \ 292tensorflow/lite/micro/kernels/round_test.cc \ 293tensorflow/lite/micro/kernels/shape_test.cc \ 294tensorflow/lite/micro/kernels/softmax_test.cc \ 295tensorflow/lite/micro/kernels/space_to_batch_nd_test.cc \ 296tensorflow/lite/micro/kernels/split_test.cc \ 297tensorflow/lite/micro/kernels/split_v_test.cc \ 298tensorflow/lite/micro/kernels/strided_slice_test.cc \ 299tensorflow/lite/micro/kernels/sub_test.cc \ 300tensorflow/lite/micro/kernels/svdf_test.cc \ 301tensorflow/lite/micro/kernels/tanh_test.cc \ 302tensorflow/lite/micro/kernels/transpose_conv_test.cc \ 303tensorflow/lite/micro/kernels/unpack_test.cc \ 304tensorflow/lite/micro/kernels/zeros_like_test.cc \ 305tensorflow/lite/micro/memory_planner/greedy_memory_planner_test.cc \ 306tensorflow/lite/micro/memory_planner/linear_memory_planner_test.cc 307 308MICROLITE_CC_KERNEL_SRCS := \ 309tensorflow/lite/micro/kernels/activations.cc \ 310tensorflow/lite/micro/kernels/add.cc \ 311tensorflow/lite/micro/kernels/arg_min_max.cc \ 312tensorflow/lite/micro/kernels/batch_to_space_nd.cc \ 313tensorflow/lite/micro/kernels/cast.cc \ 314tensorflow/lite/micro/kernels/ceil.cc \ 315tensorflow/lite/micro/kernels/circular_buffer.cc \ 316tensorflow/lite/micro/kernels/comparisons.cc \ 317tensorflow/lite/micro/kernels/concatenation.cc \ 318tensorflow/lite/micro/kernels/conv.cc \ 319tensorflow/lite/micro/kernels/conv_common.cc \ 320tensorflow/lite/micro/kernels/conv_test_common.cc \ 321tensorflow/lite/micro/kernels/depthwise_conv.cc \ 322tensorflow/lite/micro/kernels/dequantize.cc \ 323tensorflow/lite/micro/kernels/detection_postprocess.cc \ 324tensorflow/lite/micro/kernels/elementwise.cc \ 325tensorflow/lite/micro/kernels/ethosu.cc \ 326tensorflow/lite/micro/kernels/exp.cc \ 327tensorflow/lite/micro/kernels/flexbuffers_generated_data.cc \ 328tensorflow/lite/micro/kernels/floor.cc \ 329tensorflow/lite/micro/kernels/fully_connected.cc \ 330tensorflow/lite/micro/kernels/fully_connected_common.cc \ 331tensorflow/lite/micro/kernels/hard_swish.cc \ 332tensorflow/lite/micro/kernels/kernel_runner.cc \ 333tensorflow/lite/micro/kernels/kernel_util.cc \ 334tensorflow/lite/micro/kernels/l2norm.cc \ 335tensorflow/lite/micro/kernels/logical.cc \ 336tensorflow/lite/micro/kernels/logistic.cc \ 337tensorflow/lite/micro/kernels/maximum_minimum.cc \ 338tensorflow/lite/micro/kernels/mul.cc \ 339tensorflow/lite/micro/kernels/neg.cc \ 340tensorflow/lite/micro/kernels/pack.cc \ 341tensorflow/lite/micro/kernels/pad.cc \ 342tensorflow/lite/micro/kernels/pooling.cc \ 343tensorflow/lite/micro/kernels/prelu.cc \ 344tensorflow/lite/micro/kernels/quantize.cc \ 345tensorflow/lite/micro/kernels/quantize_common.cc \ 346tensorflow/lite/micro/kernels/reduce.cc \ 347tensorflow/lite/micro/kernels/reshape.cc \ 348tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc \ 349tensorflow/lite/micro/kernels/round.cc \ 350tensorflow/lite/micro/kernels/shape.cc \ 351tensorflow/lite/micro/kernels/softmax.cc \ 352tensorflow/lite/micro/kernels/softmax_common.cc \ 353tensorflow/lite/micro/kernels/space_to_batch_nd.cc \ 354tensorflow/lite/micro/kernels/split.cc \ 355tensorflow/lite/micro/kernels/split_v.cc \ 356tensorflow/lite/micro/kernels/strided_slice.cc \ 357tensorflow/lite/micro/kernels/sub.cc \ 358tensorflow/lite/micro/kernels/svdf.cc \ 359tensorflow/lite/micro/kernels/svdf_common.cc \ 360tensorflow/lite/micro/kernels/tanh.cc \ 361tensorflow/lite/micro/kernels/transpose_conv.cc \ 362tensorflow/lite/micro/kernels/unpack.cc \ 363tensorflow/lite/micro/kernels/zeros_like.cc 364 365MICROLITE_TEST_HDRS := \ 366$(wildcard tensorflow/lite/micro/testing/*.h) 367 368MICROLITE_CC_BASE_SRCS := \ 369$(wildcard tensorflow/lite/micro/*.cc) \ 370$(wildcard tensorflow/lite/micro/memory_planner/*.cc) \ 371tensorflow/lite/c/common.c \ 372tensorflow/lite/core/api/error_reporter.cc \ 373tensorflow/lite/core/api/flatbuffer_conversions.cc \ 374tensorflow/lite/core/api/op_resolver.cc \ 375tensorflow/lite/core/api/tensor_utils.cc \ 376tensorflow/lite/kernels/internal/quantization_util.cc \ 377tensorflow/lite/kernels/kernel_util.cc \ 378tensorflow/lite/schema/schema_utils.cc 379 380MICROLITE_CC_SRCS := $(filter-out $(MICROLITE_TEST_SRCS), $(MICROLITE_CC_BASE_SRCS)) 381MICROLITE_CC_SRCS := $(filter-out $(MICROLITE_BENCHMARK_SRCS), $(MICROLITE_CC_SRCS)) 382 383MICROLITE_CC_HDRS := \ 384$(wildcard tensorflow/lite/micro/*.h) \ 385$(wildcard tensorflow/lite/micro/benchmarks/*model_data.h) \ 386$(wildcard tensorflow/lite/micro/kernels/*.h) \ 387$(wildcard tensorflow/lite/micro/memory_planner/*.h) \ 388LICENSE \ 389tensorflow/lite/c/builtin_op_data.h \ 390tensorflow/lite/c/c_api_types.h \ 391tensorflow/lite/c/common.h \ 392tensorflow/lite/core/api/error_reporter.h \ 393tensorflow/lite/core/api/flatbuffer_conversions.h \ 394tensorflow/lite/core/api/op_resolver.h \ 395tensorflow/lite/core/api/tensor_utils.h \ 396tensorflow/lite/kernels/internal/common.h \ 397tensorflow/lite/kernels/internal/compatibility.h \ 398tensorflow/lite/kernels/internal/optimized/neon_check.h \ 399tensorflow/lite/kernels/internal/quantization_util.h \ 400tensorflow/lite/kernels/internal/reference/add.h \ 401tensorflow/lite/kernels/internal/reference/arg_min_max.h \ 402tensorflow/lite/kernels/internal/reference/batch_to_space_nd.h \ 403tensorflow/lite/kernels/internal/reference/binary_function.h \ 404tensorflow/lite/kernels/internal/reference/ceil.h \ 405tensorflow/lite/kernels/internal/reference/comparisons.h \ 406tensorflow/lite/kernels/internal/reference/concatenation.h \ 407tensorflow/lite/kernels/internal/reference/conv.h \ 408tensorflow/lite/kernels/internal/reference/depthwiseconv_float.h \ 409tensorflow/lite/kernels/internal/reference/depthwiseconv_uint8.h \ 410tensorflow/lite/kernels/internal/reference/dequantize.h \ 411tensorflow/lite/kernels/internal/reference/exp.h \ 412tensorflow/lite/kernels/internal/reference/floor.h \ 413tensorflow/lite/kernels/internal/reference/fully_connected.h \ 414tensorflow/lite/kernels/internal/reference/hard_swish.h \ 415tensorflow/lite/kernels/internal/reference/integer_ops/add.h \ 416tensorflow/lite/kernels/internal/reference/integer_ops/conv.h \ 417tensorflow/lite/kernels/internal/reference/integer_ops/depthwise_conv.h \ 418tensorflow/lite/kernels/internal/reference/integer_ops/fully_connected.h \ 419tensorflow/lite/kernels/internal/reference/integer_ops/logistic.h \ 420tensorflow/lite/kernels/internal/reference/integer_ops/l2normalization.h \ 421tensorflow/lite/kernels/internal/reference/integer_ops/mean.h \ 422tensorflow/lite/kernels/internal/reference/integer_ops/mul.h \ 423tensorflow/lite/kernels/internal/reference/integer_ops/pooling.h \ 424tensorflow/lite/kernels/internal/reference/integer_ops/tanh.h \ 425tensorflow/lite/kernels/internal/reference/integer_ops/transpose_conv.h \ 426tensorflow/lite/kernels/internal/reference/l2normalization.h \ 427tensorflow/lite/kernels/internal/reference/maximum_minimum.h \ 428tensorflow/lite/kernels/internal/reference/mul.h \ 429tensorflow/lite/kernels/internal/reference/neg.h \ 430tensorflow/lite/kernels/internal/reference/pad.h \ 431tensorflow/lite/kernels/internal/reference/pooling.h \ 432tensorflow/lite/kernels/internal/reference/prelu.h \ 433tensorflow/lite/kernels/internal/reference/process_broadcast_shapes.h \ 434tensorflow/lite/kernels/internal/reference/quantize.h \ 435tensorflow/lite/kernels/internal/reference/reduce.h \ 436tensorflow/lite/kernels/internal/reference/requantize.h \ 437tensorflow/lite/kernels/internal/reference/resize_nearest_neighbor.h \ 438tensorflow/lite/kernels/internal/reference/round.h \ 439tensorflow/lite/kernels/internal/reference/softmax.h \ 440tensorflow/lite/kernels/internal/reference/space_to_batch_nd.h \ 441tensorflow/lite/kernels/internal/reference/sub.h \ 442tensorflow/lite/kernels/internal/reference/logistic.h \ 443tensorflow/lite/kernels/internal/reference/strided_slice.h \ 444tensorflow/lite/kernels/internal/reference/tanh.h \ 445tensorflow/lite/kernels/internal/reference/transpose_conv.h \ 446tensorflow/lite/kernels/internal/cppmath.h \ 447tensorflow/lite/kernels/internal/max.h \ 448tensorflow/lite/kernels/internal/min.h \ 449tensorflow/lite/kernels/internal/portable_tensor.h \ 450tensorflow/lite/kernels/internal/strided_slice_logic.h \ 451tensorflow/lite/kernels/internal/tensor_ctypes.h \ 452tensorflow/lite/kernels/internal/types.h \ 453tensorflow/lite/kernels/kernel_util.h \ 454tensorflow/lite/kernels/op_macros.h \ 455tensorflow/lite/kernels/padding.h \ 456tensorflow/lite/portable_type_to_tflitetype.h \ 457tensorflow/lite/schema/schema_generated.h \ 458tensorflow/lite/schema/schema_utils.h 459 460# TODO(b/165940489): Figure out how to avoid including fixed point 461# platform-specific headers. 462THIRD_PARTY_CC_HDRS := \ 463third_party/gemmlowp/fixedpoint/fixedpoint.h \ 464third_party/gemmlowp/fixedpoint/fixedpoint_neon.h \ 465third_party/gemmlowp/fixedpoint/fixedpoint_sse.h \ 466third_party/gemmlowp/internal/detect_platform.h \ 467third_party/gemmlowp/LICENSE \ 468third_party/flatbuffers/include/flatbuffers/base.h \ 469third_party/flatbuffers/include/flatbuffers/stl_emulation.h \ 470third_party/flatbuffers/include/flatbuffers/flatbuffers.h \ 471third_party/flatbuffers/include/flatbuffers/flexbuffers.h \ 472third_party/flatbuffers/include/flatbuffers/util.h \ 473third_party/flatbuffers/LICENSE.txt \ 474third_party/ruy/ruy/profiler/instrumentation.h 475 476 477MAKE_PROJECT_FILES := \ 478 Makefile \ 479 README_MAKE.md \ 480 .vscode/tasks.json 481 482MBED_PROJECT_FILES := \ 483 README_MBED.md \ 484 mbed-os.lib \ 485 mbed_app.json 486 487KEIL_PROJECT_FILES := \ 488 README_KEIL.md \ 489 keil_project.uvprojx 490 491ARDUINO_PROJECT_FILES := \ 492 library.properties 493 494ESP_PROJECT_FILES := \ 495 README_ESP.md \ 496 CMakeLists.txt \ 497 main/CMakeLists.txt \ 498 components/tfmicro/CMakeLists.txt 499 500ALL_PROJECT_TARGETS := 501 502ARDUINO_LIBRARY_TARGETS := 503ARDUINO_LIBRARY_ZIPS := 504 505# For some invocations of the makefile, it is useful to avoid downloads. This 506# can be achieved by explicitly passing in DISABLE_DOWNLOADS=true on the command 507# line. Note that for target-specific downloads (e.g. CMSIS) there will need to 508# be corresponding checking in the respecitve included makefiles (e.g. 509# ext_libs/cmsis_nn.inc) 510DISABLE_DOWNLOADS := 511 512ifneq ($(DISABLE_DOWNLOADS), true) 513 # The download scripts require that the downloads directory already exist for 514 # improved error checking. To accomodate that, we first create a downloads 515 # directory. 516 $(shell mkdir -p ${MAKEFILE_DIR}/downloads) 517 518 # Directly download the flatbuffers library. 519 DOWNLOAD_RESULT := $(shell $(MAKEFILE_DIR)/flatbuffers_download.sh ${MAKEFILE_DIR}/downloads) 520 ifneq ($(DOWNLOAD_RESULT), SUCCESS) 521 $(error Something went wrong with the flatbuffers download: $(DOWNLOAD_RESULT)) 522 endif 523 524 DOWNLOAD_RESULT := $(shell $(MAKEFILE_DIR)/pigweed_download.sh ${MAKEFILE_DIR}/downloads) 525 ifneq ($(DOWNLOAD_RESULT), SUCCESS) 526 $(error Something went wrong with the pigweed download: $(DOWNLOAD_RESULT)) 527 endif 528 529 include $(MAKEFILE_DIR)/third_party_downloads.inc 530 THIRD_PARTY_DOWNLOADS := 531 $(eval $(call add_third_party_download,$(GEMMLOWP_URL),$(GEMMLOWP_MD5),gemmlowp,)) 532 $(eval $(call add_third_party_download,$(RUY_URL),$(RUY_MD5),ruy,)) 533 $(eval $(call add_third_party_download,$(PERSON_MODEL_URL),$(PERSON_MODEL_MD5),person_model_grayscale,)) 534 $(eval $(call add_third_party_download,$(PERSON_MODEL_INT8_URL),$(PERSON_MODEL_INT8_MD5),person_model_int8,)) 535endif 536 537# The target-specific makefile must have a name that is exactly 538# TARGET_makefile.inc and is only needed for cross-compilation (i.e. when TARGET 539# is different from the HOST_OS). 540# There are also some other targets like arduino and CHRE that are also special 541# in that they do no have a <target>_makefile but are still used to create a 542# directory for the generated artifacts. We are using a workaround right now and 543# will be separating the project generation from the Makefile in the future. 544TARGETS_WITHOUT_MAKEFILES := \ 545$(HOST_OS) \ 546arduino 547 548# This specific string needs to be outputted for a test to be recognized as 549# having passed. 550TEST_PASS_STRING:='~~~ALL TESTS PASSED~~~' 551 552# ${TARGET}_makefile.inc can set this to true to allow it to defined a custom 553# implementation for `make test`. See bluepill_makefile as an example. 554TARGET_SPECIFIC_MAKE_TEST:=0 555 556ifeq ($(findstring $(TARGET),$(TARGETS_WITHOUT_MAKEFILES)),) 557 include $(MAKEFILE_DIR)/targets/$(TARGET)_makefile.inc 558endif 559 560ifneq ($(OPTIMIZED_KERNEL_DIR),) 561 include $(MAKEFILE_DIR)/ext_libs/$(OPTIMIZED_KERNEL_DIR).inc 562 # Specialize for the optimized kernels 563 MICROLITE_CC_KERNEL_SRCS := $(call substitute_specialized_implementations,$(MICROLITE_CC_KERNEL_SRCS),$(OPTIMIZED_KERNEL_DIR)) 564endif 565 566# If a co-processor is specified on the command line with 567# CO_PROCESSOR=<co_processor> then we will include ext_libs/<co_processor>.inc 568# and find additional kernel sources in kernels/<co_processor>/ 569# 570# That the co-processor specialization of the kernel sources happens after the 571# optimized_kernel_dir means that if there is an implementation of the same 572# kernel in both directories, the one from co_processor will be used. 573ifneq ($(CO_PROCESSOR),) 574 include $(MAKEFILE_DIR)/ext_libs/$(CO_PROCESSOR).inc 575 # Specialize for the coprocessor kernels. 576 MICROLITE_CC_KERNEL_SRCS := $(call substitute_specialized_implementations,$(MICROLITE_CC_KERNEL_SRCS),$(CO_PROCESSOR)) 577endif 578 579# Specialize for debug_log. micro_time etc. 580MICROLITE_CC_SRCS := $(call substitute_specialized_implementations,$(MICROLITE_CC_SRCS),$(TARGET)) 581MICROLITE_CC_SRCS += $(MICROLITE_CC_KERNEL_SRCS) 582 583ALL_SRCS := \ 584 $(MICROLITE_CC_SRCS) \ 585 $(MICROLITE_TEST_SRCS) 586 587# Where compiled objects are stored. 588 589GENDIR := $(MAKEFILE_DIR)/gen/$(TARGET)_$(TARGET_ARCH)_$(BUILD_TYPE)/ 590OBJDIR := $(GENDIR)obj/ 591BINDIR := $(GENDIR)bin/ 592LIBDIR := $(GENDIR)lib/ 593PRJDIR := $(GENDIR)prj/ 594 595MICROLITE_LIB_PATH := $(LIBDIR)$(MICROLITE_LIB_NAME) 596 597CXX := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${CXX_TOOL} 598CC := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${CC_TOOL} 599AR := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${AR_TOOL} 600 601# The default Makefile target(all) must appear before any target, 602# which is compiled if there's no command-line arguments. 603all: $(MICROLITE_LIB_PATH) 604 605# Load the examples. 606include $(MICRO_LITE_EXAMPLE_TESTS) 607 608# Load the benchmarks. 609include $(MICRO_LITE_BENCHMARKS) 610 611# Create rules for downloading third-party dependencies. 612THIRD_PARTY_TARGETS := 613$(foreach DOWNLOAD,$(THIRD_PARTY_DOWNLOADS),$(eval $(call create_download_rule,$(DOWNLOAD)))) 614third_party_downloads: $(THIRD_PARTY_TARGETS) 615 616MICROLITE_LIB_OBJS := $(addprefix $(OBJDIR), \ 617$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(MICROLITE_CC_SRCS)))) 618 619MICROLITE_LIB_OBJS += $(addprefix $(OBJDIR), \ 620$(patsubst %.S,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(THIRD_PARTY_CC_SRCS))))) 621 622# For normal manually-created TensorFlow C++ source files. 623$(OBJDIR)%.o: %.cc $(THIRD_PARTY_TARGETS) 624 @mkdir -p $(dir $@) 625 $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ 626 627# For normal manually-created TensorFlow C source files. 628$(OBJDIR)%.o: %.c $(THIRD_PARTY_TARGETS) 629 @mkdir -p $(dir $@) 630 $(CC) $(CCFLAGS) $(INCLUDES) -c $< -o $@ 631 632# For normal manually-created TensorFlow ASM source files. 633$(OBJDIR)%.o: %.S $(THIRD_PARTY_TARGETS) 634 @mkdir -p $(dir $@) 635 $(CC) $(CCFLAGS) $(INCLUDES) -c $< -o $@ 636 637microlite: $(MICROLITE_LIB_PATH) 638 639# Hack for generating schema file bypassing flatbuffer parsing 640tensorflow/lite/schema/schema_generated.h: 641 @cp -u tensorflow/lite/schema/schema_generated.h.oss tensorflow/lite/schema/schema_generated.h 642 643# Gathers together all the objects we've compiled into a single '.a' archive. 644$(MICROLITE_LIB_PATH): tensorflow/lite/schema/schema_generated.h $(MICROLITE_LIB_OBJS) 645 @mkdir -p $(dir $@) 646 $(AR) $(ARFLAGS) $(MICROLITE_LIB_PATH) $(MICROLITE_LIB_OBJS) 647 648$(BINDIR)%_test : $(OBJDIR)%_test.o $(MICROLITE_LIB_PATH) 649 @mkdir -p $(dir $@) 650 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 651 -o $@ $< \ 652 $(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS) 653 654$(BINDIR)%.test_target: $(BINDIR)%_test 655 @test -f $(TEST_SCRIPT) || (echo 'Unable to find the test script. Is the software emulation available in $(TARGET)?'; exit 1) 656 $(TEST_SCRIPT) $< $(TEST_PASS_STRING) 657 658# snease: Add %.bin rule here since BINDIR is now defined 659# These are microcontroller-specific rules for converting the ELF output 660# of the linker into a binary image that can be loaded directly. 661OBJCOPY := ${TARGET_TOOLCHAIN_ROOT}$(TARGET_TOOLCHAIN_PREFIX)objcopy 662$(BINDIR)%.bin: $(BINDIR)% 663 @mkdir -p $(dir $@) 664 $(OBJCOPY) $< $@ -O binary 665 666 667# Some tests have additional dependencies (beyond libtensorflow-microlite.a) and 668# those need to be explicitly specified with their own individual call to the 669# microlite_test helper function. For these tests, we also need to make sure to 670# not add targets for them if they have been excluded as part of the target 671# specific Makefile. 672EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/memory_arena_threshold_test.cc 673ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),) 674 MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS)) 675 EXPLICITLY_SPECIFIED_TEST_SRCS := \ 676 $(EXPLICITLY_SPECIFIED_TEST) \ 677 tensorflow/lite/micro/benchmarks/keyword_scrambled_model_data.cc \ 678 tensorflow/lite/micro/testing/test_conv_model.cc 679 EXPLICITLY_SPECIFIED_TEST_HDRS := \ 680 tensorflow/lite/micro/benchmarks/keyword_scrambled_model_data.h \ 681 tensorflow/lite/micro/testing/test_conv_model.h 682 $(eval $(call microlite_test,memory_arena_threshold_test,\ 683 $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS))) 684endif 685 686EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/micro_allocator_test.cc 687ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),) 688 MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS)) 689 EXPLICITLY_SPECIFIED_TEST_SRCS := \ 690 $(EXPLICITLY_SPECIFIED_TEST) \ 691 tensorflow/lite/micro/testing/test_conv_model.cc 692 EXPLICITLY_SPECIFIED_TEST_HDRS := \ 693 tensorflow/lite/micro/testing/test_conv_model.h 694 $(eval $(call microlite_test,micro_allocator_test,\ 695 $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS))) 696endif 697 698EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/recording_micro_allocator_test.cc 699ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),) 700 MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS)) 701 EXPLICITLY_SPECIFIED_TEST_SRCS := \ 702 $(EXPLICITLY_SPECIFIED_TEST) \ 703 tensorflow/lite/micro/testing/test_conv_model.cc 704 EXPLICITLY_SPECIFIED_TEST_HDRS := \ 705 tensorflow/lite/micro/testing/test_conv_model.h 706 $(eval $(call microlite_test,recording_micro_allocator_test,\ 707 $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS))) 708endif 709 710# For all the tests that do not have any additional dependencies, we can 711# add a make target in a common way. 712$(foreach TEST_TARGET,$(filter-out tensorflow/lite/micro/kernels/%,$(MICROLITE_TEST_SRCS)),\ 713$(eval $(call microlite_test,$(notdir $(basename $(TEST_TARGET))),$(TEST_TARGET)))) 714 715$(foreach TEST_TARGET,$(filter tensorflow/lite/micro/kernels/%,$(MICROLITE_TEST_SRCS)),\ 716$(eval $(call microlite_test,kernel_$(notdir $(basename $(TEST_TARGET))),$(TEST_TARGET)))) 717 718ifeq ($(TARGET_SPECIFIC_MAKE_TEST),0) 719test: $(MICROLITE_TEST_TARGETS) 720endif 721 722# Just build the test targets 723build: $(MICROLITE_BUILD_TARGETS) 724 725generate_projects: $(ALL_PROJECT_TARGETS) 726 727ARDUINO_PROJECT_TARGETS := $(foreach TARGET,$(ALL_PROJECT_TARGETS),$(if $(findstring _arduino,$(TARGET)),$(TARGET),)) 728 729generate_arduino_zip: $(ARDUINO_PROJECT_TARGETS) $(ARDUINO_LIBRARY_ZIPS) 730 python tensorflow/lite/micro/tools/make/merge_arduino_zips.py $(PRJDIR)/tensorflow_lite.zip $(ARDUINO_LIBRARY_ZIPS) 731 732# Gets rid of all generated files. 733clean: 734 rm -rf $(MAKEFILE_DIR)/gen 735 736# Removes third-party downloads. 737clean_downloads: 738 rm -rf $(MAKEFILE_DIR)/downloads 739 740$(DEPDIR)/%.d: ; 741.PRECIOUS: $(DEPDIR)/%.d 742.PRECIOUS: $(BINDIR)%_test 743 744-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(ALL_SRCS))) 745