Thursday, 3 July 2008

Creating an universal static OpenCV library with iPhone support

This post has been updated here. Sorry I have no time to upgrade the iPhone part, I hope someone will share this knowledge ;)

We will create a minimal static universal OpenCV 1.0.0 library with 4 architectures: Intel, PowerPC, x86_64 and Arm for the iPhone. I've been testing it on Leopard and Snow Leopard but it should work on any Mac OS X version.

First checkout or untar the OpenCV sources in the opencv-1.0.0 directory. Then, on the same level (not inside) create a build directory with 4 subdirectories: ppc, i386, x86_64 and arm. (Download the code from Sourceforge)

Then set the global configure settings:
$ export CONFFLAGS="--without-imageio --without-python --without-swig --disable-apps --disable-dependency-tracking --without-carbon --without-quicktime --enable-shared=no --without-gtk"
in the ppc dir:
$ ../../opencv-1.0.0/configure ${CONFFLAGS} --target=ppc-apple-darwin9
$ make CXXFLAGS="-arch ppc"
in the i386 dir:
$ ../../opencv-1.0.0/configure ${CONFFLAGS} --target=i386-apple-darwin9
$ make CXXFLAGS="-arch i386"
in the x86_64 dir:
$ ../../opencv-1.0.0/configure ${CONFFLAGS} --target=x86_64-apple-darwin9
$ make CXXFLAGS="-arch x86_64"

in the arm dir:
$ ../../opencv-1.0.0/configure ${CONFFLAGS} --host =arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.2.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
$ make
the last one is tough, so let's see the variables one by one:
CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.2.1
CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk"
CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
Ok. Now for the universal static libs:
$ lipo -create i386/cv/src/.libs/libcv.a x86_64/cv/src/.libs/libcv.a ppc/cv/src/.libs/libcv.a armv6/cv/src/.libs/libcv.a -output libcv.a
$ lipo -create i386/cxcore/src/.libs/libcxcore.a x86_64/cxcore/src/.libs/libcxcore.a ppc/cxcore/src/.libs/libcxcore.a armv6/cxcore/src/.libs/libcxcore.a -output libcxcore.a
$ lipo -create i386/cvaux/src/.libs/libcvaux.a x86_64/cvaux/src/.libs/libcvaux.a ppc/cvaux/src/.libs/libcvaux.a armv6/cvaux/src/.libs/libcvaux.a -output libcvaux.a
$ lipo -create i386/ml/src/.libs/libml.a x86_64/ml/src/.libs/libml.a ppc/ml/src/.libs/libml.a armv6/ml/src/.libs/libml.a -output libml.a
$ lipo -create i386/otherlibs/highgui/.libs/libhighgui.a x86_64/otherlibs/highgui/.libs/libhighgui.a ppc/otherlibs/highgui/.libs/libhighgui.a armv6/otherlibs/highgui/.libs/libhighgui.a -output libhighgui.a

That's all. Oh, try
$ make -j 2

36 comments:

William Dahlberg said...

This has been a great help for me. Building libraries can be tricky, so thanks for sharing!

Fabio Cionini said...

Hi, thanks for your precious effort, by following your instructions I have been able to make some OpenCV work on the iphone.
However I'm stuck with an issue that probably is beyond my knowledge.
I'm trying to use cvHaarDetectObjects to do some silly face tracking. For now I just track the coordinates of a face in a photo on the system log, no graphics at all.
Well it's working on the iPhone Simulator, but when I deploy to the real device, it doesn't detect any face anymore. No errors, no warnings, it just seems the face is not there.
Seems it's some platform related issue (Intel vs ARM). Could it be that the library compiles differently on the two platforms and one of them exclude some functionality?

ildan said...

I have no idea, sorry. Maybe an OpenCV bug?

A.S. said...

Good tutorial. Why not post it on the OpenCV wiki? http://opencv.willowgarage.com/wiki/

ildan said...

Good idea. I added a link to the wiki Mac OS X OpenCV Port page.

Phillip Whisenhunt said...

Hi, this may be a rather dumb question, but i was wondering how i would actually include the library in my project? do i need to just add in the folder? or....?

ildan said...

Good question.

Leaving to the academy the "right" way for GCC under UNIX to do that, just add the path to the libraries on the GCC command line.

In XCode that means adding the full paths of the 3 OpenCV libs to the "Other Linker Flags" option in the Project->Build tab.

Michael Lujan said...
This comment has been removed by a blog administrator.
Anonymous said...

The cvHaarDetectObjects doesn't work for me :(, that's bad news

Anonymous said...

Detection works fine for me (on both simulator and hardware), but way to slow - processing of 320x240 image with 3 faces on it takes about 6 seconds.
Trying to speed it up a little...

Anonymous said...

I just don't get it working. Could you help me?

a) I've got a folder "opencvlibrary". Inside this folder there are the folders
"branches"
"build"
"tags"
"trunk"
Inside the folder "trunk" there are the folders:
"opencv"
"opencv_extras"
I added the folder "build". Inside this folder I created the folders
"armv6", "i686" and "ppc"

Everything correct so far?

b) I don't have to put anything manually into these folders, since this is going to do the compiler, right?

c) Then I am supposed to set the global configure settings
$ export CONFFLAGS="--without-imageio --without-python --without-swig --disable-apps --disable-dependency-tracking --without-carbon --without-quicktime --enable-shared=no --without-gtk"

I have to run this in the terminal without the $, right? Where do I have to run this? In "opencvlibrary/trunk/opencv/"?

d) I went into the "armv6" directory and pasted
../../opencv/configure ${CONFFLAGS} --host=arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp

into the terminal. It resulted into an error.
Make as well resulted into an error.

Any help would be really appreciated!

Best regards

Jelmer said...

I've just updated to the 3.0 SDK and I can't build the opencv static lib as described in the tutorial. I get an error message from the compiler when trying to make the armv6 version. Any ideas?

aleor said...

I have some problems with the iPhone SDK 3.0 too. I'm still working on it. I will try to post a solution as soon as possible.
I made an application for iPhone OS 2.2. I used the OpenCV ant it worked just fine for face detection. I implemented some methods to convert from UIImage to IplImage, because the LoadImage function didn't work.
App Store link http://appshopper.com/entertainment/morphing-animal

aleor said...

Finally I compiled the OpenCV static library using the iPhone SDK 3.0.
In order to compile with the iPhone OS 3.0 platform it's a very important to do the installation of the new iPhone SDK 3.0 in another directory different to /Developer.
The g++ compiler used to compile should be that one that comes with iPhone SDK 2.2 g++ located inside /Developer folder.
The only thing to change after this point is in the arm architecture build step, the reference to the new iPhone OS 3.0 Platform installed in the new Folder. Now the cross compilation use the iPhoneOS3.0 sources, just cool.
I'm testing the statics lib .a files arm architecture on an iPhone 2.2.1 and it works ... I will test it with the iPhone 3.0 soon ...

ildan said...

Thanks aleor for your hints!

aleor said...

My last post worked in the real iPhone OS 3.0.
I tested it 2 weeks ago.
my email: almeida80gmail.com

Jagat said...

I am getting some basic error while compiling opencv, can you please guide ?

subrahmanyam-chaturvedulas-imac:opencv kavapanga$ export CONFFLAGS="--without-imageio --without-python --without-swig --disable-apps --disable-dependency-tracking --without-carbon --without-quicktime --enable-shared=no --without-gtk"
subrahmanyam-chaturvedulas-imac:opencv kavapanga$ cd build/armv6/
subrahmanyam-chaturvedulas-imac:armv6 kavapanga$ ../../opencv/configure ${CONFFLAGS} --host=arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
-bash: ../../opencv/configure: No such file or directory
subrahmanyam-chaturvedulas-imac:armv6 kavapanga$ pwd
/Users/kavapanga/desktop/opencv/build/armv6
subrahmanyam-chaturvedulas-imac:armv6 kavapanga$ ../../../opencv/configure ${CONFFLAGS} --host=arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
-bash: ../../../opencv/configure: No such file or directory
subrahmanyam-chaturvedulas-imac:armv6 kavapanga$ ../opencv/configure ${CONFFLAGS} --host=arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
-bash: ../opencv/configure: No such file or directory
subrahmanyam-chaturvedulas-imac:armv6 kavapanga$ ./configure ${CONFFLAGS} --host=arm-apple-darwin9 CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.0.1 CXXFLAGS="-arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS2.0.sdk" CXXCPP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/cpp
-bash: ./configure: No such file or directory

Anonymous said...

Hi~, Jagat
You'd better execute "$ ~/.bashrc" after the first step, "$ export CONFFLAGS="--~~~~.

duettro

Anonymous said...

Hi~, Jagat, duettro
You'd better execute "$source .bashrc" after the first step, "$ export CONFFLAGS="--~~~~.

new duettro

jeffreality said...

I'm getting the same problem as Jagat above...

Any suggestions? The armv6 configure command just dies displaying the following info...

-----

configure: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used.
checking build system type... i386-apple-darwin9.8.0
checking host system type... arm-apple-darwin9
checking target system type... arm-apple-darwin9
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-apple-darwin9-strip... no
checking for strip... strip
checking for a thread-safe mkdir -p... ../../opencv/autotools/install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make sets $(MAKE)... (cached) yes
checking for style of include used by make... GNU
checking for C++ compiler default output file name...
configure: error: in `/Users/jeffrey/Documents/opencv/build/armv6':
configure: error: C++ compiler cannot create executables
See `config.log' for more details.

nacho4d said...

Hi,
Have you trying compiling OpenCV-2.0.0 ?
I am trying but above thing is not working.
I got
checking for C++ compiler default output file name...
configure: error: in `/Users/nacho4d/Downloads/OpenCV-2.0.0/build_armv6':
configure: error: C++ compiler cannot create executables

I wonder what am I doing wrong?

Krog said...

I am also trying to compile for openCV 2.0 with no success. Has anyone managed to get it to work?

Cheers!

Miha said...

HEllo!

Can someone please help me with these basics:
"Then set the global configure settings:"
Does that mean i have to add code that follow ($ export CONFFLAGS="--withou...) to file "configure" in OpenCV folder? And then create this file in other folders i created (ppc, i686 and armv6) ? Tnx in advance!

ildan said...

Miha, those are commands you have to type in a terminal window. To open a terminal window use the Terminal.app application

Miha said...

ildan thank you so much! now im finally getting some progress.
But im stuck again at "universal static libs:" where i get following response:
"lipo: can't open input file: i686/cv/src/.libs/libcv.a (No such file or directory)"
everything went well till that point.
Am i missing something?

ildan said...

Guys, thanks for all your comments, but I'm sorry, I have not been working with OpenCV for a long time, so I do not have suggestions about the new 2.0 release nor about Snow Leopard issues, etc.

Anyway, if someone feels about kindly posting updates and corrections on the subject, don't be shy! Leave a comment!

Jonathan deBoer said...

Here is the process I just used to create a universal-binary version (static and dynamic) of opencv-1.0.0 on OSX 10.5

Note: I have previously installed zlib, libpng, libjpeg, and libtiff

Start from the directory where you uncompressed opencv, '$>' indicates the start of a new terminal command

$> mkdir -p build/ppc
$> mkdir -p build/i686
$> export CONFFLAGS="--enable-png --enable-zlib --enable-jpeg --enable-tiff --enable-static --disable-dependency-tracking"
$> export UNIV_FLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4"
$> cd build/ppc/
$> CFLAGS="-I/usr/local/include ${UNIV_FLAGS}" LDFLAGS="-L/usr/local/lib ${UNIV_FLAGS}" ../../configure ${CONFFLAGS} --host=ppc-apple-darwin9
$> make CXXFLAGS="-I/usr/local/include ${UNIV_FLAGS} -arch ppc -Wall -fno-rtti -pipe -O3 -g -mcpu=G3 -mtune=G5 -fomit-frame-pointer"
$> cd ../i686
$> CFLAGS="-I/usr/local/include ${UNIV_FLAGS}" LDFLAGS="-L/usr/local/lib ${UNIV_FLAGS}" ../../configure ${CONFFLAGS} --host=i686-apple-darwin9
$> make CXXFLAGS="-I/usr/local/include ${UNIV_FLAGS} -arch i386 -Wall -fno-rtti -pipe -O3 -g -march=prescott -ffast-math -fomit-frame-pointer"
$> find . -name *.dylib | while read ln; do if [ ! -L $ln ]; then echo $ln; fi; done > ../liblist
$> find . -name *.a >> ../liblist
$> find . -name *.so >> ../liblist
$> find . -name *.la > ../lalist
$> tar -cf ../i686.tar .
$> cd ..
$> mkdir universal
$> cd universal
$> tar -xf ../i686.tar
$> cd ..
$> cat liblist | while read ln; do lipo -create i686/$ln ppc/$ln -output universal/$ln; done;
$> cat liblist lalist | while read ln; do touch universal/$ln; done
$> cd universal/apps
$> make clean
$> make CXXFLAGS="-I/usr/local/include ${UNIV_FLAGS} -arch i386 -arch ppc -Wall -fno-rtti -pipe -O3 -g -fomit-frame-pointer"
$> cd ..
$> sudo make install

Anonymous said...
This comment has been removed by a blog administrator.
Dennis Miao said...
This comment has been removed by the author.
Dennis Miao said...

Hi Miha,

You mentioned you got the problem "lipo: can't open input file: i686/cv/src/.libs/libcv.a (No such file or directory)". Have you solved that now? I met the same problem when I was setting up.

Guys, I'm using OS3.0 and OpenCV-2.0.0. Everything's perfect except the question above. Does that mean the "make" process isn't perfectly done?

Dennis Miao said...

Hi,

I downloaded the old version of OpenCV, version 1.1.0. Now the script will create "cv" folders etc. But I got a worse question: when come to i686, it will encounter lots of errors and quit. Here's the strange error messages:

{standard input}:20173:non-relocatable subtraction expression, "LC4" minus "L00000000038$pb"
{standard input}:20173:symbol: "L00000000038$pb" can't be undefined in a subtraction expression
{standard input}:20160:non-relocatable subtraction expression, "LC4" minus "L00000000038$pb"
{standard input}:20160:symbol: "L00000000038$pb" can't be undefined in a subtraction expression

{standard input}:unknown:Undefined local symbol L00000000026$pb
{standard input}:unknown:Undefined local symbol L00000000027$pb
{standard input}:unknown:Undefined local symbol L00000000034$pb
{standard input}:unknown:Undefined local symbol L00000000037$pb
{standard input}:unknown:Undefined local symbol L00000000038$pb

There're lots of errors like this. I don't know what to do. I'm new to iPhone programming, I've no idea what to do. Could you tell me how to delete the staff so I can try that again? Or I have to reinstall my OS X?

BTW, I've tried to delete the contents in i686, and rebuild, but still got the same error messages.

Thanks in advance!

Dennis Miao said...
This comment has been removed by the author.
Dennis Miao said...
This comment has been removed by the author.
Dennis Miao said...

Hi Miha,

I think I find your problem, because the OpenCV2.0.0 changed the file structure a bit, there's a src folder under the root directory, check that out and change the path in the command.

But does anyone succeed in compiling the last one, the arm one? like some guys said, I got the same problem: configure: error: in `/Users/dennismiao/Desktop/opencv-2.0/build/armv6':
configure: error: C++ compiler cannot create executables
See `config.log' for more details.

Can someone help me plz.

This is really..... for me who are not familiar with UNIX, it's really painful to spend 5 hours a day to try to make it work....

Dennis Miao said...

Hi guys, http://github.com/niw/iphone_opencv_test, this compiles perfectly, just scroll down and read the readme. I used it to compile the iPhone SDK3.1, no problem at all. But I only did with opencv 1.1, haven't tried 2.0. Whew!! at last....

ildan said...

Hi all, I have updated the post here: http://ildan.blogspot.com/2009/11/creating-universal-static-opencv.html

:)