How to compile ios example in tensorflow - tensorflow

I just realized the tensorflow has supported ios now. But how to compile the example in contrib/ios_examples directory?
thanks!
josh

We're still finishing off all the documentation, but here's a draft of the README I'll be adding to the ios_examples directory. I'd be interested to hear if this helps, and if you have ideas for improvements.
TensorFlow iOS Examples
This folder contains examples of how to build applications for iOS devices using TensorFlow.
Building the Examples
You'll need Xcode 7.3 or later, with the command-line tools installed.
Follow the instructions at tensorflow/contrib/makefile to compile a static library containing the core TensorFlow code.
Download Inception v1, and extract the label and graph files into the data folders inside both the simple and camera examples.
Load the Xcode project inside the simple subfolder, and press Command-R to build and run it on the simulator or your connected device.
You should see a single-screen app with a "Run Model" button. Tap that, and you should see some debug output appear below indicating that the example Grace Hopper image has been analyzed, with a military uniform recognized.
Once that's been successfully run, make sure you have a real device connected and open up the Xcode project in the camera subfolder. Once you build and run that, you should get a live camera view that you can point at objects to get real-time recognition results.
Troubleshooting
If you're hitting problems, here's a checklist of common things to investigate:
Make sure that you've run the download_dependencies.sh and compile_ios_protobuf.sh scripts before you run compile_ios_tensorflow.
Check that you have version 7.3 of Xcode.
If there are Eigen errors, look inside the build settings of your Xcode project. In the Search Paths section, you'll see an Eigen include directory that changes with each version of the framework. You may need to update this to may the version in your tensorflow/contrib/makefile/downloads folder.
If there's a complaint about no Session's registered, that means that the C++ global constructors that TensorFlow relies on for registration haven't been linked in properly. You'll have to make sure your project uses force_load, as described below.
Creating your Own App
You'll need to update various settings in your app to link against TensorFlow. You can view them in the example projects, but here's a full rundown:
The `compile_ios_tensorflow.sh' script builds a universal static library in tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a. You'll need to add this to your linking build stage, and in Search Paths add tensorflow/contrib/makefile/gen/lib to the Library Search Paths setting.
You'll also need to add libprotobuf.a and libprotobuf-lite.a from tensorflow/contrib/makefile/gen/protobuf_ios/lib to your Build Stages and Library Search Paths.
The Header Search paths needs to contain the root folder of tensorflow, tensorflow/contrib/makefile/downloads/protobuf/src, tensorflow/contrib/makefile/downloads, tensorflow/contrib/makefile/downloads/eigen-eigen-, and tensorflow/contrib/makefile/gen/proto.
In the Linking section, you need to add -force_load followed by the path to the TensorFlow static library in the Other Linker Flags section. This ensures that the global C++ objects that are used to register important classes inside the library are not stripped out. To the linker, they can appear unused because no other code references the variables, but in fact their constructors have the important side effect of registering the class.
The library doesn't currently support bitcode, so you'll need to disable that in your project settings.

Related

Properly embedding custom frameworks into a project in Xcode 5

It's getting quite frustrating with Xcode 5 here. All I'm trying to achieve is embedding some custom Cocoa frameworks into my project and create two versions of the app, one for the Mac App Store and one for a custom Online Store (so that when building for the MAS there'll be a folder called Debug (MAS) so I can distinguish it from the other version).
I embedded three frameworks into the project (only god knows why only one project can have another one embedded at a time, to hell with this limitation) and added their products in the "Link binary with libraries" and "copy frameworks" build phase. The finished built products are at the default location in the Library.
Now here's the thing - every time I'm using custom build configuration files other than "Debug" and "Release", the frameworks are NOT copied to the custom build folders but instead just go into "Debug" and "Release" regardless of any build options of the main app. Also, the frameworks are always built using "Debug" and are no longer connected to the current build mode (test, archive, etc.). To cut a long story short, this is a huge mess with file paths and obviously a lot of bugs concerning custom frameworks and custom build configurations.
Now my question is - there has to be an official or working way of maintaining an Xcode project that is both distributed over the MAS and a custom online store (two versions) and has at least one custom framework embedded. How do all other developers have solved this problem, I feel like I'm doing something fundamentally wrong and if I do, sorry for putting the blame on Xcode but something's for sure: Xcode's path management with external components is a chaos and the cause for unlimited mailing list and forum posts...
The answer is to create separate targets for the MAS & non-MAS app. You can add additional targets to build the custom frameworks and make the different targets dependent on each other (as necessary). Once this is all setup (properly) then building any of the targets will build any dependent targets (with the same build flags). And AFAIK there's nothing preventing an Xcode project from including multiple sub-projects so I haven't a clue why you believe this to be the case.

Building a distributable static library that uses cocoapods

I'm building a static library to be distributed to other iOS developers and having some trouble configuring the linker to allow the static library to be used in another app. I have used this guide to create a MyStaticLibrary.framework bundle containing the lib itself, and other assets such as images. This builds successfully and uses cocoapods to source the required dependencies (AFNetworking, etc.). So far, so good.
But when I import MyStaticLibrary.framework into a new Xcode project to test build an app with the library, I get tons of linker errors (Undefined symbols for architecture i386, _OBJC_CLASS_$_CLASSNAME) indicating that I'm doing something very wrong here.
So my question is, how can I build MyStaticLibrary.framework with the dependencies sourced from cocoapods, such that I can provide a 3rd party with just my framework file and allow them access to all functions specified in the public headers?
Any libraries you include using CocoaPods will not be compiled into your framework by default - they're meant to be external dependencies that are not part of your actual product. However, according to their FAQ, they support a mode where you can download pods and not have them linked to your project. From their FAQ:
Note that CocoaPods itself does not require the use of a workspace. If
you prefer to use sub-projects, you can do so by running pod install
--no-integrate, which will leave integration into your project up to you as you see fit.
To include external dependencies in your compiled binary:
For code: Instead of using cocoapods, check out the repositories you want to include and copy the source files into your project -- this will ensure they are compiled with the rest of your code
For static libraries (i.e. .a files), in your framework's Link Binary With Libraries build phase, make sure to include all the ones you would like to compile. You should also make sure the associated header files are included in Copy Headers build phase, with the appropriate visibility.
Note When bundling third party libraries in this way, you run the risk of conflicting with the projects that are integrating your framework. For example, let's say you are using a lib called SOSomeView, and you choose to compile that in with your framework. Now, if the app you are integrating with also includes SOSomeView, you will get a compile-time error that the class is declared twice. To fix this issue, you should re-namespace any external dependencies you want to hardcode into your framework (i.e. rename the class to XXSOSomeView).
I don't know how to solve that problem if you are compiling static libraries in with your framework.

Xcode: how to build a static library project correctly?

This question will be easy for Xcode pros but for a MonoTouch developer it seems to be impossible to resolve. :-)
I'm using Xcode 4.5 and I want to target iOS 5.1 and above and iOS Simulator 5.1 and above.
I have a a library project here and it is coming with a prebuilt binary named "DemoLib" (no extension and it is 11MB in size). The library is a fat lib for Simulator and iOS 5.1+.
I can use that library without any problem.
However if I try to build the library myself, I end up with a "DemoLib.a" file (notice the extension and the size of 30MB). How can I get the same build result? What is a .a file compared to the file without extension?
I tried to build the project "for running", and "for archiving" in Xcode. Both results in the same 30MB .a file.
I was expecting some dropdown in Xcode where one could select "DEBUG" or "RELEASE" build and the latter one would create the smaller lib.
Of course I could never tell without seeing the framework's project file. Having said that, there is an excellent guide to creating and compiling iOS frameworks here: https://github.com/jverkoey/iOS-Framework
Using the above guide, you should be able to recreate your framework's project from scratch, add the files you have to it, and properly compile it.
Hope this helps! :)
Did it come with a Makefile? Create a new target, set the build settings of the target to what's in the Makefile, then set your project to depend on that new target.
A file with the .a is a static library, which means it depends on nothing external and all the code it needs is compiled inside it. I think no extension generally implies dynamic library, which means it'll depend on some dependencies being present on your system to link against. Maybe that's why the .a is so much bigger. I think Xcode will build static by default because iOS does not allow the use of dynamic libraries.
The dropdown for what to build is in your scheme. Command+shift+< to view your scheme. Within the scheme you can edit which environment each method of building will use.

Cocos2d Targeting iPhone/iPad/Mac

I recently did some research on making a cocos2d app for iPhone/iPad AND Mac. I have done the iPhone/iPad route but have never done it with a Mac target. It appears that some people have added it as a target but mentioned that it is finicky and others have suggested making a separate Cocos2d Mac project that uses the same files. Any wisdom to impart here?
I believe it is absolutely crucial to have both iOS and Mac targets in the same project. Otherwise you'll spend too much time keeping one platform in synch with the other, until eventually you either manage to create a good (but still time-consuming) workflow - or end up neglecting one of the two platforms.
Ideally the code base should make as little use as possible of compiler macros. You'll want to compile both iOS and Mac code even if it's not being used for one platform. So having some classes or methods that are #ifdef'ed to Mac, others to iOS, will more often than not lead to compile errors when you switch targets. That means wrapper classes, so that you can write the same code regardless of the platform, are essential.
Right now, Cocos2D doesn't offer you to create iOS & Mac targets in the same Xcode project. The way to get there isn't immediately obvious either, because each target requires its own build settings for: Base SDK, SDK Root, Deployment Target, Architectures and possibly Compiler version. It gets worse if you also want to use 3rd party libraries (Box2D, Chipmunk, etc) because in some cases you'll be forced to create iOS and Mac specific targets for those libraries as well - if only to ensure that the library is built with the same compiler as the project's target, otherwise you can run into the strangest build or runtime issues.
I've had issues getting these platform specific targets to work within a single Xcode project without Xcode complaining or otherwise misbehaving. I haven't tried it with Xcode 4.1 and 4.2. By that time I had created .xcconfig files to host the build settings. The .xcconfig files may or may not be necessary with the more recent Xcode versions but they definitely make managing multiple platform-specific targets easier.
Long story short, the best and easiest way to do cross-platform development with cocos2d-iphone is by using Kobold2D.
Most of the 15 template projects have an iOS and Mac target in each project, you just need to select the corresponding scheme, then hit build & run. The most commonly needed platform-specific code (processing user input) is wrapped in a platform-agnostic, simple to use wrapper class KKInput.
Disclaimer: I'm the developer of Kobold2D. There's a slim chance that I may be biased. You should try Kobold2D anyway. :)

Creating one static library for iOS and simulator for distribution

If you create a static library for iOS do you have to distribute the header file(s) with it or is there another way to get it to work?
Currently I have a single my_lib.a file for both device and simulator but when I drag it into another test app to use it, it says it can't find the header and that all the places I'm using it in the code are undeclared. So I figure I'm either doing something wrong, or I have to also send the appropriate header files with it.
Background to my process:
I've seen two guides for creating a static library for both device and simulator. One on this site: Build fat static library (device + simulator) using Xcode and SDK 4+
and one here: http://mark.aufflick.com/blog/2010/11/19/making-a-fat-static-library-for-ios-device-and-simulator
I used the second site to just try it out. I'm also a bit curious if I did it correctly. I just went into the Release-iphone(os|simulator) folders and found the .a in the ios one and the .o in the simulator one.
The short answer is yes, you have to package header files with your static library. You have to package header files with any library in fact, dynamic or static. The library itself contains the compiled code, but you still have to tell the compiler about the identifiers in the library so when it's compiling your code it knows that they exist.
If you care, you can package your static library into a static framework with a little care. You simply create the same directory structure that a dynamic framework has, with your .a file in place of the .dylib (or .so) file. Frameworks contain a directory for headers, so you can distribute the binary and headers as a single package, and you can easily import headers from a framework without messing with the Additional Header Search Paths build setting.
Just in case it's useful - I followed Ray Wenderlich's instructions from here and was able to produce a framework for iOS that supported several architectures at once (including the simulator). The instructions are a bit too long to just copy-paste here.