Makefile 34.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
# Copyright 2021 The TensorFlow Authors. 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.
# ==============================================================================

ifneq (3.82,$(firstword $(sort $(MAKE_VERSION) 3.82)))
  $(error "Requires make version 3.82 or later (current is $(MAKE_VERSION))")
endif

# root directory of tensorflow
TENSORFLOW_ROOT :=
MAKEFILE_DIR := tensorflow/lite/micro/tools/make

#  Override this on make command line to parse third party downloads during project generation
#  make -f tensorflow/lite/micro/tools/make/Makefile PARSE_THIRD_PARTY=true TARGET=apollo3evb generate_hello_world_make_project
PARSE_THIRD_PARTY :=


# Pull in some convenience functions.
include $(MAKEFILE_DIR)/helper_functions.inc

# Try to figure out the host system
HOST_OS :=
ifeq ($(OS),Windows_NT)
	HOST_OS = windows
else
	UNAME_S := $(shell uname -s)
	ifeq ($(UNAME_S),Linux)
		HOST_OS := linux
	endif
	ifeq ($(UNAME_S),Darwin)
		HOST_OS := osx
	endif
endif

# Determine the host architecture, with any ix86 architecture being labelled x86_32
HOST_ARCH := $(shell if uname -m | grep -Eq 'i[345678]86'; then echo x86_32; else echo $(shell uname -m); fi)

# Override these on the make command line to target a specific architecture. For example:
# make -f tensorflow/lite/Makefile TARGET=rpi TARGET_ARCH=armv7l
TARGET := $(HOST_OS)
TARGET_ARCH := $(HOST_ARCH)

# Default compiler and tool names:
TOOLCHAIN:=gcc
CXX_TOOL := g++
CC_TOOL := gcc
AR_TOOL := ar

ifneq ($(TAGS),)
  $(error The TAGS command line option is no longer supported in the TFLM Makefile.)
endif

# Specify which specialized kernel implementation should be pulled in.
OPTIMIZED_KERNEL_DIR :=

67 68 69 70
# Override this variable from the command line in case the optimized kernels are
# in a different directory.
OPTIMIZED_KERNEL_DIR_PREFIX := tensorflow/lite/micro/kernels

71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
# Specify which co-processor's kernel implementation should be pulled in.
# If the same kernel is implemented in both kernels/OPTIMIZED_KERNEL_DIR and
# kernels/CO_PROCESSOR, then the implementation from kernels/CO_PROCESSOR will
# be used.
CO_PROCESSOR :=

# This is obviously horrible.  We need to generate these 3 versions of the
# include directories from one source.
INCLUDES := \
-I. \
-I$(MAKEFILE_DIR)/downloads/gemmlowp \
-I$(MAKEFILE_DIR)/downloads/flatbuffers/include \
-I$(MAKEFILE_DIR)/downloads/ruy

# Same list of paths, but now relative to the generated project files.
GENERATED_PROJECT_INCLUDES := \
-I. \
-I./third_party/gemmlowp \
-I./third_party/flatbuffers/include \
-I./third_party/ruy

# Same list of paths, but now in the format the generate_keil_project.py
# script expects them.
PROJECT_INCLUDES := \
. \
third_party/gemmlowp \
third_party/flatbuffers/include \
third_party/ruy

TEST_SCRIPT :=

MICROLITE_LIBS := -lm

# For the target, optimized_kernel_dir, and co-processor as specified on the
# command line we add -D<tag> to the cflags to allow for #idefs in the code.
#
# We apply the following transformations (via the tr command):
#   1. Convert to uppercase (TARGET=xtensa -> -DXTENSA)

ADDITIONAL_DEFINES := -D$(shell echo $(TARGET) | tr [a-z] [A-Z])

ifneq ($(OPTIMIZED_KERNEL_DIR),)
  ADDITIONAL_DEFINES += -D$(shell echo $(OPTIMIZED_KERNEL_DIR) | tr [a-z] [A-Z])
endif

ifneq ($(CO_PROCESSOR),)
  ADDITIONAL_DEFINES += -D$(shell echo $(CO_PROCESSOR) | tr [a-z] [A-Z])
endif

120 121 122 123 124 125 126 127 128
CORE_OPTIMIZATION_LEVEL := -Os
KERNEL_OPTIMIZATION_LEVEL := -O2

# Warn if deprecated optimization level is set.
OPTIMIZATION_LEVEL :=
ifneq ($(OPTIMIZATION_LEVEL),)
$(error "OPTIMIZATION_LEVEL is no longer used.")
endif

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144

CC_WARNINGS := \
  -Wsign-compare \
  -Wdouble-promotion \
  -Wshadow \
  -Wunused-variable \
  -Wmissing-field-initializers \
  -Wunused-function \
  -Wswitch \
  -Wvla \
  -Wall \
  -Wextra \
  -Wstrict-aliasing \
  -Wno-unused-parameter

COMMON_FLAGS := \
T
TFLM-bot 已提交
145
  -Werror \
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
  -fno-unwind-tables \
  -ffunction-sections \
  -fdata-sections \
  -fmessage-length=0 \
  -DTF_LITE_STATIC_MEMORY \
  -DTF_LITE_DISABLE_X86_NEON \
  $(CC_WARNINGS) \
  $(ADDITIONAL_DEFINES)

ifeq ($(TARGET), $(HOST_OS))
  # If we are not doing a cross-compilation then -DTF_LITE_USE_CTIME is what we
  # want to have by default.
  COMMON_FLAGS += -DTF_LITE_USE_CTIME
endif

CXXFLAGS := \
  -std=c++11 \
  -fno-rtti \
  -fno-exceptions \
  -fno-threadsafe-statics \
  $(COMMON_FLAGS)

CCFLAGS := \
T
TFLM-bot 已提交
169
  -Wimplicit-function-declaration \
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
  -std=c11 \
  $(COMMON_FLAGS)

ARFLAGS := -r

ifeq ($(TOOLCHAIN), gcc)
  ifneq ($(TARGET), osx)
    # GCC on MacOS uses an LLVM backend so we avoid the additional linker flags
    # that are unsupported with LLVM.
    LDFLAGS += \
      -Wl,--fatal-warnings \
      -Wl,--gc-sections
  endif
endif

# override these in the makefile.inc for specific compiler targets
TARGET_TOOLCHAIN_PREFIX :=
TARGET_TOOLCHAIN_ROOT :=

# Specifying BUILD_TYPE=<blah> as part of the make command gives us a few
# options to choose from.
#
# If BUILD_TYPE is not specified, the default build (which should be suitable
# most of the time) has all of the error checking logic at the expense of a
# latency increase of ~5-10% relative to BUILD_TYPE=release_with_logs.
#
# This default build is most suited for usual development and testing as is
# highlighted by the discussion on this github pull request:
# https://github.com/tensorflow/tensorflow/pull/42314#issuecomment-694360567
BUILD_TYPE := default
ifeq ($(BUILD_TYPE), debug)
	# Specifying BUILD_TYPE=debug adds debug symbols to the binary (and makes it
	# larger) and should be used to run a binary with gdb.
	CXXFLAGS += -g
	CCFLAGS  += -g
else ifeq ($(BUILD_TYPE), release)
	# The 'release' build results in the smallest binary (by virtue of removing
	# strings from log messages, DCHECKs ...).
	#
	# The down-side is that we currently do not have a good mechanism to allow
	# for logging that is not related to errors (e.g. profiling information, or
	# logs that help determine if tests pass or fail). As a result, we are unable
	# to run tests or benchmarks with BUILD_TYPE=release (which is a bit
	# counter-intuitive). TODO(b/158205789): A global error reporter might help.
	#
	# For a close approximation of the release build use
	# BUILD_TYPE=release_with_logs.
	CXXFLAGS += -DNDEBUG -DTF_LITE_STRIP_ERROR_STRINGS
	CCFLAGS  += -DNDEBUG -DTF_LITE_STRIP_ERROR_STRINGS
else ifeq ($(BUILD_TYPE), release_with_logs)
	# The latency with BUILD_TYPE=release_with_logs will be close to the 'release'
	# build and there will still be error logs. This build type may be preferable
	# for profiling and benchmarking.
	CXXFLAGS += -DNDEBUG
	CCFLAGS  += -DNDEBUG
else ifeq ($(BUILD_TYPE), no_tf_lite_static_memory)
	# This build should not be used to run any binaries/tests since
	# TF_LITE_STATIC_MEMORY should be defined for all micro builds. However,
	# having a build without TF_LITE_STATIC_MEMORY is useful to catch errors in
	# code that is shared between TfLite Mobile and TfLite Micro. See this issue
	# for more details:
	# https://github.com/tensorflow/tensorflow/issues/43076
	CXXFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CXXFLAGS))
	CCFLAGS := $(filter-out -DTF_LITE_STATIC_MEMORY, $(CCFLAGS))
endif

# This library is the main target for this makefile. It will contain a minimal
# runtime that can be linked in to other programs.
MICROLITE_LIB_NAME := libtensorflow-microlite.a

# These two must be defined before we include the target specific Makefile.inc
# because we filter out the examples that are not supported for those targets.
# See targets/xtensa_xpg_makefile.inc for an example.
#
# We limit max depth of directories to search to not include target specific
# Makefiles that are included directly by the main example Makefile. See
# examples/micro_speech/Makefile.inc for an example. At the same time, we
# search till an arbitrary depth for files named Makefile_internal.inc as a way
# to bypass this check and allow for deeper directory structures.
MICRO_LITE_EXAMPLE_TESTS := $(shell find tensorflow/lite/micro/examples/ -maxdepth 2 -name Makefile.inc)
250 251
# Internal examples are copied outside the TFLM repo in ../google.
MICRO_LITE_EXAMPLE_TESTS += $(shell find ../google/ -name Makefile_internal.inc)
252 253 254 255 256 257 258 259

MICRO_LITE_BENCHMARKS := $(wildcard tensorflow/lite/micro/benchmarks/Makefile.inc)

# TODO(b/152645559): move all benchmarks to benchmarks directory.
MICROLITE_BENCHMARK_SRCS := \
$(wildcard tensorflow/lite/micro/benchmarks/*benchmark.cc)

MICROLITE_TEST_SRCS := \
260
tensorflow/lite/micro/flatbuffer_utils_test.cc \
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
tensorflow/lite/micro/memory_arena_threshold_test.cc \
tensorflow/lite/micro/memory_helpers_test.cc \
tensorflow/lite/micro/micro_allocator_test.cc \
tensorflow/lite/micro/micro_error_reporter_test.cc \
tensorflow/lite/micro/micro_interpreter_test.cc \
tensorflow/lite/micro/micro_mutable_op_resolver_test.cc \
tensorflow/lite/micro/micro_string_test.cc \
tensorflow/lite/micro/micro_time_test.cc \
tensorflow/lite/micro/micro_utils_test.cc \
tensorflow/lite/micro/recording_micro_allocator_test.cc \
tensorflow/lite/micro/recording_simple_memory_allocator_test.cc \
tensorflow/lite/micro/simple_memory_allocator_test.cc \
tensorflow/lite/micro/testing_helpers_test.cc \
tensorflow/lite/micro/kernels/activations_test.cc \
tensorflow/lite/micro/kernels/add_test.cc \
tensorflow/lite/micro/kernels/add_n_test.cc \
tensorflow/lite/micro/kernels/arg_min_max_test.cc \
tensorflow/lite/micro/kernels/batch_to_space_nd_test.cc \
tensorflow/lite/micro/kernels/cast_test.cc \
tensorflow/lite/micro/kernels/ceil_test.cc \
tensorflow/lite/micro/kernels/circular_buffer_test.cc \
tensorflow/lite/micro/kernels/comparisons_test.cc \
tensorflow/lite/micro/kernels/concatenation_test.cc \
tensorflow/lite/micro/kernels/conv_test.cc \
tensorflow/lite/micro/kernels/cumsum_test.cc \
286
tensorflow/lite/micro/kernels/depth_to_space_test.cc \
287 288 289 290 291 292 293 294 295 296 297 298
tensorflow/lite/micro/kernels/depthwise_conv_test.cc \
tensorflow/lite/micro/kernels/dequantize_test.cc \
tensorflow/lite/micro/kernels/detection_postprocess_test.cc \
tensorflow/lite/micro/kernels/elementwise_test.cc \
tensorflow/lite/micro/kernels/elu_test.cc \
tensorflow/lite/micro/kernels/exp_test.cc \
tensorflow/lite/micro/kernels/expand_dims_test.cc \
tensorflow/lite/micro/kernels/fill_test.cc \
tensorflow/lite/micro/kernels/floor_test.cc \
tensorflow/lite/micro/kernels/floor_div_test.cc \
tensorflow/lite/micro/kernels/floor_mod_test.cc \
tensorflow/lite/micro/kernels/fully_connected_test.cc \
299
tensorflow/lite/micro/kernels/gather_test.cc \
300
tensorflow/lite/micro/kernels/gather_nd_test.cc \
301 302 303 304 305 306
tensorflow/lite/micro/kernels/hard_swish_test.cc \
tensorflow/lite/micro/kernels/l2norm_test.cc \
tensorflow/lite/micro/kernels/l2_pool_2d_test.cc \
tensorflow/lite/micro/kernels/leaky_relu_test.cc \
tensorflow/lite/micro/kernels/logical_test.cc \
tensorflow/lite/micro/kernels/logistic_test.cc \
307
tensorflow/lite/micro/kernels/log_softmax_test.cc \
308 309 310 311 312 313 314 315 316 317 318
tensorflow/lite/micro/kernels/maximum_minimum_test.cc \
tensorflow/lite/micro/kernels/mul_test.cc \
tensorflow/lite/micro/kernels/neg_test.cc \
tensorflow/lite/micro/kernels/pack_test.cc \
tensorflow/lite/micro/kernels/pad_test.cc \
tensorflow/lite/micro/kernels/pooling_test.cc \
tensorflow/lite/micro/kernels/prelu_test.cc \
tensorflow/lite/micro/kernels/quantization_util_test.cc \
tensorflow/lite/micro/kernels/quantize_test.cc \
tensorflow/lite/micro/kernels/reduce_test.cc \
tensorflow/lite/micro/kernels/reshape_test.cc \
319
tensorflow/lite/micro/kernels/resize_bilinear_test.cc \
320 321 322 323 324
tensorflow/lite/micro/kernels/resize_nearest_neighbor_test.cc \
tensorflow/lite/micro/kernels/round_test.cc \
tensorflow/lite/micro/kernels/shape_test.cc \
tensorflow/lite/micro/kernels/softmax_test.cc \
tensorflow/lite/micro/kernels/space_to_batch_nd_test.cc \
325
tensorflow/lite/micro/kernels/space_to_depth_test.cc \
326 327 328 329 330 331 332
tensorflow/lite/micro/kernels/split_test.cc \
tensorflow/lite/micro/kernels/split_v_test.cc \
tensorflow/lite/micro/kernels/squeeze_test.cc \
tensorflow/lite/micro/kernels/strided_slice_test.cc \
tensorflow/lite/micro/kernels/sub_test.cc \
tensorflow/lite/micro/kernels/svdf_test.cc \
tensorflow/lite/micro/kernels/tanh_test.cc \
333
tensorflow/lite/micro/kernels/transpose_test.cc \
334 335 336 337 338 339 340 341
tensorflow/lite/micro/kernels/transpose_conv_test.cc \
tensorflow/lite/micro/kernels/unpack_test.cc \
tensorflow/lite/micro/kernels/zeros_like_test.cc \
tensorflow/lite/micro/memory_planner/greedy_memory_planner_test.cc \
tensorflow/lite/micro/memory_planner/linear_memory_planner_test.cc

MICROLITE_CC_KERNEL_SRCS := \
tensorflow/lite/micro/kernels/activations.cc \
342
tensorflow/lite/micro/kernels/activations_common.cc \
343 344 345 346 347 348 349 350 351 352 353 354
tensorflow/lite/micro/kernels/add.cc \
tensorflow/lite/micro/kernels/add_n.cc \
tensorflow/lite/micro/kernels/arg_min_max.cc \
tensorflow/lite/micro/kernels/batch_to_space_nd.cc \
tensorflow/lite/micro/kernels/cast.cc \
tensorflow/lite/micro/kernels/ceil.cc \
tensorflow/lite/micro/kernels/circular_buffer.cc \
tensorflow/lite/micro/kernels/comparisons.cc \
tensorflow/lite/micro/kernels/concatenation.cc \
tensorflow/lite/micro/kernels/conv.cc \
tensorflow/lite/micro/kernels/conv_common.cc \
tensorflow/lite/micro/kernels/cumsum.cc \
355
tensorflow/lite/micro/kernels/depth_to_space.cc \
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
tensorflow/lite/micro/kernels/depthwise_conv.cc \
tensorflow/lite/micro/kernels/depthwise_conv_common.cc \
tensorflow/lite/micro/kernels/dequantize.cc \
tensorflow/lite/micro/kernels/detection_postprocess.cc \
tensorflow/lite/micro/kernels/elementwise.cc \
tensorflow/lite/micro/kernels/elu.cc \
tensorflow/lite/micro/kernels/ethosu.cc \
tensorflow/lite/micro/kernels/exp.cc \
tensorflow/lite/micro/kernels/expand_dims.cc \
tensorflow/lite/micro/kernels/fill.cc \
tensorflow/lite/micro/kernels/floor.cc \
tensorflow/lite/micro/kernels/floor_div.cc \
tensorflow/lite/micro/kernels/floor_mod.cc \
tensorflow/lite/micro/kernels/fully_connected.cc \
tensorflow/lite/micro/kernels/fully_connected_common.cc \
371
tensorflow/lite/micro/kernels/gather.cc \
372
tensorflow/lite/micro/kernels/gather_nd.cc \
373
tensorflow/lite/micro/kernels/hard_swish.cc \
C
cad-audio 已提交
374
tensorflow/lite/micro/kernels/hard_swish_common.cc \
T
TFLM-bot 已提交
375
tensorflow/lite/micro/kernels/if.cc \
376 377 378 379 380 381
tensorflow/lite/micro/kernels/kernel_runner.cc \
tensorflow/lite/micro/kernels/kernel_util.cc \
tensorflow/lite/micro/kernels/l2norm.cc \
tensorflow/lite/micro/kernels/l2_pool_2d.cc \
tensorflow/lite/micro/kernels/leaky_relu.cc \
tensorflow/lite/micro/kernels/logical.cc \
382
tensorflow/lite/micro/kernels/logical_common.cc \
383
tensorflow/lite/micro/kernels/logistic.cc \
C
cad-audio 已提交
384
tensorflow/lite/micro/kernels/logistic_common.cc \
385
tensorflow/lite/micro/kernels/log_softmax.cc \
386 387 388 389 390 391
tensorflow/lite/micro/kernels/maximum_minimum.cc \
tensorflow/lite/micro/kernels/mul.cc \
tensorflow/lite/micro/kernels/neg.cc \
tensorflow/lite/micro/kernels/pack.cc \
tensorflow/lite/micro/kernels/pad.cc \
tensorflow/lite/micro/kernels/pooling.cc \
392
tensorflow/lite/micro/kernels/pooling_common.cc \
393 394 395 396 397
tensorflow/lite/micro/kernels/prelu.cc \
tensorflow/lite/micro/kernels/quantize.cc \
tensorflow/lite/micro/kernels/quantize_common.cc \
tensorflow/lite/micro/kernels/reduce.cc \
tensorflow/lite/micro/kernels/reshape.cc \
398
tensorflow/lite/micro/kernels/resize_bilinear.cc \
399 400 401 402 403 404
tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc \
tensorflow/lite/micro/kernels/round.cc \
tensorflow/lite/micro/kernels/shape.cc \
tensorflow/lite/micro/kernels/softmax.cc \
tensorflow/lite/micro/kernels/softmax_common.cc \
tensorflow/lite/micro/kernels/space_to_batch_nd.cc \
405
tensorflow/lite/micro/kernels/space_to_depth.cc \
406 407 408 409 410 411 412 413
tensorflow/lite/micro/kernels/split.cc \
tensorflow/lite/micro/kernels/split_v.cc \
tensorflow/lite/micro/kernels/squeeze.cc \
tensorflow/lite/micro/kernels/strided_slice.cc \
tensorflow/lite/micro/kernels/sub.cc \
tensorflow/lite/micro/kernels/svdf.cc \
tensorflow/lite/micro/kernels/svdf_common.cc \
tensorflow/lite/micro/kernels/tanh.cc \
414
tensorflow/lite/micro/kernels/transpose.cc \
415 416 417 418 419 420 421
tensorflow/lite/micro/kernels/transpose_conv.cc \
tensorflow/lite/micro/kernels/unpack.cc \
tensorflow/lite/micro/kernels/zeros_like.cc

MICROLITE_TEST_HDRS := \
$(wildcard tensorflow/lite/micro/testing/*.h)

422 423 424
# The explicitly specified list of sources and headers that are shared between
# TfLite and TFLM are in the ci/sync_from_upstream_tf.sh script.
TFL_CC_SRCS := \
425
$(shell find tensorflow/lite -type d \( -path tensorflow/lite/experimental -o -path tensorflow/lite/micro \) -prune -false -o -name "*.cc" -o -name "*.c")
426 427

TFL_CC_HDRS := \
428
$(shell find tensorflow/lite -type d \( -path tensorflow/lite/experimental -o -path tensorflow/lite/micro \) -prune -false -o -name "*.h")
429

430 431 432
MICROLITE_CC_BASE_SRCS := \
$(wildcard tensorflow/lite/micro/*.cc) \
$(wildcard tensorflow/lite/micro/memory_planner/*.cc) \
433
$(TFL_CC_SRCS)
434 435 436 437 438 439 440

MICROLITE_CC_HDRS := \
$(wildcard tensorflow/lite/micro/*.h) \
$(wildcard tensorflow/lite/micro/benchmarks/*model_data.h) \
$(wildcard tensorflow/lite/micro/kernels/*.h) \
$(wildcard tensorflow/lite/micro/memory_planner/*.h) \
LICENSE \
441
$(TFL_CC_HDRS)
442

T
TFLM-bot 已提交
443 444 445 446 447 448
# Load custom kernels.
include $(MAKEFILE_DIR)/additional_kernels.inc

MICROLITE_CC_SRCS := $(filter-out $(MICROLITE_TEST_SRCS), $(MICROLITE_CC_BASE_SRCS))
MICROLITE_CC_SRCS := $(filter-out $(MICROLITE_BENCHMARK_SRCS), $(MICROLITE_CC_SRCS))

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537
# For project generation v1, the headers that are common to all targets need to
# have a third_party prefix. Other third_party headers (e.g. CMSIS) do not have
# this requirement and are added to THIRD_PARTY_CC_HDRS with full path from the
# tensorflow root. This inconsistency may also be the reason why (for
# example) these different third party libraries are fund in different paths in
# the Arduino output tree.
#
# The convention with the (under development) project generation v2 is for all
# third party paths to be relative to the root of the git repository. We are
# keeping backwards compatibility between v1 and v2 by having a
# THIRD_PARTY_CC_HDRS_BASE variable and adding in a third_party prefix to
# THIRD_PARTY_CC_HDRS later on in the Makefile logic.
# TODO(#47413): remove this additional logic once we are ready to switch over to
# project generation v2.
THIRD_PARTY_CC_HDRS :=

# TODO(b/165940489): Figure out how to avoid including fixed point
# platform-specific headers.
THIRD_PARTY_CC_HDRS_BASE := \
gemmlowp/fixedpoint/fixedpoint.h \
gemmlowp/fixedpoint/fixedpoint_neon.h \
gemmlowp/fixedpoint/fixedpoint_sse.h \
gemmlowp/internal/detect_platform.h \
gemmlowp/LICENSE \
flatbuffers/include/flatbuffers/base.h \
flatbuffers/include/flatbuffers/stl_emulation.h \
flatbuffers/include/flatbuffers/flatbuffers.h \
flatbuffers/include/flatbuffers/flexbuffers.h \
flatbuffers/include/flatbuffers/util.h \
flatbuffers/LICENSE.txt \
ruy/ruy/profiler/instrumentation.h

MAKE_PROJECT_FILES := \
  Makefile \
  README_MAKE.md \
  .vscode/tasks.json

MBED_PROJECT_FILES := \
  README_MBED.md \
  mbed-os.lib \
  mbed_app.json

KEIL_PROJECT_FILES := \
  README_KEIL.md \
  keil_project.uvprojx

ARDUINO_PROJECT_FILES := \
  library.properties

ESP_PROJECT_FILES := \
  README_ESP.md \
  CMakeLists.txt \
  main/CMakeLists.txt \
  components/tfmicro/CMakeLists.txt

ALL_PROJECT_TARGETS :=

ARDUINO_LIBRARY_TARGETS :=
ARDUINO_LIBRARY_ZIPS :=

# For some invocations of the makefile, it is useful to avoid downloads. This
# can be achieved by explicitly passing in DISABLE_DOWNLOADS=true on the command
# line. Note that for target-specific downloads (e.g. CMSIS) there will need to
# be corresponding checking in the respecitve included makefiles (e.g.
# ext_libs/cmsis_nn.inc)
DISABLE_DOWNLOADS :=

ifneq ($(DISABLE_DOWNLOADS), true)
  # The download scripts require that the downloads directory already exist for
  # improved error checking. To accomodate that, we first create a downloads
  # directory.
  $(shell mkdir -p ${MAKEFILE_DIR}/downloads)

  # Directly download the flatbuffers library.
  DOWNLOAD_RESULT := $(shell $(MAKEFILE_DIR)/flatbuffers_download.sh ${MAKEFILE_DIR}/downloads)
  ifneq ($(DOWNLOAD_RESULT), SUCCESS)
    $(error Something went wrong with the flatbuffers download: $(DOWNLOAD_RESULT))
  endif

  DOWNLOAD_RESULT := $(shell $(MAKEFILE_DIR)/pigweed_download.sh ${MAKEFILE_DIR}/downloads)
  ifneq ($(DOWNLOAD_RESULT), SUCCESS)
    $(error Something went wrong with the pigweed download: $(DOWNLOAD_RESULT))
  endif

  include $(MAKEFILE_DIR)/third_party_downloads.inc
  THIRD_PARTY_DOWNLOADS :=
  $(eval $(call add_third_party_download,$(GEMMLOWP_URL),$(GEMMLOWP_MD5),gemmlowp,))
  $(eval $(call add_third_party_download,$(RUY_URL),$(RUY_MD5),ruy,))
  $(eval $(call add_third_party_download,$(PERSON_MODEL_URL),$(PERSON_MODEL_MD5),person_model_grayscale,))
538 539 540 541
  RESULT := $(shell $(MAKEFILE_DIR)/person_detection_int8_download.sh ${MAKEFILE_DIR}/downloads $(CO_PROCESSOR))
  ifneq ($(RESULT), SUCCESS)
    $(error Something went wrong with the person detection int8 model download: $(RESULT))
  endif
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
endif

# The target-specific makefile must have a name that is exactly
# TARGET_makefile.inc and is only needed for cross-compilation (i.e. when TARGET
# is different from the HOST_OS).
# There are also some other targets like arduino and CHRE that are also special
# in that they do no have a <target>_makefile but are still used to create a
# directory for the generated artifacts. We are using a workaround right now and
# will be separating the project generation from the Makefile in the future.
TARGETS_WITHOUT_MAKEFILES := \
$(HOST_OS) \
arduino

# This specific string needs to be outputted for a test to be recognized as
# having passed.
TEST_PASS_STRING:='~~~ALL TESTS PASSED~~~'

# ${TARGET}_makefile.inc can set this to true to allow it to defined a custom
# implementation for `make test`. See bluepill_makefile as an example.
TARGET_SPECIFIC_MAKE_TEST:=0

ifeq ($(findstring $(TARGET),$(TARGETS_WITHOUT_MAKEFILES)),)
  include $(MAKEFILE_DIR)/targets/$(TARGET)_makefile.inc
endif

ifneq ($(OPTIMIZED_KERNEL_DIR),)
568 569
  PATH_TO_OPTIMIZED_KERNELS := $(OPTIMIZED_KERNEL_DIR_PREFIX)/$(OPTIMIZED_KERNEL_DIR)

570
  # Check that OPTIMIZED_KERNEL_DIR is valid to avoid unexpected fallback to
571
  # reference kernels. See http://b/183546742 for more context.
572 573 574 575 576 577 578
  RESULT := $(shell $(MAKEFILE_DIR)/check_optimized_kernel_dir.sh $(PATH_TO_OPTIMIZED_KERNELS))
  ifneq ($(RESULT), SUCCESS)
    $(error Incorrect OPTIMIZED_KERNEL_DIR: $(RESULT))
  endif

  include $(MAKEFILE_DIR)/ext_libs/$(OPTIMIZED_KERNEL_DIR).inc
  # Specialize for the optimized kernels
579
  MICROLITE_CC_KERNEL_SRCS := $(shell python3 $(MAKEFILE_DIR)/specialize_files.py \
580 581
		--base_files "$(MICROLITE_CC_KERNEL_SRCS)" \
		--specialize_directory $(PATH_TO_OPTIMIZED_KERNELS))
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
endif

# If a co-processor is specified on the command line with
# CO_PROCESSOR=<co_processor> then we will include ext_libs/<co_processor>.inc
# and find additional kernel sources in kernels/<co_processor>/
#
# That the co-processor specialization of the kernel sources happens after the
# optimized_kernel_dir means that if there is an implementation of the same
# kernel in both directories, the one from co_processor will be used.
ifneq ($(CO_PROCESSOR),)
  include $(MAKEFILE_DIR)/ext_libs/$(CO_PROCESSOR).inc
  # Specialize for the coprocessor kernels.
  MICROLITE_CC_KERNEL_SRCS := $(call substitute_specialized_implementations,$(MICROLITE_CC_KERNEL_SRCS),$(CO_PROCESSOR))
endif

# TODO(#47413): Remove this logic once we are switched over to the newer version
# of project generation (v2). Project generation v1 needs the "base" third party
# headers to have a prefix of third_party/. In order to support v2 prototyping
# without a lot of changes with the v1 system, we are manually adding in this
# prefix, and also making a copy in THIRD_PARTY_CC_HDRS_V2 that will be used in
# the list_third_party_headers target.
THIRD_PARTY_CC_HDRS_V2 := $(THIRD_PARTY_CC_HDRS)
THIRD_PARTY_CC_HDRS += $(addprefix third_party/,$(THIRD_PARTY_CC_HDRS_BASE))

# Specialize for debug_log. micro_time etc.
MICROLITE_CC_SRCS := $(call substitute_specialized_implementations,$(MICROLITE_CC_SRCS),$(TARGET))

ALL_SRCS := \
	$(MICROLITE_CC_SRCS) \
611
	$(MICROLITE_CC_KERNEL_SRCS) \
612 613
	$(MICROLITE_TEST_SRCS)

614 615 616 617 618 619 620 621 622
# Where compiled objects are stored.
GENDIR := $(MAKEFILE_DIR)/gen/$(TARGET)_$(TARGET_ARCH)_$(BUILD_TYPE)/
CORE_OBJDIR := $(GENDIR)obj/core/
KERNEL_OBJDIR := $(GENDIR)obj/kernels/
THIRD_PARTY_OBJDIR := $(GENDIR)obj/third_party/
BINDIR := $(GENDIR)bin/
LIBDIR := $(GENDIR)lib/
PRJDIR := $(GENDIR)prj/

623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
MICROLITE_LIB_PATH := $(LIBDIR)$(MICROLITE_LIB_NAME)

CXX := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${CXX_TOOL}
CC := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${CC_TOOL}
AR := $(TARGET_TOOLCHAIN_ROOT)${TARGET_TOOLCHAIN_PREFIX}${AR_TOOL}

# The default Makefile target(all) must appear before any target,
# which is compiled if there's no command-line arguments.
all: $(MICROLITE_LIB_PATH)

# Load the examples.
include $(MICRO_LITE_EXAMPLE_TESTS)

# Load the benchmarks.
include $(MICRO_LITE_BENCHMARKS)

T
TFLM-bot 已提交
639 640 641
# Load custom kernel tests.
include $(MAKEFILE_DIR)/additional_tests.inc

642 643 644 645 646
# Create rules for downloading third-party dependencies.
THIRD_PARTY_TARGETS :=
$(foreach DOWNLOAD,$(THIRD_PARTY_DOWNLOADS),$(eval $(call create_download_rule,$(DOWNLOAD))))
third_party_downloads: $(THIRD_PARTY_TARGETS)

647
MICROLITE_LIB_OBJS := $(addprefix $(CORE_OBJDIR), \
648
$(patsubst %.S,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(MICROLITE_CC_SRCS)))))
649

650
MICROLITE_THIRD_PARTY_OBJS := $(addprefix $(THIRD_PARTY_OBJDIR), \
651 652
$(patsubst %.S,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(THIRD_PARTY_CC_SRCS)))))

653 654 655
MICROLITE_KERNEL_OBJS := $(addprefix $(KERNEL_OBJDIR), \
$(patsubst %.S,%.o,$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(MICROLITE_CC_KERNEL_SRCS)))))

656
$(CORE_OBJDIR)%.o: %.cc $(THIRD_PARTY_TARGETS)
657
	@mkdir -p $(dir $@)
658
	$(CXX) $(CXXFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@
659

660
$(CORE_OBJDIR)%.o: %.c $(THIRD_PARTY_TARGETS)
661
	@mkdir -p $(dir $@)
662
	$(CC) $(CCFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@
663

664
$(CORE_OBJDIR)%.o: %.S $(THIRD_PARTY_TARGETS)
665 666 667
	@mkdir -p $(dir $@)
	$(CC) $(CCFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@

668
$(THIRD_PARTY_OBJDIR)%.o: %.cc $(THIRD_PARTY_TARGETS)
669
	@mkdir -p $(dir $@)
670
	$(CXX) $(CXXFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@
671

672 673 674
$(THIRD_PARTY_OBJDIR)%.o: %.c $(THIRD_PARTY_TARGETS)
	@mkdir -p $(dir $@)
	$(CC) $(CCFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@
675

676 677 678 679
$(THIRD_PARTY_OBJDIR)%.o: %.S $(THIRD_PARTY_TARGETS)
	@mkdir -p $(dir $@)
	$(CC) $(CCFLAGS) $(CORE_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@

680
$(KERNEL_OBJDIR)%.o: %.cc $(THIRD_PARTY_TARGETS)
681 682 683
	@mkdir -p $(dir $@)
	$(CXX) $(CXXFLAGS) $(KERNEL_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@

684
$(KERNEL_OBJDIR)%.o: %.c $(THIRD_PARTY_TARGETS)
685 686 687
	@mkdir -p $(dir $@)
	$(CC) $(CXXFLAGS) $(KERNEL_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@

688
$(KERNEL_OBJDIR)%.o: %.S $(THIRD_PARTY_TARGETS)
689 690 691
	@mkdir -p $(dir $@)
	$(CC) $(CXXFLAGS) $(KERNEL_OPTIMIZATION_LEVEL) $(INCLUDES) -c $< -o $@

692
microlite: $(MICROLITE_LIB_PATH)
693 694

# Gathers together all the objects we've compiled into a single '.a' archive.
695
$(MICROLITE_LIB_PATH): $(MICROLITE_LIB_OBJS) $(MICROLITE_KERNEL_OBJS) $(MICROLITE_THIRD_PARTY_OBJS)
696
	@mkdir -p $(dir $@)
697 698
	$(AR) $(ARFLAGS) $(MICROLITE_LIB_PATH) $(MICROLITE_LIB_OBJS) \
	$(MICROLITE_KERNEL_OBJS) $(MICROLITE_THIRD_PARTY_OBJS)
699

700
$(BINDIR)%_test : $(CORE_OBJDIR)%_test.o $(MICROLITE_LIB_PATH)
701 702 703 704 705 706 707 708 709 710 711 712
	@mkdir -p $(dir $@)
	$(CXX) $(CXXFLAGS) $(INCLUDES) \
	-o $@ $< \
	$(MICROLITE_LIB_PATH) $(LDFLAGS) $(MICROLITE_LIBS)

$(BINDIR)%.test_target: $(BINDIR)%_test
	@test -f $(TEST_SCRIPT) || (echo 'Unable to find the test script. Is the software emulation available in $(TARGET)?'; exit 1)
	$(TEST_SCRIPT) $< $(TEST_PASS_STRING)

# snease: Add %.bin rule here since BINDIR is now defined
# These are microcontroller-specific rules for converting the ELF output
# of the linker into a binary image that can be loaded directly.
713 714 715 716 717 718 719 720 721 722 723
ifeq ($(TOOLCHAIN), armclang)
  FROMELF := ${TARGET_TOOLCHAIN_ROOT}$(TARGET_TOOLCHAIN_PREFIX)fromelf
  $(BINDIR)%.bin: $(BINDIR)%
		@mkdir -p $(dir $@)
		$(FROMELF) --bin --output=$@ $<
else
  OBJCOPY := ${TARGET_TOOLCHAIN_ROOT}$(TARGET_TOOLCHAIN_PREFIX)objcopy
  $(BINDIR)%.bin: $(BINDIR)%
		@mkdir -p $(dir $@)
		$(OBJCOPY) $< $@ -O binary
endif
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796

# Some tests have additional dependencies (beyond libtensorflow-microlite.a) and
# those need to be explicitly specified with their own individual call to the
# microlite_test helper function. For these tests, we also need to make sure to
# not add targets for them if they have been excluded as part of the target
# specific Makefile.
EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/kernels/detection_postprocess_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/kernels/detection_postprocess_flexbuffers_generated_data.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/kernels/detection_postprocess_flexbuffers_generated_data.h
  $(eval $(call microlite_test,kernel_detection_postprocess_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/kernels/circular_buffer_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/kernels/circular_buffer_flexbuffers_generated_data.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/kernels/circular_buffer_flexbuffers_generated_data.h
  $(eval $(call microlite_test,kernel_circular_buffer_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/memory_arena_threshold_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/benchmarks/keyword_scrambled_model_data.cc \
  tensorflow/lite/micro/testing/test_conv_model.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/benchmarks/keyword_scrambled_model_data.h \
  tensorflow/lite/micro/testing/test_conv_model.h
  $(eval $(call microlite_test,memory_arena_threshold_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/micro_allocator_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/testing/test_conv_model.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/testing/test_conv_model.h
  $(eval $(call microlite_test,micro_allocator_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/recording_micro_allocator_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/testing/test_conv_model.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/testing/test_conv_model.h
  $(eval $(call microlite_test,recording_micro_allocator_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/kernels/conv_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
797 798
  tensorflow/lite/micro/kernels/conv_test_common.cc \
  tensorflow/lite/micro/kernels/testdata/conv_test_data.cc
799
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
800 801
  tensorflow/lite/micro/kernels/conv_test.h \
  tensorflow/lite/micro/kernels/testdata/conv_test_data.h
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
  $(eval $(call microlite_test,kernel_conv_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

EXPLICITLY_SPECIFIED_TEST:= tensorflow/lite/micro/kernels/transpose_conv_test.cc
ifneq ($(findstring $(EXPLICITLY_SPECIFIED_TEST),$(MICROLITE_TEST_SRCS)),)
  MICROLITE_TEST_SRCS := $(filter-out $(EXPLICITLY_SPECIFIED_TEST), $(MICROLITE_TEST_SRCS))
  EXPLICITLY_SPECIFIED_TEST_SRCS := \
  $(EXPLICITLY_SPECIFIED_TEST) \
  tensorflow/lite/micro/kernels/conv_test_common.cc
  EXPLICITLY_SPECIFIED_TEST_HDRS := \
  tensorflow/lite/micro/kernels/conv_test.h
  $(eval $(call microlite_test,kernel_transpose_conv_test,\
  $(EXPLICITLY_SPECIFIED_TEST_SRCS),$(EXPLICITLY_SPECIFIED_TEST_HDRS)))
endif

# For all the tests that do not have any additional dependencies, we can
# add a make target in a common way.
$(foreach TEST_TARGET,$(filter-out tensorflow/lite/micro/kernels/%,$(MICROLITE_TEST_SRCS)),\
$(eval $(call microlite_test,$(notdir $(basename $(TEST_TARGET))),$(TEST_TARGET))))

$(foreach TEST_TARGET,$(filter tensorflow/lite/micro/kernels/%,$(MICROLITE_TEST_SRCS)),\
$(eval $(call microlite_test,kernel_$(notdir $(basename $(TEST_TARGET))),$(TEST_TARGET))))



ifeq ($(TARGET_SPECIFIC_MAKE_TEST),0)
test: $(MICROLITE_TEST_TARGETS)
endif

# Just build the test targets
build: $(MICROLITE_BUILD_TARGETS)

generate_projects: $(ALL_PROJECT_TARGETS)

ARDUINO_PROJECT_TARGETS := $(foreach TARGET,$(ALL_PROJECT_TARGETS),$(if $(findstring _arduino,$(TARGET)),$(TARGET),))

generate_arduino_zip: $(ARDUINO_PROJECT_TARGETS) $(ARDUINO_LIBRARY_ZIPS)
	python tensorflow/lite/micro/tools/make/merge_arduino_zips.py $(PRJDIR)/tensorflow_lite.zip $(ARDUINO_LIBRARY_ZIPS)

list_library_sources:
843
	@echo $(MICROLITE_CC_SRCS) $(MICROLITE_CC_KERNEL_SRCS)
844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866

list_library_headers:
	@echo $(MICROLITE_CC_HDRS)

list_third_party_sources:
	@echo $(THIRD_PARTY_CC_SRCS)

list_third_party_headers:
	@echo $(addprefix $(MAKEFILE_DIR)/downloads/,$(THIRD_PARTY_CC_HDRS_BASE)) $(THIRD_PARTY_CC_HDRS_V2)

# Gets rid of all generated files.
clean:
	rm -rf $(MAKEFILE_DIR)/gen

# Removes third-party downloads.
clean_downloads:
	rm -rf $(MAKEFILE_DIR)/downloads

$(DEPDIR)/%.d: ;
.PRECIOUS: $(DEPDIR)/%.d
.PRECIOUS: $(BINDIR)%_test

-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(ALL_SRCS)))