1# Make uses /bin/sh by default, which is incompatible with the bashisms seen 2# below. 3SHELL := /bin/bash 4 5# Find where we're running from, so we can store generated files here. 6ifeq ($(origin MAKEFILE_DIR), undefined) 7 MAKEFILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 8endif 9 10# Try to figure out the host system 11HOST_OS := 12ifeq ($(OS),Windows_NT) 13 HOST_OS = windows 14else 15 UNAME_S := $(shell uname -s) 16 ifeq ($(UNAME_S),Linux) 17 HOST_OS := linux 18 endif 19 ifeq ($(UNAME_S),Darwin) 20 HOST_OS := osx 21 endif 22endif 23 24HOST_ARCH := $(shell if uname -m | grep -q i[345678]86; then echo x86_32; else uname -m; fi) 25 26# Override these on the make command line to target a specific architecture. For example: 27# make -f tensorflow/lite/tools/make/Makefile TARGET=rpi TARGET_ARCH=armv7l 28TARGET := $(HOST_OS) 29TARGET_ARCH := $(HOST_ARCH) 30 31INCLUDES := \ 32-I. \ 33-I$(MAKEFILE_DIR)/../../../../../ \ 34-I$(MAKEFILE_DIR)/../../../../../../ \ 35-I$(MAKEFILE_DIR)/downloads/ \ 36-I$(MAKEFILE_DIR)/downloads/eigen \ 37-I$(MAKEFILE_DIR)/downloads/absl \ 38-I$(MAKEFILE_DIR)/downloads/gemmlowp \ 39-I$(MAKEFILE_DIR)/downloads/ruy \ 40-I$(MAKEFILE_DIR)/downloads/neon_2_sse \ 41-I$(MAKEFILE_DIR)/downloads/farmhash/src \ 42-I$(MAKEFILE_DIR)/downloads/flatbuffers/include \ 43-I$(MAKEFILE_DIR)/downloads/fp16/include \ 44-I$(MAKEFILE_DIR)/downloads/cpuinfo \ 45-I$(MAKEFILE_DIR)/downloads/cpuinfo/include \ 46-I$(MAKEFILE_DIR)/downloads/cpuinfo/src \ 47-I$(MAKEFILE_DIR)/downloads/cpuinfo/deps/clog/include \ 48-I$(OBJDIR) 49# This is at the end so any globally-installed frameworks like protobuf don't 50# override local versions in the source tree. 51INCLUDES += -I/usr/local/include 52 53# These are the default libraries needed, but they can be added to or 54# overridden by the platform-specific settings in target makefiles. 55LIBS := \ 56-lstdc++ \ 57-lpthread \ 58-lm \ 59-lz \ 60-ldl 61 62# There are no rules for compiling objects for the host system (since we don't 63# generate things like the protobuf compiler that require that), so all of 64# these settings are for the target compiler. 65CFLAGS := -O3 -DNDEBUG -DCPU_SETSIZE=__CPU_SETSIZE -fPIC $(EXTRA_CFLAGS) 66CXXFLAGS := $(CFLAGS) --std=c++11 $(EXTRA_CXXFLAGS) 67LDOPTS := -L/usr/local/lib 68ARFLAGS := -r 69TARGET_TOOLCHAIN_PREFIX := 70CC_PREFIX := 71 72ifeq ($(HOST_OS),windows) 73CXXFLAGS += -fext-numeric-literals -D__LITTLE_ENDIAN__ 74endif 75 76ifeq ($(TARGET_ARCH),x86_64) 77 ifeq ($(TARGET),linux) 78 CXXFLAGS += -DTFLITE_HAVE_CPUINFO 79 TFLITE_HAVE_CPUINFO := true 80 endif 81endif 82 83# Auto-detect optimization opportunity if building natively. 84ifeq ($(HOST_OS),$(TARGET)) 85ifeq ($(HOST_ARCH),$(TARGET_ARCH)) 86ifeq ($(TARGET_ARCH),armv7l) 87ifneq ($(shell cat /proc/cpuinfo | grep Features | grep neon),) 88 ifneq ($(shell cat /proc/cpuinfo | grep Features | grep vfpv4),) 89 CXXFLAGS += -mfpu=neon-vfpv4 90 else 91 CXXFLAGS += -mfpu=neon 92 endif 93endif # ifeq ($(TARGET_ARCH),armv7l) 94endif # ifeq ($(HOST_ARCH),$(TARGET_ARCH)) 95endif # ifeq ($(HOST_OS),$(TARGET)) 96endif 97 98# This library is the main target for this makefile. It will contain a minimal 99# runtime that can be linked in to other programs. 100LIB_NAME := libtensorflow-lite.a 101 102# Benchmark static library and binary 103BENCHMARK_LIB_NAME := benchmark-lib.a 104BENCHMARK_BINARY_NAME := benchmark_model 105BENCHMARK_PERF_OPTIONS_BINARY_NAME := benchmark_model_performance_options 106 107# A small example program that shows how to link against the library. 108MINIMAL_SRCS := \ 109 tensorflow/lite/examples/minimal/minimal.cc 110 111LABEL_IMAGE_SRCS := \ 112 tensorflow/lite/examples/label_image/bitmap_helpers.cc \ 113 tensorflow/lite/examples/label_image/label_image.cc \ 114 tensorflow/lite/tools/evaluation/utils.cc 115 116# What sources we want to compile, must be kept in sync with the main Bazel 117# build files. 118 119PROFILER_SRCS := \ 120 tensorflow/lite/profiling/memory_info.cc \ 121 tensorflow/lite/profiling/platform_profiler.cc \ 122 tensorflow/lite/profiling/time.cc 123 124PROFILE_SUMMARIZER_SRCS := \ 125 tensorflow/lite/profiling/profile_summarizer.cc \ 126 tensorflow/lite/profiling/profile_summary_formatter.cc \ 127 tensorflow/core/util/stats_calculator.cc 128 129CMD_LINE_TOOLS_SRCS := \ 130 tensorflow/lite/tools/command_line_flags.cc \ 131 tensorflow/lite/tools/tool_params.cc 132 133CORE_CC_ALL_SRCS := \ 134$(wildcard tensorflow/lite/*.cc) \ 135$(wildcard tensorflow/lite/*.c) \ 136$(wildcard tensorflow/lite/c/*.c) \ 137$(wildcard tensorflow/lite/c/*.cc) \ 138$(wildcard tensorflow/lite/core/*.cc) \ 139$(wildcard tensorflow/lite/core/api/*.cc) \ 140$(wildcard tensorflow/lite/delegates/interpreter_utils.cc) \ 141$(wildcard tensorflow/lite/experimental/resource/*.cc) \ 142$(wildcard tensorflow/lite/schema/schema_utils.cc) \ 143$(wildcard tensorflow/lite/tools/make/downloads/ruy/ruy/*.cc) 144ifeq ($(TFLITE_HAVE_CPUINFO),true) 145CORE_CC_ALL_SRCS += \ 146$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/*.c) \ 147$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/x86/*.c) \ 148$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/x86/linux/*.c) \ 149$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/x86/cache/*.c) \ 150$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/linux/*.c) \ 151$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/deps/clog/src/*.c) 152endif 153ifneq ($(BUILD_TYPE),micro) 154CORE_CC_ALL_SRCS += \ 155$(wildcard tensorflow/lite/kernels/*.cc) \ 156$(wildcard tensorflow/lite/kernels/internal/*.cc) \ 157$(wildcard tensorflow/lite/kernels/internal/optimized/*.cc) \ 158$(wildcard tensorflow/lite/kernels/internal/reference/*.cc) \ 159$(wildcard tensorflow/lite/tools/optimize/sparsity/*.cc) \ 160$(PROFILER_SRCS) \ 161tensorflow/lite/tools/make/downloads/farmhash/src/farmhash.cc \ 162tensorflow/lite/tools/make/downloads/fft2d/fftsg.c \ 163tensorflow/lite/tools/make/downloads/fft2d/fftsg2d.c \ 164tensorflow/lite/tools/make/downloads/flatbuffers/src/util.cpp 165CORE_CC_ALL_SRCS += \ 166 $(shell find tensorflow/lite/tools/make/downloads/absl/absl/ \ 167 -type f -name \*.cc | grep -v test | grep -v benchmark | grep -v synchronization | grep -v debugging | grep -v hash | grep -v flags | grep -v random) 168endif 169# Remove any duplicates. 170CORE_CC_ALL_SRCS := $(sort $(CORE_CC_ALL_SRCS)) 171CORE_CC_EXCLUDE_SRCS := \ 172$(wildcard tensorflow/lite/*test.cc) \ 173$(wildcard tensorflow/lite/*/*test.c) \ 174$(wildcard tensorflow/lite/*/*test.cc) \ 175$(wildcard tensorflow/lite/*/*test*.cc) \ 176$(wildcard tensorflow/lite/*/*/benchmark.cc) \ 177$(wildcard tensorflow/lite/*/*/example*.cc) \ 178$(wildcard tensorflow/lite/*/*/test*.cc) \ 179$(wildcard tensorflow/lite/*/*/*test.cc) \ 180$(wildcard tensorflow/lite/*/*/*tool.cc) \ 181$(wildcard tensorflow/lite/*/*/*/benchmark.cc) \ 182$(wildcard tensorflow/lite/*/*/*/example*.cc) \ 183$(wildcard tensorflow/lite/*/*/*/test*.cc) \ 184$(wildcard tensorflow/lite/*/*/*/*test.cc) \ 185$(wildcard tensorflow/lite/*/*/*/*tool.cc) \ 186$(wildcard tensorflow/lite/*/*/*/*/*/benchmark.cc) \ 187$(wildcard tensorflow/lite/*/*/*/*/*/example*.cc) \ 188$(wildcard tensorflow/lite/*/*/*/*/*/test*.cc) \ 189$(wildcard tensorflow/lite/*/*/*/*/*/*test.cc) \ 190$(wildcard tensorflow/lite/*/*/*/*/*/*tool.cc) \ 191$(wildcard tensorflow/lite/tools/make/downloads/cpuinfo/src/*/mock*.c) \ 192tensorflow/lite/create_op_resolver_with_selected_ops.cc \ 193tensorflow/lite/tflite_with_xnnpack.cc \ 194$(MINIMAL_SRCS) 195 196BUILD_WITH_MMAP ?= true 197ifeq ($(BUILD_TYPE),micro) 198 BUILD_WITH_MMAP=false 199endif 200ifeq ($(BUILD_TYPE),windows) 201 BUILD_WITH_MMAP=false 202endif 203ifeq ($(BUILD_WITH_MMAP),true) 204 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/mmap_allocation_disabled.cc 205else 206 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/mmap_allocation.cc 207endif 208 209BUILD_WITH_RUY ?= false 210ifeq ($(TARGET_ARCH),aarch64) 211 BUILD_WITH_RUY=true 212endif 213ifeq ($(BUILD_WITH_RUY),true) 214 CXXFLAGS += -DTFLITE_WITH_RUY 215endif 216 217BUILD_WITH_RUY_PROFILER ?= false 218ifeq ($(BUILD_WITH_RUY_PROFILER),true) 219 CORE_CC_ALL_SRCS += tensorflow/lite/tools/make/downloads/ruy/ruy/profiler/instrumentation.cc 220 CORE_CC_ALL_SRCS += tensorflow/lite/tools/make/downloads/ruy/ruy/profiler/profiler.cc 221 CORE_CC_ALL_SRCS += tensorflow/lite/tools/make/downloads/ruy/ruy/profiler/treeview.cc 222 CXXFLAGS += -DRUY_PROFILER 223endif 224 225# Not to include XNNPACK. 226CXXFLAGS += -DTFLITE_WITHOUT_XNNPACK 227 228BUILD_WITH_NNAPI ?= false 229ifeq ($(BUILD_WITH_NNAPI),true) 230 CORE_CC_ALL_SRCS += tensorflow/lite/delegates/nnapi/nnapi_delegate.cc 231 CORE_CC_ALL_SRCS += tensorflow/lite/delegates/nnapi/quant_lstm_sup.cc 232 CORE_CC_ALL_SRCS += tensorflow/lite/nnapi/nnapi_implementation.cc 233 CORE_CC_ALL_SRCS += tensorflow/lite/nnapi/nnapi_util.cc 234 LIBS += -lrt 235else 236 CORE_CC_ALL_SRCS += tensorflow/lite/delegates/nnapi/nnapi_delegate_disabled.cc 237 CORE_CC_ALL_SRCS += tensorflow/lite/nnapi/nnapi_implementation_disabled.cc 238endif 239 240ifeq ($(TARGET),ios) 241 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/minimal_logging_android.cc 242 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/minimal_logging_default.cc 243else 244 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/minimal_logging_android.cc 245 CORE_CC_EXCLUDE_SRCS += tensorflow/lite/minimal_logging_ios.cc 246endif 247 248# Filter out all the excluded files. 249TF_LITE_CC_SRCS := $(filter-out $(CORE_CC_EXCLUDE_SRCS), $(CORE_CC_ALL_SRCS)) 250 251# Benchmark sources 252BENCHMARK_SRCS_DIR := tensorflow/lite/tools/benchmark 253DELEGATE_PROVIDER_SRCS_DIR := tensorflow/lite/tools/delegates 254EVALUATION_UTILS_SRCS := \ 255 tensorflow/lite/tools/evaluation/utils.cc 256BENCHMARK_ALL_SRCS := \ 257 $(wildcard $(BENCHMARK_SRCS_DIR)/*.cc) \ 258 $(PROFILE_SUMMARIZER_SRCS) \ 259 $(CMD_LINE_TOOLS_SRCS) \ 260 $(EVALUATION_UTILS_SRCS) 261 262BENCHMARK_MAIN_SRC := $(BENCHMARK_SRCS_DIR)/benchmark_main.cc 263BENCHMARK_PERF_OPTIONS_SRC := \ 264 $(BENCHMARK_SRCS_DIR)/benchmark_tflite_performance_options_main.cc 265BENCHMARK_LIB_SRCS := $(filter-out \ 266 $(wildcard $(BENCHMARK_SRCS_DIR)/*_test.cc) \ 267 $(BENCHMARK_MAIN_SRC) \ 268 $(BENCHMARK_PERF_OPTIONS_SRC) \ 269 $(BENCHMARK_SRCS_DIR)/benchmark_plus_flex_main.cc \ 270 $(DELEGATE_PROVIDER_SRCS_DIR)/default_execution_provider.cc \ 271 $(DELEGATE_PROVIDER_SRCS_DIR)/external_delegate_provider.cc \ 272 $(DELEGATE_PROVIDER_SRCS_DIR)/gpu_delegate_provider.cc \ 273 $(DELEGATE_PROVIDER_SRCS_DIR)/hexagon_delegate_provider.cc \ 274 $(DELEGATE_PROVIDER_SRCS_DIR)/nnapi_delegate_provider.cc \ 275 $(DELEGATE_PROVIDER_SRCS_DIR)/xnnpack_delegate_provider.cc, \ 276 $(BENCHMARK_ALL_SRCS)) 277 278# These target-specific makefiles should modify or replace options like 279# CXXFLAGS or LIBS to work for a specific targeted architecture. All logic 280# based on platforms or architectures should happen within these files, to 281# keep this main makefile focused on the sources and dependencies. 282include $(wildcard $(MAKEFILE_DIR)/targets/*_makefile.inc) 283 284ALL_SRCS := \ 285 $(MINIMAL_SRCS) \ 286 $(PROFILER_SRCS) \ 287 $(PROFILER_SUMMARIZER_SRCS) \ 288 $(TF_LITE_CC_SRCS) \ 289 $(BENCHMARK_LIB_SRCS) \ 290 $(CMD_LINE_TOOLS_SRCS) 291 292# Where compiled objects are stored. 293TARGET_OUT_DIR ?= $(TARGET)_$(TARGET_ARCH) 294GENDIR := $(MAKEFILE_DIR)/gen/$(TARGET_OUT_DIR)/ 295OBJDIR := $(GENDIR)obj/ 296BINDIR := $(GENDIR)bin/ 297LIBDIR := $(GENDIR)lib/ 298 299LIB_PATH := $(LIBDIR)$(LIB_NAME) 300BENCHMARK_LIB := $(LIBDIR)$(BENCHMARK_LIB_NAME) 301BENCHMARK_BINARY := $(BINDIR)$(BENCHMARK_BINARY_NAME) 302BENCHMARK_PERF_OPTIONS_BINARY := $(BINDIR)$(BENCHMARK_PERF_OPTIONS_BINARY_NAME) 303MINIMAL_BINARY := $(BINDIR)minimal 304LABEL_IMAGE_BINARY := $(BINDIR)label_image 305 306CXX := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}g++ 307CC := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}gcc 308AR := $(CC_PREFIX)${TARGET_TOOLCHAIN_PREFIX}ar 309 310MINIMAL_OBJS := $(addprefix $(OBJDIR), \ 311$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(MINIMAL_SRCS)))) 312 313LABEL_IMAGE_OBJS := $(addprefix $(OBJDIR), \ 314$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(LABEL_IMAGE_SRCS) $(CMD_LINE_TOOLS_SRCS)))) 315 316LIB_OBJS := $(addprefix $(OBJDIR), \ 317$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(TF_LITE_CC_SRCS))))) 318 319BENCHMARK_MAIN_OBJ := $(addprefix $(OBJDIR), \ 320$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(BENCHMARK_MAIN_SRC)))) 321 322BENCHMARK_PERF_OPTIONS_OBJ := $(addprefix $(OBJDIR), \ 323$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(BENCHMARK_PERF_OPTIONS_SRC)))) 324 325BENCHMARK_LIB_OBJS := $(addprefix $(OBJDIR), \ 326$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(BENCHMARK_LIB_SRCS)))) 327 328# For normal manually-created TensorFlow Lite C++ source files. 329$(OBJDIR)%.o: %.cpp 330 @mkdir -p $(dir $@) 331 $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ 332 333$(OBJDIR)%.o: %.cc 334 @mkdir -p $(dir $@) 335 $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ 336 337# For normal manually-created TensorFlow Lite C source files. 338$(OBJDIR)%.o: %.c 339 @mkdir -p $(dir $@) 340 $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ 341 342# The target that's compiled if there's no command-line arguments. 343all: $(LIB_PATH) $(MINIMAL_BINARY) $(BENCHMARK_BINARY) $(BENCHMARK_PERF_OPTIONS_BINARY) 344 345# The target that's compiled for micro-controllers 346micro: $(LIB_PATH) 347 348# Hack for generating schema files bypassing flatbuffer parsing 349tensorflow/lite/schema/schema_generated.h: 350 @cp -u tensorflow/lite/schema/schema_generated.h.oss tensorflow/lite/schema/schema_generated.h 351 @cp -u tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h.oss tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h 352 353# Gathers together all the objects we've compiled into a single '.a' archive. 354$(LIB_PATH): tensorflow/lite/schema/schema_generated.h $(LIB_OBJS) 355 @mkdir -p $(dir $@) 356 $(AR) $(ARFLAGS) $(LIB_PATH) $(LIB_OBJS) 357$(LIB_PATH): tensorflow/lite/experimental/acceleration/configuration/configuration_generated.h $(LIB_OBJS) 358 @mkdir -p $(dir $@) 359 $(AR) $(ARFLAGS) $(LIB_PATH) $(LIB_OBJS) 360 361lib: $(LIB_PATH) 362 363$(MINIMAL_BINARY): $(MINIMAL_OBJS) $(LIB_PATH) 364 @mkdir -p $(dir $@) 365 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 366 -o $(MINIMAL_BINARY) $(MINIMAL_OBJS) \ 367 $(LIBFLAGS) $(LIB_PATH) $(LDFLAGS) $(LIBS) 368 369minimal: $(MINIMAL_BINARY) 370 371$(LABEL_IMAGE_BINARY): $(LABEL_IMAGE_OBJS) $(LIB_PATH) 372 @mkdir -p $(dir $@) 373 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 374 -o $(LABEL_IMAGE_BINARY) $(LABEL_IMAGE_OBJS) \ 375 $(LIBFLAGS) $(LIB_PATH) $(LDFLAGS) $(LIBS) 376 377label_image: $(LABEL_IMAGE_BINARY) 378 379$(BENCHMARK_LIB) : $(LIB_PATH) $(BENCHMARK_LIB_OBJS) 380 @mkdir -p $(dir $@) 381 $(AR) $(ARFLAGS) $(BENCHMARK_LIB) $(LIB_OBJS) $(BENCHMARK_LIB_OBJS) 382 383benchmark_lib: $(BENCHMARK_LIB) 384 385BENCHMARK_LINKOPTS := 386ifeq ($(HOST_OS),osx) 387 BENCHMARK_LINKOPTS += $(LIBFLAGS) -Wl,-force_load $(BENCHMARK_LIB) $(LIBS) $(LDFLAGS) -framework CoreFoundation 388else 389 BENCHMARK_LINKOPTS += $(LIBFLAGS) -Wl,--whole-archive $(BENCHMARK_LIB) -Wl,--no-whole-archive $(LDFLAGS) $(LIBS) 390endif 391 392$(BENCHMARK_BINARY) : $(BENCHMARK_MAIN_OBJ) $(BENCHMARK_LIB) 393 @mkdir -p $(dir $@) 394 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 395 -o $(BENCHMARK_BINARY) $(BENCHMARK_MAIN_OBJ) \ 396 $(LIBFLAGS) $(BENCHMARK_LINKOPTS) 397 398$(BENCHMARK_PERF_OPTIONS_BINARY) : $(BENCHMARK_PERF_OPTIONS_OBJ) $(BENCHMARK_LIB) 399 @mkdir -p $(dir $@) 400 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 401 -o $(BENCHMARK_PERF_OPTIONS_BINARY) $(BENCHMARK_PERF_OPTIONS_OBJ) \ 402 $(LIBFLAGS) $(BENCHMARK_LIB) $(LDFLAGS) $(LIBS) 403 404benchmark: $(BENCHMARK_BINARY) $(BENCHMARK_PERF_OPTIONS_BINARY) 405 406libdir: 407 @echo $(LIBDIR) 408 409# Gets rid of all generated files. 410clean: 411 rm -rf $(MAKEFILE_DIR)/gen 412 413# Gets rid of target files only, leaving the host alone. Also leaves the lib 414# directory untouched deliberately, so we can persist multiple architectures 415# across builds for iOS and Android. 416cleantarget: 417 rm -rf $(OBJDIR) 418 rm -rf $(BINDIR) 419 420$(DEPDIR)/%.d: ; 421.PRECIOUS: $(DEPDIR)/%.d 422 423-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(ALL_SRCS))) 424