SmartBody : Building SmartBody for iOS

Requirments

To run SmartBody on iOS devices you will need:

  • Mac computer, where you should have fairly recent mac operating system.
  • iOS device on which the software should also be recent.
  • Apple developing ID which allows you to develop on your devices.
  • XCode whose downloads require apple ID, it's also the porter where you download the application onto your device.

To be more clearly, all the things required for developing iOS application doesn't have to be all up-to-date, but they need to be matching versions and if you accidentally upgrade your device there's no backward compatibility. It's always a good habit to keep updating all your software. 

Due to software version problem, the xcode version and location described below are yield to change.

Compiling with console

There's many steps in the following tables, but you can choose either build yourself or pre-built version can be found at trunk/ios/libs/iphoneos

 

Compiling using console

1

Cross compiling apr (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Copy setup-iphoneos.sh from trunk/ios/activemq/apr to the folder where you extracted the above downloaded contents.
  • Change the SBROOT inside setup-iphoneos.sh to your trunk directory. 
  • Make sure you have gcc-4.2 installed on the system. If not, please download the version of xcode 4.02 iOS4.3 which contains gcc-4.2 and install it (make sure you change the installation folder to something other than /Developer, make it something like /Developer-4.0, uncheck update system environment options). You can download previous xcode4.02 from https://developer.apple.com/downloads/index.action , search for xcode 4.02 iOS4.3. P.S. Latest xcode 4.2 and iOS5.0 is using LLVM GCC compiler which has trouble building apr, apr-util and activemq, not sure if it can compile the other third party library, for now just stick on gcc4.2.
  • If, in the previous step, you had to download a different version of xcode, make sure in both the scripts, you change the following variable from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to

    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run setup-iphoneos.sh
  • Go to trunk/ios/activemq/apr/iphone*/include/apr-l
    • edit line 79 of apr_general.h to be: -
      • #if defined(CRAY) || (defined(__arm) && !(defined(LINUX) || defined(__APPLE__)))
2

Cross compiling apr-util (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Copy setup-iphoneos.sh from trunk/ios/activemq/apr-util to the folder where you extracted the above downloaded contents.
  • Change the SBROOT inside setup-iphoneos.sh to your trunk directory
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the DEVROOT variable in the scripts as in the previous step from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to
    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run setup-iphoneos.sh

 

3

Cross compiling activemq-cpp-library (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Copy setup-iphoneos.sh from trunk/ios/activemq/activemq-cpp to the folder where you extracted the above downloaded contents.
  • Change src/main/decaf/lang/system.cpp line 471 inside activemq folder (above mentioned folder) from "#if defined (__APPLE__)" to "#if 0"
  • Change the SBROOT inside setup-iphoneos.sh to your trunk directory
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the DEVROOT variable in the scripts as in the previous step from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to
    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run setup-iphoneos.sh

Note: for smartbody iphone running on unity, we need to rename variables inside activemq-cpp-library decaf/internal/util/zip/*.c to avoid conflict symbols. If you don't want to do that, you can directly use the one under trunk/ios/activemq/activemq-cpp/libs/activemq-unity

4

Cross compiling xerces-c (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Copy setup-iphoneos.sh from trunk/ios/xerces-c to the folder where you extracted the above downloaded contents.
  • Change the SBROOT inside setup-iphoneos.sh to your trunk directory
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the DEVROOT variable in the scripts as in the previous step from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to
    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run setup-iphoneos.sh
5

Cross compiling ODE (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Copy setup-iphoneos.sh from trunk/ios/ode to the folder where you extracted the above downloaded contents
  • Change the SBROOT inside setup-iphoneos.sh to your trunk directory
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the DEVROOT variable in the scripts as in the previous step from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to
    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run setup-iphoneos.sh
6

Cross compiling clapack (Not required. If you chose not to cross compile, make sure you add Acceleration framework from xcode project)

  • Copy toolchain-iphone*.cmake and setup-iphone*.sh from trunk/ios/clapack to the folder where you extracted the above downloaded contents
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the IPHONE_ROOT variable in the toolchain-iphone*.cmake from -
    • /Developer/Platforms/iPhoneOS.platform/Developer to
    • /Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • To make a Unity compatible build, you need to modify the cmake file. If not used for Unity Iphone, you can skip the following step:

    -Go to clapack/CMakeLists.txt, comment out include(CTest) and add_subdirectory(TESTING)
    -Go to clapack/BLAS/CMakeLists.txt, comment out add_subdirectory(TESTING)
    -Go to clapack/F2CLIBS/libf2c/CMakeLists.txt, take out main.c from first SET so it became
            set(MISC
            f77vers.c i77vers.c s_rnge.c abort_.c exit_.c getarg_.c iargc_.c
              getenv_.c signal_.c s_stop.c s_paus.c system_.c cabs.c ctype.c
             derf_.c derfc_.c erf_.c erfc_.c sig_die.c uninit.c)
     -Go to clapack/SRC/CMakeLists.txt, take out ../INSTALL/lsame.c from first SET so it became
            set(ALLAUX  maxloc.c ilaenv.c ieeeck.c lsamen.c  iparmq.c    
                ilaprec.c ilatrans.c ilauplo.c iladiag.c chla_transtype.c
            ../INSTALL/ilaver.c) # xerbla.c xerbla_array.c

  • Change the SBROOT inside setup-iphoneos.sh
  • Run setup-iphoneos.sh
7

Cross compiling python (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Go to trunk/ios/python, modify the SBROOT inside setup-iphoneos.sh
  • If in the step 1, you had to download the gcc-4.2 (from xcode), change the DEVROOT variable in the scripts as in the previous step from -
    • export DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer to
    • export DEVROOT=/Developer-4.0/Platforms/iPhoneOS.platform/Developer (if you installed the xcode in /Developer-4.0)

  • Run the script, you may need to add sudo before the script in case the copying step fails (last step is to copy libpython2.6.a out)
  • Execute "chmod +w libpython2.6.a" command in the console to make libpython2.6.a writable.
  • Run setup-iphoneos.sh.
8

Cross compiling libsndfile (You can find prebuilt library at trunk/ios/libs/iphoneos)

9

Cross compiling freealut (You can find prebuilt library at trunk/ios/libs/iphoneos)

  • Download freealut from https://github.com/vancegroup/freealut
  • Copy CMakeList.txt, setup-iphoneos.sh and toolchain-iphoneos.cmake to downloaded freealut top level.
  • Change the SBROOT inside setup-iphoneos.sh
  • Run setup-iphoneos.sh
10

Cross compiling pocket sphinx (Not required)

Download from http://www.rajeevan.co.uk/pocketsphinx_in_iphone/. The steps are on the website.   

 P.S.

  • Since the results are not that good on Unity and I don't have time fully test out, the code is not intergrated into smartbody yet.
  • When integrating pocketsphinx with Unity, it would have duplicated symbol problem(this might be the reason of bad recognizing result, it's under sphinx/src/util). I already built a library for Unity that can be used directly.
  • Also for Unity you may need get prime31 iphone plugin AudioRecorder

Compiling with XCode

Libraries

 Compiling using Xcode4
1

Build bonebus

  • Open smartbody-iphone.xcworkspace, select the scheme to be bonebus, build
2

Build boost libraries (You can find prebuilt library at trunk/ios/libs/iphoneos, version 1.51)

  • Open boost/boost.xcodeproj, select boost_system, boost_filesystem, boost_regex, boost_python, build them seperately. Make sure the hearder search path and lib search path are correct according to boost version. Also make sure that source files for each target are included properly under xcode project according to the right boost version.
3

Build steersuite

  • Open smartbody-iphone.xcworkspace, select the steerlib, pprAI, build them seperately.
4

Build vhmsg

  • Open smartbody-iphone.xcworkspace, select scheme vhmsg and build.
5

Build vhcl

  • Open smartbody-iphone.xcworkspace, select scheme vhcl and build.
6

Build wsp

  • Open smartbody-iphone.xcworkspace, select scheme wsp and build.
7

Build smartbody-lib (Currently including boost1.5, python2.65)

  • Open smartbody-iphone.xcworkspace, select scheme smartbody-lib and build.

P.S. This xcode project needs maintenance by the developer to make sure it incorporates all the file from SmartBody core.

8

Build smartbody-dll  

  • Open smartbody-iphone.xcworkspace, select scheme smartbody-dll and build.
9

Build vhwrapper-dll (Not required, for Unity only)

  • Open smartbody-iphone.xcworkspace, select scheme vhwrapper-dll and build.

Applications

Once those steps have been completed, you can build any of three applications:

  • smartbody-openglES - a simple example of using SmartBody with OpenGL
  • smartbody-ogre - an example of using SmartBody with the Ogre3D rendering engine
  • smartbody-unity - The Unity3D game engine connected to SmartBody.

Make sure that your iOS device is connected and follow any of the three applications below:

 Building smartbody-openglES
1

Build smartbody-openglES

    Go to trunk/ios/applications/minimal, open smartbody-iphone.xcodeproj, build and run.

P.S. Under smartbody-openglES project Frameworks, you should see all the libraries existing. If not, go over previous steps to check if anything is wrong

 Building smartbody-ogre
1Build ogre iphone
  • Make sure all the libraries exist inside build/lib/Debug

 

2

Build smartbody ogre application

  • Go to trunk/ios/applications/ogreIphone, open smartbody-ogre.xcodeproj
  • go to smartbody-ogre project, set OGRE_SDK_ROOT to your ogreSDK directory,
  • set OGRE_SRC_ROOT to your ogre source directory.
  • Select scheme smartbody-ogre, build and run.

p.s.

  • If the program hangs on boost thread function, try rebuild the ogre iphone dependencies boost libs (pthread, date_time), alternative way is to build the whole ogre iOS libraries with Boost symbol turned off which may affect the results.
  • ogre 1.8 seems to have trouble when building for iphone/ipad, use ogre 1.7.3.It is extremely slow running on armv6 ipod(after testing), and there's something wrong with the texture and shader. So maybe should just run on armv7 iPhone/iPad
 Building smartbody-unity
1

Check out the project

  • smartbody mobile minimal includes only smartbody while smartbody mobile can include all the other components like face detection, audio acquisition etc.
2

Build unity project into xcode

  • Open any scene from Assests e.g. smartbdoySceneOutDoor.unity
  • Copy the static libraries inside (SmartBody)trunk/ios/libs/iphoneos to (Unity)Assets/Plugins/iOS. Do not include liblapack.a libf2c.a libblas.a, these would cause duplicated symbol problems. Make sure you are using libactivemq-cpp.a for unity which you can get from trunk/ios/activemq-cpp/libs/activemq-cpp-unity.
  • Make sure your unity is under iOS platform.
  • Go to build setting, set the ios platform application name, resolution etc and hit build button.
3

Compile xcode project and run

  • Add Accelerate.framework(which contains the lapack library) into xcode project.
  • If you are using smartbody mobile minimal scenes, build and run!
  • If you are using smartbody mobile scenes. You will need to include CoreVideo.framework, CoreGraphic.framework, OpenAL.framework. Also make sure that in the xcode project setting, include the header search path for opencv_device; in the Libraries folder, drag in opencv_divice libraries. After above steps are done, build and run!

Notes

  • smartbody-iphone.xcworkspace needs to change if there's file changes under SmartBoby.
  • vhwrapper.h and vhwrapper.cpp are copied from VH svn, they are used to build smartbody unity application. So if these two files got changed outside, they have to be copied over again and modifies maybe needed to make it working.
  • Since python26 has only been built for iOS device, SmartBody won't be available on iPhone simulator for now. 



Comments:

You can compile the libraries using Xcode 4.3 and iOS SDK 5.1. (note that Xcode 4.0.2 will not run on Lion)  I managed to compile apr, apr-util, and activemq-cpp. You need to modify the script files, though.

1. you need to replace the "/Developer" path prefix for DEVROOT with "/Applications/Xcode.app/Contents/Developer"

2. change the SDK version to 5.1

3. for the iphoneos scripts, replace the compiler variables with

export CPP="$DEVROOT/usr/bin/gcc -E"
export CXX="$DEVROOT/usr/bin/g++"
export CC="$DEVROOT/usr/bin/gcc"
export LD="$DEVROOT/usr/bin/ld"

the trick here is to define cpp as "gcc -E"

Posted by leuski at Apr 17, 2012 20:49

It is convenient to build fat libraries for iOS development: then you do not have to worry about including the correct library when selecting between simulator and device targets.

After you build libraries for both device and simulator, run something like this with $1 set to the trunk/ios/libs:

ROOT_DIR=$1

for l in `ls "$ROOT_DIR/iphoneos/"`
do
echo $l
lipo -output $ROOT_DIR/$l \
-create -arch armv7 $ROOT_DIR/iphoneos/$l \
-arch i386 $ROOT_DIR/iphonesimulator/$l
done

It will generate .a files in trunk/ios/libs that you can include in your project. 

Posted by leuski at Apr 17, 2012 20:52

Yeah, it is good to build fat libraries. I think I ran into problem trying to build python for simulator targets. Same problem happens with few particular libraries. So I kept it separate to make all the libraries consistent. 

Posted by yxu at Apr 18, 2012 10:11

Thanks for the tips. I think there's a third way we can solve this problem, build gcc 4.2 from source (smile)

Posted by yxu at Apr 18, 2012 10:13

Here are my results of testing these steps.

Environment:
OSX 10.7.4
Xcode 4.3.2
Ipad 3

Used pre-compiled libraries instead of building my own (\trunk\ios\libs)

Updated Xcode project files to include the latest smartbody C++ files.

Committed headers of the 3rd party libs in the 'Compiling using console' section

Committed boost binaries to svn

Started with 'Compiling using Xcode4' section.
I skipped step #2 (committed binaries earlier)
I did the steps in that section in this order:
- 5 (vhcl). Note about vhcl_audio has been fixed in svn, so that's no longer needed
- 4 (vhmsg)
- 1 (bonebus)
- 6 (wsp)
- 3 (steersuite)
- 7 (smartbody-lib)
- 8 (smartbody-dll)
- 9 (vhwrapper-dll)

Recommendations:
- We should use CMake for this. That way we don't have to maintain separate projects.
We should be able to compile ios static libs (.a) through Cmake. <?>   Potential link here:
http://stackoverflow.com/questions/822404/how-to-set-up-cmake-to-build-an-app-for-the-iphone

- Headers and libs have been committed to /trunk/ios. We should modify the header locations to pull from 
\trunk\lib as much as possible to prevent duplication.

- We should also use vhwrapper-dll in the VH repo to prevent duplication.
This is how it's done on the windows/osx steps.

 

svn revisions:
r3552
r3570
r3571
r3572
r3573
r3575
r3577
r3578
r3579

 

Posted by fast at Jul 23, 2012 12:07
  • Yeah, i'm aware of using Cmake to compile automatically. Will look into that when i have time.
  • we can pull some code from trunk\lib, but for some particular libraries (e.g. python), we will need fixed version because the lib version won't compile.
Posted by yxu at Jul 23, 2012 12:13

A better way to build boost is to use boost.sh from https://gitorious.org/~galbraithjoseph/boostoniphone/galbraithjosephs-boostoniphone. It check a version of boost from boost svn repository, compiles boost into a framework that can be used by XCode or other build tools. It also builds a universal library for OSX in the same pass. You can find the script locally at https://svn.ict.usc.edu/svn_vh/branches/mNL/3rd_party/boost/

Posted by leuski at Nov 16, 2012 11:55