1# This Makefile compiles a library containing the C++ runtime for the TensorFlow 2# library. It's designed for use on platforms with limited resources where 3# running a full Bazel build would be prohibitive, or for cross-compilation onto 4# embedded systems. It includes only a bare-bones set of functionality. 5# 6# The default setup below is aimed at Unix-like devices, and should work on 7# modern Linux and OS X distributions without changes. 8# 9# If you have another platform, you'll need to take a careful look at the 10# compiler flags and folders defined below. They're separated into two sections, 11# the first for the host (the machine you're compiling on) and the second for 12# the target (the machine you want the program to run on). 13 14SHELL := /bin/bash 15 16# Host compilation settings 17 18# Find where we're running from, so we can store generated files here. 19ifeq ($(origin MAKEFILE_DIR), undefined) 20 MAKEFILE_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 21endif 22 23HAS_GEN_HOST_PROTOC := \ 24$(shell test -f $(MAKEFILE_DIR)/gen/protobuf-host/bin/protoc && echo "true" ||\ 25echo "false") 26 27# Hexagon integration 28ifdef HEXAGON_LIBS 29 LIBGEMM_WRAPPER := $(HEXAGON_LIBS)/libhexagon_controller.so 30 ifeq ($(shell test -f $(LIBGEMM_WRAPPER) 2> /dev/null; echo $$?), 0) 31 $(info "Use hexagon libs at " $(LIBGEMM_WRAPPER)) 32 else 33 $(error "hexagon libs not found at " $(LIBGEMM_WRAPPER)) 34 endif 35 ifdef HEXAGON_INCLUDE 36 ifeq ($(shell test -d $(HEXAGON_INCLUDE) 2> /dev/null; echo $$?), 0) 37 $(info "Use hexagon libs at " $(HEXAGON_INCLUDE)) 38 else 39 $(error "hexagon libs not found at " $(HEXAGON_INCLUDE)) 40 endif 41 else 42 $(error "HEXAGON_INCLUDE is not set.") 43 endif 44 ifneq ($(TARGET),ANDROID) 45 $(error "hexagon is only supported on Android") 46 endif 47endif # HEXAGON_LIBS 48 49# If ANDROID_TYPES is not set assume __ANDROID_TYPES_SLIM__ 50ifeq ($(ANDROID_TYPES),) 51 ANDROID_TYPES := -D__ANDROID_TYPES_SLIM__ 52endif 53 54# Try to figure out the host system 55HOST_OS := 56ifeq ($(OS),Windows_NT) 57 HOST_OS = WINDOWS 58else 59 UNAME_S := $(shell uname -s) 60 ifeq ($(UNAME_S),Linux) 61 HOST_OS := LINUX 62 endif 63 ifeq ($(UNAME_S),Darwin) 64 HOST_OS := OSX 65 endif 66endif 67 68HOST_ARCH := $(shell if [[ $(shell uname -m) =~ i[345678]86 ]]; then echo x86_32; else echo $(shell uname -m); fi) 69 70# Where compiled objects are stored. 71HOST_OBJDIR := $(MAKEFILE_DIR)/gen/host_obj/ 72HOST_BINDIR := $(MAKEFILE_DIR)/gen/host_bin/ 73HOST_GENDIR := $(MAKEFILE_DIR)/gen/host_obj/ 74 75# Settings for the host compiler. 76HOST_CXX := $(CC_PREFIX) gcc 77HOST_CXXFLAGS := --std=c++11 78HOST_LDOPTS := 79ifeq ($(HAS_GEN_HOST_PROTOC),true) 80 HOST_LDOPTS += -L$(MAKEFILE_DIR)/gen/protobuf-host/lib 81endif 82HOST_LDOPTS += -L/usr/local/lib 83 84HOST_INCLUDES := \ 85-I. \ 86-I$(MAKEFILE_DIR)/../../../ \ 87-I$(MAKEFILE_DIR)/downloads/ \ 88-I$(MAKEFILE_DIR)/downloads/eigen \ 89-I$(MAKEFILE_DIR)/downloads/gemmlowp \ 90-I$(MAKEFILE_DIR)/downloads/nsync/public \ 91-I$(MAKEFILE_DIR)/downloads/fft2d \ 92-I$(MAKEFILE_DIR)/downloads/double_conversion \ 93-I$(MAKEFILE_DIR)/downloads/absl \ 94-I$(HOST_GENDIR) 95ifeq ($(HAS_GEN_HOST_PROTOC),true) 96 HOST_INCLUDES += -I$(MAKEFILE_DIR)/gen/protobuf-host/include 97endif 98# This is at the end so any globally-installed frameworks like protobuf don't 99# override local versions in the source tree. 100HOST_INCLUDES += -I/usr/local/include 101 102HOST_LIBS := \ 103$(HOST_NSYNC_LIB) \ 104-lstdc++ \ 105-lprotobuf \ 106-lpthread \ 107-lm \ 108-lz 109 110# If we're on Linux, also link in the dl library. 111ifeq ($(HOST_OS),LINUX) 112 HOST_LIBS += -ldl -lpthread 113endif 114 115# If we're on a Pi, link in pthreads and dl 116ifeq ($(HOST_OS),PI) 117 HOST_LIBS += -ldl -lpthread 118endif 119 120# Abseil sources. 121ABSL_CC_ALL_SRCS := \ 122$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*.cc) \ 123$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*.cc) \ 124$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*.cc) \ 125$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*/*.cc) 126 127ABSL_CC_EXCLUDE_SRCS := \ 128$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*test*.cc) \ 129$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*test*.cc) \ 130$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*test*.cc) \ 131$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*/*test*.cc) \ 132$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*benchmark*.cc) \ 133$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*benchmark*.cc) \ 134$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*benchmark*.cc) \ 135$(wildcard tensorflow/contrib/makefile/downloads/absl/absl/*/*/*/*/*benchmark*.cc) \ 136tensorflow/contrib/makefile/downloads/absl/absl/synchronization/internal/mutex_nonprod.cc \ 137tensorflow/contrib/makefile/downloads/absl/absl/hash/internal/print_hash_of.cc 138 139ABSL_CC_SRCS := $(filter-out $(ABSL_CC_EXCLUDE_SRCS), $(ABSL_CC_ALL_SRCS)) 140 141# proto_text is a tool that converts protobufs into a form we can use more 142# compactly within TensorFlow. It's a bit like protoc, but is designed to 143# produce a much more minimal result so we can save binary space. 144# We have to build it on the host system first so that we can create files 145# that are needed for the runtime building. 146PROTO_TEXT := $(HOST_BINDIR)proto_text 147# The list of dependencies is derived from the Bazel build file by running 148# the gen_file_lists.sh script on a system with a working Bazel setup. 149PROTO_TEXT_CC_FILES := \ 150 $(ABSL_CC_SRCS) \ 151 $(shell cat $(MAKEFILE_DIR)/proto_text_cc_files.txt) 152PROTO_TEXT_PB_CC_LIST := \ 153 $(shell cat $(MAKEFILE_DIR)/proto_text_pb_cc_files.txt) \ 154 $(wildcard tensorflow/contrib/makefile/downloads/double_conversion/double-conversion/*.cc) 155PROTO_TEXT_PB_H_LIST := $(shell cat $(MAKEFILE_DIR)/proto_text_pb_h_files.txt) 156 157# Locations of the intermediate files proto_text generates. 158PROTO_TEXT_PB_H_FILES := $(addprefix $(HOST_GENDIR), $(PROTO_TEXT_PB_H_LIST)) 159PROTO_TEXT_CC_OBJS := $(addprefix $(HOST_OBJDIR), $(PROTO_TEXT_CC_FILES:.cc=.o)) 160PROTO_TEXT_PB_OBJS := $(addprefix $(HOST_OBJDIR), $(PROTO_TEXT_PB_CC_LIST:.cc=.o)) 161PROTO_TEXT_OBJS := $(PROTO_TEXT_CC_OBJS) $(PROTO_TEXT_PB_OBJS) 162 163# Target device settings. 164 165# Default to running on the same system we're compiling on. 166# You should override TARGET on the command line if you're cross-compiling, e.g. 167# make -f tensorflow/contrib/makefile/Makefile TARGET=ANDROID 168TARGET := $(HOST_OS) 169 170# Where compiled objects are stored. 171GENDIR := $(MAKEFILE_DIR)/gen/ 172OBJDIR := $(GENDIR)obj/ 173LIBDIR := $(GENDIR)lib/ 174BINDIR := $(GENDIR)bin/ 175PBTGENDIR := $(GENDIR)proto_text/ 176PROTOGENDIR := $(GENDIR)proto/ 177DEPDIR := $(GENDIR)dep/ 178$(shell mkdir -p $(DEPDIR) >/dev/null) 179 180# Settings for the target compiler. 181CXX := $(CC_PREFIX) gcc 182OPTFLAGS := -O2 183 184ifneq ($(TARGET),ANDROID) 185 OPTFLAGS += -march=native 186endif 187 188CXXFLAGS := --std=c++11 -DIS_SLIM_BUILD -fno-exceptions -DNDEBUG $(OPTFLAGS) 189LDFLAGS := \ 190-L/usr/local/lib 191DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td 192 193INCLUDES := \ 194-I. \ 195-I$(MAKEFILE_DIR)/downloads/ \ 196-I$(MAKEFILE_DIR)/downloads/eigen \ 197-I$(MAKEFILE_DIR)/downloads/gemmlowp \ 198-I$(MAKEFILE_DIR)/downloads/nsync/public \ 199-I$(MAKEFILE_DIR)/downloads/fft2d \ 200-I$(MAKEFILE_DIR)/downloads/double_conversion \ 201-I$(MAKEFILE_DIR)/downloads/absl \ 202-I$(PROTOGENDIR) \ 203-I$(PBTGENDIR) 204ifeq ($(HAS_GEN_HOST_PROTOC),true) 205 INCLUDES += -I$(MAKEFILE_DIR)/gen/protobuf-host/include 206endif 207# This is at the end so any globally-installed frameworks like protobuf don't 208# override local versions in the source tree. 209INCLUDES += -I/usr/local/include 210 211# If `$(WITH_TFLITE_FLEX)` is `true`, this Makefile will build a library 212# for TensorFlow Lite Flex runtime. 213# Farmhash and Flatbuffer is required for TensorFlow Lite Flex runtime. 214ifeq ($(WITH_TFLITE_FLEX), true) 215 HOST_INCLUDES += -I$(MAKEFILE_DIR)/downloads/farmhash/src 216 HOST_INCLUDES += -I$(MAKEFILE_DIR)/downloads/flatbuffers/include 217 INCLUDES += -I$(MAKEFILE_DIR)/downloads/farmhash/src 218 INCLUDES += -I$(MAKEFILE_DIR)/downloads/flatbuffers/include 219endif 220 221LIBS := \ 222$(TARGET_NSYNC_LIB) \ 223-lstdc++ \ 224-lprotobuf \ 225-lz \ 226-lm 227 228ifeq ($(HAS_GEN_HOST_PROTOC),true) 229 PROTOC := $(MAKEFILE_DIR)/gen/protobuf-host/bin/protoc 230else 231 PROTOC := protoc 232endif 233 234$(info PROTOC = "$(PROTOC)") 235$(info CC_PREFIX = "$(CC_PREFIX)") 236 237PROTOCFLAGS := 238AR := ar 239ARFLAGS := -r 240LIBFLAGS := 241 242# If we're on OS X, make sure that globals aren't stripped out. 243ifeq ($(TARGET),OSX) 244ifeq ($(HAS_GEN_HOST_PROTOC),true) 245 LIBFLAGS += -L$(MAKEFILE_DIR)/gen/protobuf-host/lib 246 export LD_LIBRARY_PATH=$(MAKEFILE_DIR)/gen/protobuf-host/lib 247endif 248 LDFLAGS += -all_load 249endif 250# Make sure that we don't strip global constructors on Linux. 251ifeq ($(TARGET),LINUX) 252ifeq ($(HAS_GEN_HOST_PROTOC),true) 253 LIBFLAGS += -L$(MAKEFILE_DIR)/gen/protobuf-host/lib 254 export LD_LIBRARY_PATH=$(MAKEFILE_DIR)/gen/protobuf-host/lib 255endif 256 CXXFLAGS += -fPIC 257 LIBFLAGS += -Wl,--allow-multiple-definition -Wl,--whole-archive 258 LDFLAGS := -Wl,--no-whole-archive 259endif 260# If we're on Linux, also link in the dl library. 261ifeq ($(TARGET),LINUX) 262 LIBS += -ldl -lpthread 263endif 264# If we're cross-compiling for the Raspberry Pi, use the right gcc. 265ifeq ($(TARGET),PI) 266 CXXFLAGS += $(ANDROID_TYPES) -DRASPBERRY_PI 267 LDFLAGS := -Wl,--no-whole-archive 268 LIBS += -ldl -lpthread 269 LIBFLAGS += -Wl,--allow-multiple-definition -Wl,--whole-archive 270endif 271 272# Set up Android building 273ifeq ($(TARGET),ANDROID) 274# Override NDK_ROOT on the command line with your own NDK location, e.g. 275# make -f tensorflow/contrib/makefile/Makefile TARGET=ANDROID \ 276# NDK_ROOT=/path/to/your/ndk 277# You need to have an Android version of the protobuf libraries compiled to link 278# in. The compile_android_protobuf.sh script may help. 279 280 ANDROID_HOST_OS_ARCH := 281 ifeq ($(HOST_OS),LINUX) 282 ANDROID_HOST_OS_ARCH=linux 283 endif 284 ifeq ($(HOST_OS),OSX) 285 ANDROID_HOST_OS_ARCH=darwin 286 endif 287 ifeq ($(HOST_OS),WINDOWS) 288 $(error "windows is not supported.") 289 endif 290 291 ifeq ($(HOST_ARCH),x86_32) 292 ANDROID_HOST_OS_ARCH := $(ANDROID_HOST_OS_ARCH)-x86 293 else 294 ANDROID_HOST_OS_ARCH := $(ANDROID_HOST_OS_ARCH)-$(HOST_ARCH) 295 endif 296 297 ifndef ANDROID_ARCH 298 ANDROID_ARCH := armeabi-v7a 299 endif 300 301 ifeq ($(ANDROID_ARCH),arm64-v8a) 302 TOOLCHAIN := aarch64-linux-android-4.9 303 SYSROOT_ARCH := arm64 304 BIN_PREFIX := aarch64-linux-android 305 MARCH_OPTION := 306 endif 307 ifeq ($(ANDROID_ARCH),armeabi) 308 TOOLCHAIN := arm-linux-androideabi-4.9 309 SYSROOT_ARCH := arm 310 BIN_PREFIX := arm-linux-androideabi 311 MARCH_OPTION := 312 endif 313 ifeq ($(ANDROID_ARCH),armeabi-v7a) 314 TOOLCHAIN := arm-linux-androideabi-4.9 315 SYSROOT_ARCH := arm 316 BIN_PREFIX := arm-linux-androideabi 317 MARCH_OPTION := -march=armv7-a -mfloat-abi=softfp -mfpu=neon 318 endif 319 ifeq ($(ANDROID_ARCH),mips) 320 TOOLCHAIN := mipsel-linux-android-4.9 321 SYSROOT_ARCH := mips 322 BIN_PREFIX := mipsel-linux-android 323 MARCH_OPTION := 324 endif 325 ifeq ($(ANDROID_ARCH),mips64) 326 TOOLCHAIN := mips64el-linux-android-4.9 327 SYSROOT_ARCH := mips64 328 BIN_PREFIX := mips64el-linux-android 329 MARCH_OPTION := 330 endif 331 ifeq ($(ANDROID_ARCH),x86) 332 TOOLCHAIN := x86-4.9 333 SYSROOT_ARCH := x86 334 BIN_PREFIX := i686-linux-android 335 MARCH_OPTION := 336 endif 337 ifeq ($(ANDROID_ARCH),x86_64) 338 TOOLCHAIN := x86_64-4.9 339 SYSROOT_ARCH := x86_64 340 BIN_PREFIX := x86_64-linux-android 341 MARCH_OPTION := 342 endif 343 344 ifndef NDK_ROOT 345 $(error "NDK_ROOT is not defined.") 346 endif 347 CXX := $(CC_PREFIX) $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-g++ 348 CC := $(CC_PREFIX) $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-gcc 349 CXXFLAGS +=\ 350--sysroot $(NDK_ROOT)/platforms/android-21/arch-$(SYSROOT_ARCH) \ 351-Wno-narrowing \ 352-fomit-frame-pointer \ 353$(MARCH_OPTION) \ 354-fPIE \ 355-fPIC 356 INCLUDES = \ 357-I$(NDK_ROOT)/sources/android/support/include \ 358-I$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/include \ 359-I$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(ANDROID_ARCH)/include \ 360-I. \ 361-I$(MAKEFILE_DIR)/downloads/ \ 362-I$(MAKEFILE_DIR)/downloads/eigen \ 363-I$(MAKEFILE_DIR)/downloads/gemmlowp \ 364-I$(MAKEFILE_DIR)/downloads/nsync/public \ 365-I$(MAKEFILE_DIR)/downloads/fft2d \ 366-I$(MAKEFILE_DIR)/downloads/double_conversion \ 367-I$(MAKEFILE_DIR)/downloads/absl \ 368-I$(MAKEFILE_DIR)/gen/protobuf_android/$(ANDROID_ARCH)/include \ 369-I$(PROTOGENDIR) \ 370-I$(PBTGENDIR) 371 372 LIBS := \ 373$(TARGET_NSYNC_LIB) \ 374-lgnustl_static \ 375-lprotobuf \ 376-llog \ 377-lz \ 378-lm \ 379-ldl \ 380-latomic 381 382 LD := $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/$(BIN_PREFIX)/bin/ld 383 384 LDFLAGS := \ 385$(MARCH_OPTION) \ 386-L$(MAKEFILE_DIR)/gen/protobuf_android/$(ANDROID_ARCH)/lib \ 387-L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(ANDROID_ARCH) \ 388-fPIE \ 389-pie \ 390-v 391 392 AR := $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-ar 393 ARFLAGS := r 394 LIBFLAGS += -Wl,--allow-multiple-definition -Wl,--whole-archive 395 396 ifdef HEXAGON_LIBS 397 INCLUDES += -I$(HEXAGON_INCLUDE) 398 LIBS += -lhexagon_controller 399 LDFLAGS += -L$(HEXAGON_LIBS) 400 CXXFLAGS += -DUSE_HEXAGON_LIBS 401 402# CAVEAT: We should disable TENSORFLOW_DISABLE_META while running 403# quantized_matmul on Android because it crashes in 404# MultiThreadGemm in tensorflow/core/kernels/meta_support.cc 405# See http://b/33270149 406# TODO(satok): Remove once it's fixed 407 CXXFLAGS += -DTENSORFLOW_DISABLE_META 408 409# Declare __ANDROID_TYPES_FULL__ to enable required types for hvx 410 CXXFLAGS += -D__ANDROID_TYPES_FULL__ 411 endif 412 413 ifdef ENABLE_EXPERIMENTAL_HEXNN_OPS 414 CXXFLAGS += -DENABLE_EXPERIMENTAL_HEXNN_OPS 415 endif 416 417 ifeq ($(BUILD_FOR_TEGRA),1) 418 NVCC := $(JETPACK)/cuda/bin/nvcc 419 NVCCFLAGS := -x=cu -D__CUDACC__ -DNVCC -DANDROID_TEGRA -ccbin $(NDK_ROOT)/toolchains/$(TOOLCHAIN)/prebuilt/$(ANDROID_HOST_OS_ARCH)/bin/$(BIN_PREFIX)-g++ --std c++11 --expt-relaxed-constexpr -m64 -gencode arch=compute_53,\"code=sm_53\" -gencode arch=compute_62,\"code=sm_62\" -DEIGEN_AVOID_STL_ARRAY -DTENSORFLOW_USE_EIGEN_THREADPOOL -DLANG_CXX11 -DEIGEN_HAS_C99_MATH -DGOOGLE_CUDA=1 -DTF_EXTRA_CUDA_CAPABILITIES=5.3 420 CXXFLAGS4NVCC =\ 421-DIS_SLIM_BUILD \ 422-DANDROID_TEGRA \ 423-fno-exceptions \ 424-DNDEBUG $(OPTFLAGS) \ 425-march=armv8-a \ 426-fPIE \ 427-D__ANDROID_TYPES_FULL__ \ 428--sysroot $(NDK_ROOT)/platforms/android-21/arch-arm64 429 430 CXXFLAGS +=\ 431-DGOOGLE_CUDA=1 \ 432-D__ANDROID_TYPES_FULL__ \ 433-DANDROID_TEGRA \ 434-DEIGEN_AVOID_STL_ARRAY \ 435-DEIGEN_HAS_C99_MATH \ 436-DLANG_CXX11 -DTENSORFLOW_USE_EIGEN_THREADPOOL -DTF_EXTRA_CUDA_CAPABILITIES=5.3 437 438 INCLUDES += \ 439-Itensorflow/core/kernels \ 440-I$(MAKEFILE_DIR)/downloads/cub \ 441-I$(MAKEFILE_DIR)/downloads/cub/cub_archive/cub/device \ 442-I$(JETPACK)/cuda/include \ 443-I$(JETPACK) \ 444-I$(JETPACK)/cuDNN/aarch64 \ 445-I$(JETPACK)/cuda/extras/CUPTI/include 446 447 448 CUDA_LIBS := \ 449-ltfcuda \ 450-lcudart_static \ 451-lcudnn \ 452-lcublas_static \ 453-lcufftw_static \ 454-lcusolver_static \ 455-lcusparse_static \ 456-lcufft \ 457-lcuda \ 458-lculibos \ 459-lcurand_static 460 461 OBJDIR := $(OBJDIR)android_arm64-v8a/ 462 LIBDIR := $(LIBDIR)android_arm64-v8a/ 463 BINDIR := $(BINDIR)android_arm64-v8a/ 464 DEPDIR := $(DEPDIR)android_arm64-v8a/ 465 466 TEGRA_LIBS := \ 467-L$(JETPACK)/cuda/targets/aarch64-linux-androideabi/lib \ 468-L$(JETPACK)/cuda/targets/aarch64-linux-androideabi/lib/stubs \ 469-L$(JETPACK)/cuda/targets/aarch64-linux-androideabi/lib64 \ 470-L$(JETPACK)/cuda/targets/aarch64-linux-androideabi/lib64/stubs \ 471-L$(JETPACK)/cuDNN/aarch64/cuda/lib64 \ 472-L$(LIBDIR) 473 474 CUDA_LIB_DEPS := $(LIBDIR)libtfcuda.a 475 else 476 OBJDIR := $(OBJDIR)android_$(ANDROID_ARCH)/ 477 LIBDIR := $(LIBDIR)android_$(ANDROID_ARCH)/ 478 BINDIR := $(BINDIR)android_$(ANDROID_ARCH)/ 479 DEPDIR := $(DEPDIR)android_$(ANDROID_ARCH)/ 480 endif # ifeq ($(BUILD_FOR_TEGRA),1) 481endif # ANDROID 482 483# Settings for iOS. 484ifeq ($(TARGET),IOS) 485 IPHONEOS_PLATFORM := $(shell xcrun --sdk iphoneos --show-sdk-platform-path) 486 IPHONEOS_SYSROOT := $(shell xcrun --sdk iphoneos --show-sdk-path) 487 IPHONESIMULATOR_PLATFORM := $(shell xcrun --sdk iphonesimulator \ 488 --show-sdk-platform-path) 489 IPHONESIMULATOR_SYSROOT := $(shell xcrun --sdk iphonesimulator \ 490 --show-sdk-path) 491 IOS_SDK_VERSION := $(shell xcrun --sdk iphoneos --show-sdk-version) 492 MIN_SDK_VERSION := 9.0 493# Override IOS_ARCH with ARMV7, ARMV7S, ARM64, or I386. 494 IOS_ARCH := X86_64 495 ifeq ($(IOS_ARCH),ARMV7) 496 CXXFLAGS += -miphoneos-version-min=$(MIN_SDK_VERSION) \ 497 -arch armv7 \ 498 -fembed-bitcode \ 499 -D__thread=thread_local \ 500 -DUSE_GEMM_FOR_CONV \ 501 -Wno-c++11-narrowing \ 502 -mno-thumb \ 503 -DTF_LEAN_BINARY \ 504 $(ANDROID_TYPES) \ 505 -fno-exceptions \ 506 -isysroot \ 507 ${IPHONEOS_SYSROOT} 508 LDFLAGS := -arch armv7 \ 509 -fembed-bitcode \ 510 -miphoneos-version-min=${MIN_SDK_VERSION} \ 511 -framework Accelerate \ 512 -Xlinker -S \ 513 -Xlinker -x \ 514 -Xlinker -dead_strip \ 515 -all_load \ 516 -L$(GENDIR)protobuf_ios/lib \ 517 -lz 518 endif 519 ifeq ($(IOS_ARCH),ARMV7S) 520 CXXFLAGS += -miphoneos-version-min=$(MIN_SDK_VERSION) \ 521 -arch armv7s \ 522 -fembed-bitcode \ 523 -D__thread=thread_local \ 524 -DUSE_GEMM_FOR_CONV \ 525 -Wno-c++11-narrowing \ 526 -mno-thumb \ 527 -DTF_LEAN_BINARY \ 528 $(ANDROID_TYPES) \ 529 -fno-exceptions \ 530 -isysroot \ 531 ${IPHONEOS_SYSROOT} 532 LDFLAGS := -arch armv7s \ 533 -fembed-bitcode \ 534 -miphoneos-version-min=${MIN_SDK_VERSION} \ 535 -framework Accelerate \ 536 -Xlinker -S \ 537 -Xlinker -x \ 538 -Xlinker -dead_strip \ 539 -all_load \ 540 -L$(GENDIR)protobuf_ios/lib \ 541 -lz 542 endif 543 ifeq ($(IOS_ARCH),ARM64) 544 CXXFLAGS += -miphoneos-version-min=$(MIN_SDK_VERSION) \ 545 -arch arm64 \ 546 -fembed-bitcode \ 547 -D__thread=thread_local \ 548 -DUSE_GEMM_FOR_CONV \ 549 -Wno-c++11-narrowing \ 550 -DTF_LEAN_BINARY \ 551 $(ANDROID_TYPES) \ 552 -fno-exceptions \ 553 -isysroot \ 554 ${IPHONEOS_SYSROOT} 555 LDFLAGS := -arch arm64 \ 556 -fembed-bitcode \ 557 -miphoneos-version-min=${MIN_SDK_VERSION} \ 558 -framework Accelerate \ 559 -Xlinker -S \ 560 -Xlinker -x \ 561 -Xlinker -dead_strip \ 562 -all_load \ 563 -L$(GENDIR)protobuf_ios/lib \ 564 -lz 565 endif 566 ifeq ($(IOS_ARCH),I386) 567 CXXFLAGS += -mios-simulator-version-min=$(MIN_SDK_VERSION) \ 568 -arch i386 \ 569 -mno-sse \ 570 -fembed-bitcode \ 571 -D__thread=thread_local \ 572 -DUSE_GEMM_FOR_CONV \ 573 -Wno-c++11-narrowing \ 574 -DTF_LEAN_BINARY \ 575 $(ANDROID_TYPES) \ 576 -fno-exceptions \ 577 -isysroot \ 578 ${IPHONESIMULATOR_SYSROOT} 579 LDFLAGS := -arch i386 \ 580 -fembed-bitcode \ 581 -mios-simulator-version-min=${MIN_SDK_VERSION} \ 582 -framework Accelerate \ 583 -Xlinker -S \ 584 -Xlinker -x \ 585 -Xlinker -dead_strip \ 586 -all_load \ 587 -L$(GENDIR)protobuf_ios/lib \ 588 -lz 589 endif 590 ifeq ($(IOS_ARCH),X86_64) 591 CXXFLAGS += -mios-simulator-version-min=$(MIN_SDK_VERSION) \ 592 -arch x86_64 \ 593 -fembed-bitcode \ 594 -D__thread=thread_local \ 595 -DUSE_GEMM_FOR_CONV \ 596 -Wno-c++11-narrowing \ 597 -DTF_LEAN_BINARY \ 598 $(ANDROID_TYPES) \ 599 -fno-exceptions \ 600 -isysroot \ 601 ${IPHONESIMULATOR_SYSROOT} 602 LDFLAGS := -arch x86_64 \ 603 -fembed-bitcode \ 604 -mios-simulator-version-min=${MIN_SDK_VERSION} \ 605 -framework Accelerate \ 606 -Xlinker -S \ 607 -Xlinker -x \ 608 -Xlinker -dead_strip \ 609 -all_load \ 610 -L$(GENDIR)protobuf_ios/lib \ 611 -lz 612 endif 613 OBJDIR := $(OBJDIR)ios_$(IOS_ARCH)/ 614 LIBDIR := $(LIBDIR)ios_$(IOS_ARCH)/ 615 BINDIR := $(BINDIR)ios_$(IOS_ARCH)/ 616 DEPDIR := $(DEPDIR)ios_$(IOS_ARCH)/ 617endif 618 619# This library is the main target for this makefile. It will contain a minimal 620# runtime that can be linked in to other programs. 621LIB_NAME := libtensorflow-core.a 622LIB_PATH := $(LIBDIR)$(LIB_NAME) 623 624# A small example program that shows how to link against the library. 625BENCHMARK_NAME := $(BINDIR)benchmark 626 627# What sources we want to compile, derived from the main Bazel build using the 628# gen_file_lists.sh script. 629 630CORE_CC_ALL_SRCS := \ 631$(ABSL_CC_SRCS) \ 632tensorflow/c/c_api.cc \ 633tensorflow/c/kernels.cc \ 634tensorflow/c/tf_status_helper.cc \ 635$(wildcard tensorflow/core/*.cc) \ 636$(wildcard tensorflow/core/common_runtime/*.cc) \ 637$(wildcard tensorflow/core/framework/*.cc) \ 638$(wildcard tensorflow/core/graph/*.cc) \ 639$(wildcard tensorflow/core/grappler/*.cc) \ 640$(wildcard tensorflow/core/grappler/*/*.cc) \ 641$(wildcard tensorflow/core/lib/*/*.cc) \ 642$(wildcard tensorflow/core/platform/*.cc) \ 643$(wildcard tensorflow/core/platform/*/*.cc) \ 644$(wildcard tensorflow/core/platform/*/*/*.cc) \ 645$(wildcard tensorflow/core/util/*.cc) \ 646$(wildcard tensorflow/core/util/*/*.cc) \ 647$(wildcard tensorflow/contrib/makefile/downloads/double_conversion/double-conversion/*.cc) \ 648tensorflow/core/util/version_info.cc 649# Remove duplicates (for version_info.cc) 650CORE_CC_ALL_SRCS := $(sort $(CORE_CC_ALL_SRCS)) 651 652CORE_CC_EXCLUDE_SRCS_NON_GPU := \ 653$(wildcard tensorflow/core/*/*test.cc) \ 654$(wildcard tensorflow/core/*/*testutil*) \ 655$(wildcard tensorflow/core/*/*testlib*) \ 656$(wildcard tensorflow/core/*/*main.cc) \ 657$(wildcard tensorflow/core/*/*/*test.cc) \ 658$(wildcard tensorflow/core/*/*/*testutil*) \ 659$(wildcard tensorflow/core/*/*/*testlib*) \ 660$(wildcard tensorflow/core/*/*/*main.cc) \ 661$(wildcard tensorflow/core/debug/*.cc) \ 662$(wildcard tensorflow/core/framework/op_gen_lib.cc) \ 663$(wildcard tensorflow/core/graph/dot.*) \ 664$(wildcard tensorflow/core/lib/db/*) \ 665$(wildcard tensorflow/core/lib/gif/*) \ 666$(wildcard tensorflow/core/lib/io/zlib*) \ 667$(wildcard tensorflow/core/lib/io/record*) \ 668$(wildcard tensorflow/core/lib/jpeg/*) \ 669$(wildcard tensorflow/core/lib/png/*) \ 670$(wildcard tensorflow/core/util/events_writer.*) \ 671$(wildcard tensorflow/core/util/reporter.*) \ 672$(wildcard tensorflow/core/platform/default/test_benchmark.*) \ 673$(wildcard tensorflow/core/platform/cloud/*) \ 674$(wildcard tensorflow/core/platform/google/*) \ 675$(wildcard tensorflow/core/platform/google/*/*) \ 676$(wildcard tensorflow/core/platform/jpeg.*) \ 677$(wildcard tensorflow/core/platform/png.*) \ 678$(wildcard tensorflow/core/platform/s3/*) \ 679$(wildcard tensorflow/core/platform/windows/*) \ 680$(wildcard tensorflow/core/grappler/inputs/trivial_test_graph_input_yielder.*) \ 681$(wildcard tensorflow/core/grappler/inputs/file_input_yielder.*) \ 682$(wildcard tensorflow/core/grappler/clusters/single_machine.*) \ 683tensorflow/core/util/cuda_kernel_helper_test.cu.cc 684 685CORE_CC_EXCLUDE_SRCS := \ 686$(CORE_CC_EXCLUDE_SRCS_NON_GPU) \ 687$(wildcard tensorflow/core/platform/stream_executor.*) \ 688$(wildcard tensorflow/core/platform/default/cuda_libdevice_path.*) \ 689$(wildcard tensorflow/core/platform/cuda.h) \ 690$(wildcard tensorflow/core/platform/cuda_libdevice_path.*) \ 691$(wildcard tensorflow/core/user_ops/*.cu.cc) \ 692$(wildcard tensorflow/core/common_runtime/gpu/*) \ 693$(wildcard tensorflow/core/common_runtime/gpu_device_factory.*) 694 695ifeq ($(BUILD_FOR_TEGRA),1) 696CORE_CC_ALL_SRCS := $(CORE_CC_ALL_SRCS) \ 697tensorflow/core/kernels/concat_lib_gpu.cc \ 698tensorflow/core/kernels/cuda_solvers.cc \ 699tensorflow/core/kernels/cudnn_pooling_gpu.cc \ 700tensorflow/core/kernels/dense_update_functor.cc \ 701tensorflow/core/kernels/fractional_avg_pool_op.cc \ 702tensorflow/core/kernels/fractional_max_pool_op.cc \ 703tensorflow/core/kernels/fractional_pool_common.cc \ 704tensorflow/core/kernels/pooling_ops_3d.cc \ 705tensorflow/core/kernels/sparse_fill_empty_rows_op.cc \ 706tensorflow/core/kernels/list_kernels.cc \ 707$(wildcard tensorflow/core/common_runtime/gpu/*.cc) \ 708$(wildcard tensorflow/stream_executor/*.cc) \ 709$(wildcard tensorflow/stream_executor/*/*.cc) 710 711CORE_CC_EXCLUDE_SRCS := \ 712$(CORE_CC_EXCLUDE_SRCS_NON_GPU) 713 714CUDA_CC_SRCS := $(wildcard tensorflow/core/kernels/*.cu.cc) 715CUDA_CC_OBJS := $(addprefix $(OBJDIR), $(CUDA_CC_SRCS:.cc=.o)) 716endif # TEGRA 717 718# Filter out all the excluded files. 719TF_CC_SRCS := $(filter-out $(CORE_CC_EXCLUDE_SRCS), $(CORE_CC_ALL_SRCS)) 720# Add in any extra files that don't fit the patterns easily 721TF_CC_SRCS += tensorflow/contrib/makefile/downloads/fft2d/fftsg.c 722TF_CC_SRCS += tensorflow/core/common_runtime/gpu/gpu_id_manager.cc 723# Also include the op and kernel definitions. 724TF_CC_SRCS += $(shell cat $(MAKEFILE_DIR)/tf_op_files.txt) 725PBT_CC_SRCS := $(shell cat $(MAKEFILE_DIR)/tf_pb_text_files.txt) 726PROTO_SRCS := $(shell cat $(MAKEFILE_DIR)/tf_proto_files.txt) 727BENCHMARK_SRCS := \ 728tensorflow/core/util/reporter.cc \ 729tensorflow/tools/benchmark/benchmark_model.cc \ 730tensorflow/tools/benchmark/benchmark_model_main.cc 731 732# If `$(WITH_TFLITE_FLEX)` is `true`, this Makefile will build a library 733# for TensorFlow Lite Flex runtime. 734# Adding the following dependencies> 735# * TensorFlow Eager Runtime. 736# * TensorFlow Lite Runtime. 737# * TensorFlow Lite Flex Delegate. 738ifeq ($(WITH_TFLITE_FLEX), true) 739 EAGER_CC_ALL_SRCS += $(wildcard tensorflow/core/common_runtime/eager/*.cc) 740 EAGER_CC_EXCLUDE_SRCS := $(wildcard tensorflow/core/common_runtime/eager/*test.cc) 741 EAGER_CC_SRCS := $(filter-out $(EAGER_CC_EXCLUDE_SRCS), $(EAGER_CC_ALL_SRCS)) 742 TF_CC_SRCS += $(EAGER_CC_SRCS) 743 744 TF_LITE_CORE_CC_ALL_SRCS := \ 745 $(wildcard tensorflow/lite/*.cc) \ 746 $(wildcard tensorflow/lite/*.c) \ 747 $(wildcard tensorflow/lite/c/*.c) \ 748 $(wildcard tensorflow/lite/core/api/*.cc) 749 750 TF_LITE_CORE_CC_ALL_SRCS += \ 751 $(wildcard tensorflow/lite/kernels/*.cc) \ 752 $(wildcard tensorflow/lite/kernels/internal/*.cc) \ 753 $(wildcard tensorflow/lite/kernels/internal/optimized/*.cc) \ 754 $(wildcard tensorflow/lite/kernels/internal/reference/*.cc) \ 755 $(PROFILER_SRCS) \ 756 $(wildcard tensorflow/lite/kernels/*.c) \ 757 $(wildcard tensorflow/lite/kernels/internal/*.c) \ 758 $(wildcard tensorflow/lite/kernels/internal/optimized/*.c) \ 759 $(wildcard tensorflow/lite/kernels/internal/reference/*.c) \ 760 $(wildcard tensorflow/lite/delegates/flex/*.cc) 761 762 # Hack. This shouldn't be here? 763 TF_LITE_CORE_CC_ALL_SRCS += \ 764 $(wildcard tensorflow/contrib/makefile/downloads/farmhash/src/farmhash.cc) \ 765 766 # Remove any duplicates. 767 TF_LITE_CORE_CC_ALL_SRCS := $(sort $(TF_LITE_CORE_CC_ALL_SRCS)) 768 TF_LITE_CORE_CC_EXCLUDE_SRCS := \ 769 $(wildcard tensorflow/lite/*test.cc) \ 770 $(wildcard tensorflow/lite/*/*test.cc) \ 771 $(wildcard tensorflow/lite/*/*/*test.cc) \ 772 $(wildcard tensorflow/lite/*/*/*/*test.cc) \ 773 $(wildcard tensorflow/lite/kernels/test_util.cc) \ 774 $(wildcard tensorflow/lite/delegates/flex/test_util.cc) \ 775 $(wildcard tensorflow/lite/nnapi_delegate.cc) \ 776 $(wildcard tensorflow/lite/mmap_allocation_disabled.cc) 777 778 # Filter out all the excluded files. 779 TF_LITE_CC_SRCS := $(filter-out $(TF_LITE_CORE_CC_EXCLUDE_SRCS), $(TF_LITE_CORE_CC_ALL_SRCS)) 780 TF_CC_SRCS += $(TF_LITE_CC_SRCS) 781endif 782 783ifdef HEXAGON_LIBS 784 TF_CC_SRCS += \ 785tensorflow/cc/framework/scope.cc \ 786tensorflow/cc/framework/ops.cc \ 787tensorflow/cc/ops/const_op.cc \ 788tensorflow/core/kernels/hexagon/graph_transfer_utils.cc \ 789tensorflow/core/kernels/hexagon/graph_transferer.cc \ 790tensorflow/core/kernels/hexagon/hexagon_control_wrapper.cc \ 791tensorflow/core/kernels/hexagon/hexagon_ops_definitions.cc \ 792tensorflow/core/kernels/hexagon/hexagon_remote_fused_graph_executor_build.cc 793endif 794 795# File names of the intermediate files target compilation generates. 796TF_CC_OBJS := $(addprefix $(OBJDIR), \ 797$(patsubst %.cc,%.o,$(patsubst %.c,%.o,$(TF_CC_SRCS)))) 798PBT_GEN_FILES := $(addprefix $(PBTGENDIR), $(PBT_CC_SRCS)) 799PBT_OBJS := $(addprefix $(OBJDIR), $(PBT_CC_SRCS:.cc=.o)) 800PROTO_CC_SRCS := $(addprefix $(PROTOGENDIR), $(PROTO_SRCS:.proto=.pb.cc)) 801PROTO_OBJS := $(addprefix $(OBJDIR), $(PROTO_SRCS:.proto=.pb.o)) 802LIB_OBJS := $(PROTO_OBJS) $(TF_CC_OBJS) $(PBT_OBJS) 803BENCHMARK_OBJS := $(addprefix $(OBJDIR), $(BENCHMARK_SRCS:.cc=.o)) 804 805.PHONY: clean cleantarget 806 807# The target that's compiled if there's no command-line arguments. 808all: $(LIB_PATH) $(BENCHMARK_NAME) 809 810# Rules for target compilation. 811 812 813.phony_version_info: 814tensorflow/core/util/version_info.cc: .phony_version_info 815 tensorflow/tools/git/gen_git_source.sh $@ 816 817# Gathers together all the objects we've compiled into a single '.a' archive. 818$(LIB_PATH): $(LIB_OBJS) 819 @mkdir -p $(dir $@) 820 $(AR) $(ARFLAGS) $(LIB_PATH) $(LIB_OBJS) 821 822$(BENCHMARK_NAME): $(BENCHMARK_OBJS) $(LIB_PATH) $(CUDA_LIB_DEPS) 823 @mkdir -p $(dir $@) 824 $(CXX) $(CXXFLAGS) $(INCLUDES) \ 825 -o $(BENCHMARK_NAME) $(BENCHMARK_OBJS) \ 826 $(LIBFLAGS) $(TEGRA_LIBS) $(LIB_PATH) $(LDFLAGS) $(LIBS) $(CUDA_LIBS) 827 828# NVCC compilation rules for Tegra 829ifeq ($(BUILD_FOR_TEGRA),1) 830$(OBJDIR)%.cu.o: %.cu.cc 831 @mkdir -p $(dir $@) 832 @mkdir -p $(dir $(DEPDIR)$*) 833 $(NVCC) $(NVCCFLAGS) -Xcompiler "$(CXXFLAGS4NVCC) $(DEPFLAGS)" $(INCLUDES) -c $< -o $@ 834 835$(LIBDIR)libtfcuda.a: $(CUDA_CC_OBJS) 836 @mkdir -p $(dir $@) 837 $(AR) $(ARFLAGS) $@ $(CUDA_CC_OBJS) 838endif 839 840# Matches on the normal hand-written TensorFlow C++ source files. 841$(OBJDIR)%.o: %.cc | $(PBT_GEN_FILES) 842 @mkdir -p $(dir $@) 843 @mkdir -p $(dir $(DEPDIR)$*) 844 $(CXX) $(CXXFLAGS) $(DEPFLAGS) $(INCLUDES) -c $< -o $@ 845 @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d 846 847# Matches on plain C files. 848$(OBJDIR)%.o: %.c 849 @mkdir -p $(dir $@) 850 @mkdir -p $(dir $(DEPDIR)$*) 851 $(CXX) $(patsubst --std=c++11,--std=c99, $(CXXFLAGS)) -x c $(DEPFLAGS) \ 852$(INCLUDES) -c $< -o $@ 853 @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d 854 855# Compiles C++ source files that have been generated by protoc. 856$(OBJDIR)%.pb.o: $(PROTOGENDIR)%.pb.cc 857 @mkdir -p $(dir $@) 858 $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ 859 860# Builds C++ code from proto files using protoc. 861$(PROTOGENDIR)%.pb.cc $(PROTOGENDIR)%.pb.h: %.proto 862 @mkdir -p $(dir $@) 863 $(PROTOC) $(PROTOCFLAGS) $< --cpp_out $(PROTOGENDIR) 864 865# Uses proto_text to generate minimal pb_text C++ files from protos. 866$(PBTGENDIR)%.pb_text.cc $(PBTGENDIR)%.pb_text.h $(PBTGENDIR)%.pb_text-impl.h: %.proto | $(PROTO_TEXT) 867 @mkdir -p $(dir $@) 868 $(PROTO_TEXT) \ 869 $(PBTGENDIR)tensorflow/core \ 870 tensorflow/core/ \ 871 tensorflow/tools/proto_text/placeholder.txt \ 872 $< 873 874# Compiles the C++ source files created by proto_text. 875$(OBJDIR)%.pb_text.o: $(PBTGENDIR)%.pb_text.cc 876 @mkdir -p $(dir $@) 877 $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ 878 879# Makes sure that we don't compile the protoc-generated C++ sources before they 880# and the proto_text files have been created. 881$(PROTO_OBJS): $(PROTO_CC_SRCS) $(PBT_GEN_FILES) 882 883# Host compilation rules. 884 885# For normal manually-created TensorFlow C++ source files. 886$(HOST_OBJDIR)%.o: %.cc 887 @mkdir -p $(dir $@) 888 $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_INCLUDES) -c $< -o $@ 889 890# Compiles object code from protoc-built C++ source files. 891$(HOST_OBJDIR)%.pb.o: $(HOST_GENDIR)%.pb.cc 892 @mkdir -p $(dir $@) 893 $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_INCLUDES) -c $< -o $@ 894 895# Ensures we wait until proto_text has generated the .h files from protos before 896# we compile the C++. 897$(PROTO_TEXT_OBJS) : $(PROTO_TEXT_PB_H_FILES) 898 899# Runs proto_text to generate C++ source files from protos. 900$(PROTO_TEXT): $(PROTO_TEXT_OBJS) $(PROTO_TEXT_PB_H_FILES) 901 @mkdir -p $(dir $@) 902 $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_INCLUDES) \ 903 -o $(PROTO_TEXT) $(PROTO_TEXT_OBJS) $(HOST_LDOPTS) $(HOST_LIBS) 904 905# Compiles the C++ source files from protos using protoc. 906$(HOST_GENDIR)%.pb.cc $(HOST_GENDIR)%.pb.h: %.proto 907 @mkdir -p $(dir $@) 908 $(PROTOC) $(PROTOCFLAGS) $< --cpp_out $(HOST_GENDIR) 909 910# Gets rid of all generated files. 911clean: 912 rm -rf $(MAKEFILE_DIR)/gen 913 rm -rf tensorflow/core/util/version_info.cc 914 915# Gets rid of all generated files except protobuf libs generated 916# before calling make. This allows users not to recompile proto libs everytime. 917clean_except_protobuf_libs: 918 find $(MAKEFILE_DIR)/gen -mindepth 1 -maxdepth 1 ! -name "protobuf*" -exec rm -r "{}" \; 919 rm -rf tensorflow/core/util/version_info.cc 920 921# Gets rid of target files only, leaving the host alone. Also leaves the lib 922# directory untouched deliberately, so we can persist multiple architectures 923# across builds for iOS and Android. 924cleantarget: 925 rm -rf $(OBJDIR) 926 rm -rf $(BINDIR) 927 rm -rf $(LIBDIR) 928 929$(DEPDIR)/%.d: ; 930.PRECIOUS: $(DEPDIR)/%.d 931 932-include $(patsubst %,$(DEPDIR)/%.d,$(basename $(TF_CC_SRCS))) 933 934ifdef SUB_MAKEFILES 935 $(warning "include sub makefiles, must not contain white spaces in the path:" $(SUB_MAKEFILES)) 936 include $(SUB_MAKEFILES) 937endif 938