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