• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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