README.md revision b48cfaea2aea3707a33e60c10385a87e37101b95
160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke### TensorFlow Makefile
260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
360796d7c0d401e5e7b7a139f165e78ce778583beMartin WickeThe recommended way to build TensorFlow from source is using the Bazel
4a93234a60244ffe843312c3f49ee495d1524dd48Andrew Selleopen-source build system. Sometimes this isn't possible. For example,
5a93234a60244ffe843312c3f49ee495d1524dd48Andrew Selleif you are building for iOS, you currently need to use the Makefile.
660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
7e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower - The build system may not have the RAM or processing power to support Bazel.
8e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower - Bazel or its dependencies may not be available.
960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke - You may want to cross-compile for an unsupported target system.
1060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
1160796d7c0d401e5e7b7a139f165e78ce778583beMartin WickeThis experimental project supplies a Makefile automatically derived from the
12e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerdependencies listed in the Bazel project that can be used with GNU's make tool.
13e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerWith it, you can compile the core C++ runtime into a static library.
14e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
15e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThis static library will not contain:
16e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
17e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower - Python or other language bindings
18e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower - GPU support
19e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower 
2021716d8f6e175cd6e8cd97a84e48497574268b0cMartin WickeYou can target:
2121716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke- iOS
2221716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke- OS X (macOS)
2321716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke- Android
2421716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke- Raspberry-PI
25e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower 
2621716d8f6e175cd6e8cd97a84e48497574268b0cMartin WickeYou will compile tensorflow and protobuf libraries that you can link into other
2721716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wickeapplications.  You will also compile the [benchmark](../../tools/benchmark/)
2821716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wickeapplication that will let you check your application.
29e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower 
30e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower## Before you start (all platforms)
31e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
32e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerFirst, clone this TensorFlow repository.
33e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
34e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerYou will need to download all dependencies as well.  We have provided a script
3593a975e114ee1c35f01ed3bdd47170e6f7129014Vijay Vasudevanthat does so, to be run (as with all commands) **at the root of the repository**:
36e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
3710ff074b89cd948db16f669cea019d0e9d7de91ePete Warden```bash
38e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/download_dependencies.sh
39e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
4060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
41e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerYou should only need to do this step once.  It downloads the required libraries
42e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerlike Eigen in the `tensorflow/contrib/makefile/downloads/` folder.
4360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
44e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerYou should download the example graph from [https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip](https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip).
4560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
46e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower## Building on Linux
47e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
48e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower_Note: This has only been tested on Ubuntu._
49e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
5060360feb1a5c22091a835a3c4d11beeed46ad206Pete WardenAs a first step, you need to make sure the required packages are installed:
51e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
5260360feb1a5c22091a835a3c4d11beeed46ad206Pete Wardensudo apt-get install autoconf automake libtool curl make g++ unzip zlib1g-dev \
5360360feb1a5c22091a835a3c4d11beeed46ad206Pete Wardengit python
54e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
55e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
5660360feb1a5c22091a835a3c4d11beeed46ad206Pete WardenYou should then be able to run the `build_all_linux.sh` script to compile:
5760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
5860360feb1a5c22091a835a3c4d11beeed46ad206Pete Wardentensorflow/contrib/makefile/build_all_linux.sh
5960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
6060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
6160796d7c0d401e5e7b7a139f165e78ce778583beMartin WickeThis should compile a static library in 
62510ed21e3dbb81aee8e31318990dff21163086d5Zongheng Yang`tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a`, 
63510ed21e3dbb81aee8e31318990dff21163086d5Zongheng Yangand create an example executable at `tensorflow/contrib/makefile/gen/bin/benchmark`. 
64e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
65e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerGet the graph file, if you have not already:
6660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
6760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
68e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowermkdir -p ~/graphs
69e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowercurl -o ~/graphs/inception.zip \
70e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
71e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower && unzip ~/graphs/inception.zip -d ~/graphs/inception
7260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
7360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
74e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerTo run the executable, use:
7560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
76e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
77e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/gen/bin/benchmark \
78ccbc8991db3943ef984405881a1c917c530f902fA. Unique TensorFlower --graph=$HOME/graphs/inception/tensorflow_inception_graph.pb
79e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
8060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
8160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke## Android
8260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
83e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerFirst, you will need to download and unzip the
846cd8b28da1cd42f9bacbef9d55f64c7f5162bb9cAndrew Harp[Native Development Kit (NDK)](https://developer.android.com/ndk/). You will not
85e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerneed to install the standalone toolchain, however.
86e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
87e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerAssign your NDK location to $NDK_ROOT:
8860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
8960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
90e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerexport NDK_ROOT=/absolute/path/to/NDK/android-ndk-rxxx/
91e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
92e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
93e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerDownload the graph if you haven't already:
94e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
95e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
96e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowermkdir -p ~/graphs
97e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowercurl -o ~/graphs/inception.zip \
98e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
99e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower && unzip ~/graphs/inception.zip -d ~/graphs/inception
100e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
101e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
102e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThen, execute the following:
103e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
104e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
105e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/download_dependencies.sh
106e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/compile_android_protobuf.sh -c
107b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerexport HOST_NSYNC_LIB=`tensorflow/contrib/makefile/compile_nsync.sh`
108b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerexport TARGET_NSYNC_LIB=`CC_PREFIX="${CC_PREFIX}" NDK_ROOT="${NDK_ROOT}" \
109b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlower	tensorflow/contrib/makefile/compile_nsync.sh -t android -a armeabi-v7a`
110e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowermake -f tensorflow/contrib/makefile/Makefile TARGET=ANDROID
111e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
112e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
113e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerAt this point, you will have compiled libraries in `gen/lib/*` and the
114e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower[benchmark app](../../tools/benchmark) compiled for Android.
115e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
116e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerRun the benchmark by pushing both the benchmark and the graph file to your
117e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerattached Android device:
118e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
119e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
120e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFloweradb push ~/graphs/inception/tensorflow_inception_graph.pb /data/local/tmp/
121e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFloweradb push tensorflow/contrib/makefile/gen/bin/benchmark /data/local/tmp/
122e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFloweradb shell '/data/local/tmp/benchmark \
123a771598ad83ca33eb42594d7e804859371ba4ca9Benoit Steiner --graph=/data/local/tmp/tensorflow_inception_graph.pb \
124e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower --input_layer="input:0" \
125e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower --input_layer_shape="1,224,224,3" \
126e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower --input_layer_type="float" \
127e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower --output_layer="output:0"
128e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower'
12960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
13060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
131e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerFor more details, see the [benchmark documentation](../../tools/benchmark).
13260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
13360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke## iOS
13460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
135e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower_Note: To use this library in an iOS application, see related instructions in
136a0ffaf3caa0234653035a692858606c7bdacd63bFrank Chenthe [iOS examples](../../examples/ios/) directory._
137e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
138e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerInstall XCode 7.3 or more recent. If you have not already, you will need to
139e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerinstall the command-line tools using `xcode-select`:
14060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
14160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
142e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerxcode-select --install
14360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
14460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
145e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerIf this is a new install, you will need to run XCode once to agree to the
146e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerlicense before continuing.
14760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
14893a975e114ee1c35f01ed3bdd47170e6f7129014Vijay Vasudevan(You will also need to have [Homebrew](http://brew.sh/) installed.)
14993a975e114ee1c35f01ed3bdd47170e6f7129014Vijay Vasudevan
1501cb96893a64f59b7265f9def9968f7bed1e57662Andrew HarpThen install [automake](https://en.wikipedia.org/wiki/Automake)/[libtool](https://en.wikipedia.org/wiki/GNU_Libtool):
1511283b84a49a9f5e14aca833cf981b61848aaf916Jonathan Hseu
1521283b84a49a9f5e14aca833cf981b61848aaf916Jonathan Hseu```bash
1531283b84a49a9f5e14aca833cf981b61848aaf916Jonathan Hseubrew install automake
1541cb96893a64f59b7265f9def9968f7bed1e57662Andrew Harpbrew install libtool
1551283b84a49a9f5e14aca833cf981b61848aaf916Jonathan Hseu```
1561283b84a49a9f5e14aca833cf981b61848aaf916Jonathan Hseu
157e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerAlso, download the graph if you haven't already:
15860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
159e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
160e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowermkdir -p ~/graphs
161e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowercurl -o ~/graphs/inception.zip \
162e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
163e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower && unzip ~/graphs/inception.zip -d ~/graphs/inception
164e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
165e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
166e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower### Building all at once
167e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
16821716d8f6e175cd6e8cd97a84e48497574268b0cMartin WickeIf you just want to get the libraries compiled in a hurry, you can run this
16921716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wickefrom the root of your TensorFlow source folder:
17060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
17160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
17221716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicketensorflow/contrib/makefile/build_all_ios.sh
17360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
17460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
17521716d8f6e175cd6e8cd97a84e48497574268b0cMartin WickeThis process will take around twenty minutes on a modern MacBook Pro.
176e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
17721716d8f6e175cd6e8cd97a84e48497574268b0cMartin WickeWhen it completes, you will have a library for a single architecture and the
178e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerbenchmark program. Although successfully compiling the benchmark program is a
179e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowersign of success, the program is not a complete iOS app.
180e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
181e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerTo see TensorFlow running on iOS, the example Xcode project in
182a0ffaf3caa0234653035a692858606c7bdacd63bFrank Chen[tensorflow/examples/ios](../../examples/ios/) shows how to use the static
183e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerlibrary in a simple app.
184e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
185e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower### Building by hand
186e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
187e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThis section covers each step of building.  For all the code in one place, see
188e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower[build_all_ios.sh](build_all_ios.sh). 
189e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
190e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerIf you have not already, you will need to download dependencies:
19160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
19260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
19360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicketensorflow/contrib/makefile/download_dependencies.sh
19460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
19560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
196e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerNext, you will need to compile protobufs for iOS:
19760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
19860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
199a771598ad83ca33eb42594d7e804859371ba4ca9Benoit Steinertensorflow/contrib/makefile/compile_ios_protobuf.sh 
20060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
20160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
202b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerThen, you will need to compile the nsync library for iOS:
203b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlower
204b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlower```export HOST_NSYNC_LIB=`tensorflow/contrib/makefile/compile_nsync.sh`
205b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerexport TARGET_NSYNC_LIB=`tensorflow/contrib/makefile/compile_nsync.sh -t ios`
206b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlower```
207b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlower
208e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThen, you can run the makefile specifying iOS as the target, along with the
209e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerarchitecture you want to build for:
21060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
21160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
212e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowermake -f tensorflow/contrib/makefile/Makefile \
213e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower TARGET=IOS \
214e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower IOS_ARCH=ARM64
21560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
21660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
217e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThis creates a library in
218e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower`tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a` that you can link any
219e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerxcode project against. 
220e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
221e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerAt this point, you will have a library for a single architecture and the
222e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerbenchmark program. Although successfully compiling the benchmark program is a
223e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowersign of success, the program is not a complete iOS app. 
224e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
225e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerTo see TensorFlow running on iOS, the example Xcode project in
226a0ffaf3caa0234653035a692858606c7bdacd63bFrank Chen[tensorflow/examples/ios](../../examples/ios/) shows how to use the static
227e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerlibrary in a simple app.
228e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
229e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower#### Universal binaries
230e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
231e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerIn some situations, you will need a universal library.  In that case, you will
232b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerstill need to run `compile_ios_protobuf.sh` and `compile_nsync.sh`, but this
233b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowertime follow it with:
23460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
23560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
236e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowercompile_ios_tensorflow.sh
23760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
23860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
239e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerIn XCode, you will need to use -force_load in the linker flags
24060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wickesection of the build settings to pull in the global constructors that are used
24160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicketo register ops and kernels. 
24260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
24310ff074b89cd948db16f669cea019d0e9d7de91ePete Warden#### Optimization
24410ff074b89cd948db16f669cea019d0e9d7de91ePete Warden 
24510ff074b89cd948db16f669cea019d0e9d7de91ePete WardenThe `compile_ios_tensorflow.sh` script can take optional command-line arguments.
24610ff074b89cd948db16f669cea019d0e9d7de91ePete WardenThe first argument will be passed as a C++ optimization flag and defaults to
24710ff074b89cd948db16f669cea019d0e9d7de91ePete Wardendebug mode. If you are concerned about performance or are working on a release
24810ff074b89cd948db16f669cea019d0e9d7de91ePete Wardenbuild, you would likely want a higher optimization setting, like so:
24910ff074b89cd948db16f669cea019d0e9d7de91ePete Warden 
25010ff074b89cd948db16f669cea019d0e9d7de91ePete Warden```bash
25110ff074b89cd948db16f669cea019d0e9d7de91ePete Wardencompile_ios_tensorflow.sh "-Os"
25210ff074b89cd948db16f669cea019d0e9d7de91ePete Warden```
25310ff074b89cd948db16f669cea019d0e9d7de91ePete Warden
25410ff074b89cd948db16f669cea019d0e9d7de91ePete WardenFor other variations of valid optimization flags, see [clang optimization levels](http://stackoverflow.com/questions/15548023/clang-optimization-levels).
25510ff074b89cd948db16f669cea019d0e9d7de91ePete Warden
25660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke## Raspberry Pi
25760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
2588b3d8c8b5e96036ec78e01292c56ce099c5a62abBenoit SteinerBuilding on the Raspberry Pi is similar to a normal Linux system. First
259b0bdff4827f867a67f572ed99d85f9a847788326A. Unique TensorFlowerdownload the dependencies, install the required packages and build protobuf:
26060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
26160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
2628b3d8c8b5e96036ec78e01292c56ce099c5a62abBenoit Steinertensorflow/contrib/makefile/download_dependencies.sh
26368f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpsudo apt-get install -y autoconf automake libtool gcc-4.8 g++-4.8
2645a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevancd tensorflow/contrib/makefile/downloads/protobuf/
2658b3d8c8b5e96036ec78e01292c56ce099c5a62abBenoit Steiner./autogen.sh
2665a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevan./configure
2675a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevanmake
2685a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevansudo make install
269b0bdff4827f867a67f572ed99d85f9a847788326A. Unique TensorFlowersudo ldconfig  # refresh shared library cache
2705a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevancd ../../../../..
271b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerexport HOST_NSYNC_LIB=`tensorflow/contrib/makefile/compile_nsync.sh`
272b48cfaea2aea3707a33e60c10385a87e37101b95A. Unique TensorFlowerexport TARGET_NSYNC_LIB="$HOST_NSYNC_LIB"
27360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
27460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
2755a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay VasudevanOnce that's done, you can use make to build the library and example:
27660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
27760796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
27868f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpmake -f tensorflow/contrib/makefile/Makefile HOST_OS=PI TARGET=PI OPTFLAGS="-Os" CXX=g++-4.8
27960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
28060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
2815a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay VasudevanIf you're only interested in building for Raspberry Pi's 2 and 3, you can supply
2825a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevansome extra optimization flags to give you code that will run faster:
2835a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevan
2845a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevan```bash
2855a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevanmake -f tensorflow/contrib/makefile/Makefile HOST_OS=PI TARGET=PI \
28668f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harp OPTFLAGS="-Os -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize" CXX=g++-4.8
2875a65d43a9e456aac08b32a1d38cbe123d73fcda8Vijay Vasudevan```
28860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
28968f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew HarpOne thing to be careful of is that the gcc version 4.9 currently installed on
29068f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew HarpJessie by default will hit an error mentioning `__atomic_compare_exchange`. This
29168f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpis why the examples above specify `CXX=g++-4.8` explicitly, and why we install
29268f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpit using apt-get. If you have partially built using the default gcc 4.9, hit the
29368f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harperror and switch to 4.8, you need to do a
29468f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harp`make -f tensorflow/contrib/makefile/Makefile clean` before you build. If you
29568f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpdon't, the build will appear to succeed but you'll encounter [malloc(): memory corruption errors](https://github.com/tensorflow/tensorflow/issues/3442)
29668f1a7d05ce031192321a27daaf19529b4cb0a9bAndrew Harpwhen you try to run any programs using the library.
29721716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke
2988b3d8c8b5e96036ec78e01292c56ce099c5a62abBenoit SteinerFor more examples, look at the tensorflow/contrib/pi_examples folder in the
2998b3d8c8b5e96036ec78e01292c56ce099c5a62abBenoit Steinersource tree, which contains code samples aimed at the Raspberry Pi.
30021716d8f6e175cd6e8cd97a84e48497574268b0cMartin Wicke
301e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower# Other notes
302e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
303e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower## Supported Systems
304e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
305e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThe Make script has been tested on Ubuntu and OS X. If you look in the Makefile
306e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFloweritself, you'll see it's broken up into host and target sections. If you are
307e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowercross-compiling, you should look at customizing the target settings to match
308e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerwhat you need for your desired system.
309e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
310ee112cff56081fb9d0b74c987a8935acc360b05cBenoit Steiner## Dependency Management
31160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
31260796d7c0d401e5e7b7a139f165e78ce778583beMartin WickeThe Makefile loads in a list of dependencies stored in text files. These files
31360796d7c0d401e5e7b7a139f165e78ce778583beMartin Wickeare generated from the main Bazel build by running 
31460796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke`tensorflow/contrib/makefile/gen_file_lists.sh`. You'll need to re-run this i
31560796d7c0d401e5e7b7a139f165e78ce778583beMartin Wickeyou make changes to the files that are included in the build.
31660796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
31760796d7c0d401e5e7b7a139f165e78ce778583beMartin WickeHeader dependencies are not automatically tracked by the Makefile, so if you
31860796d7c0d401e5e7b7a139f165e78ce778583beMartin Wickemake header changes you will need to run this command to recompile cleanly:
31960796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke
32060796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```bash
32160796d7c0d401e5e7b7a139f165e78ce778583beMartin Wickemake -f tensorflow/contrib/makefile/Makefile clean
32260796d7c0d401e5e7b7a139f165e78ce778583beMartin Wicke```
323e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
324e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower### Cleaning up
325e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
326e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerIn some situations, you may want to completely clean up. The dependencies,
327e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerintermediate stages, and generated files are stored in:
328e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
329e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```bash
330e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/downloads
331e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowertensorflow/contrib/makefile/gen
332e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower```
333e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower
334e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlowerThose directories can safely be removed, but you will have to start over with
335e231a8b382195bf819bfac71a0233602a7101760A. Unique TensorFlower`download_dependencies.sh` once you delete them.
3366a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden
3376a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden### Fixing Makefile Issues
3386a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden
3396a83b0787f2f5037eed2f2f47cc76b94bc740aebPete WardenBecause the main development of TensorFlow is done using Bazel, changes to the
3406a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardencodebase can sometimes break the makefile build process. If you find that tests
3416a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardenrelying on this makefile are failing with a change you're involved in, here are
3426a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardensome trouble-shooting steps:
3436a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden
3446a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden - Try to reproduce the issue on your platform. If you're on Linux, running 
3456a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden `make -f tensorflow/contrib/makefile/Makefile` should be enough to recreate
3466a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  most issues. For other platforms, see the sections earlier in this document.
3476a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  
3486a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden - The most common cause of breakages are files that have been added to the
3496a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  Bazel build scripts, but that the makefile isn't aware of. Typical symptoms
3506a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  of this include linker errors mentioning missing symbols or protobuf headers
3516a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  that aren't found. To address these problems, take a look at the *.txt files
3526a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  in `tensorflow/contrib/makefile`. If you have a new operator, you may need to
3536a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  add it to `tf_op_files.txt`, or for a new proto to `tf_proto_files.txt`.
3546a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden
3556a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden - There's also a wildcard system in `Makefile` that defines what core C++ files
3566a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  are included in the library. This is designed to match the equivalent rule in
3576a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  `tensorflow/core/BUILD`, so if you change the wildcards there to include new
3586a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  files you'll need to also update `CORE_CC_ALL_SRCS` and `CORE_CC_EXCLUDE_SRCS`
3596a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  in the makefile.
3606a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  
3616a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden - Some of the supported platforms use clang instead of gcc as their compiler,
3626a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  so if you're hitting compile errors you may need to tweak your code to be more
3636a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  friendly to different compilers by avoiding gcc extensions or idioms.
3646a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Warden  
3656a83b0787f2f5037eed2f2f47cc76b94bc740aebPete WardenThese are the most common reasons for makefile breakages, but it's also
3666a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardenpossible you may hit something unusual, like a platform incompatibility. For
3676a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardenthose, you'll need to see if you can reproduce the issue on that particular
3686a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardenplatform and debug it there. You can also reach out to the broader TensorFlow
3696a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardenteam by [filing a Github issue](https://github.com/tensorflow/tensorflow/issues)
3706a83b0787f2f5037eed2f2f47cc76b94bc740aebPete Wardento ask for help.
371