Project

General

Profile

How to compile for iOS

Added by Manuj LHT over 8 years ago

Hi,

I am creating an iOS app to display image metadata. The app is in Objective-C

I want to compile the library for iOS platform but instructions to do so are not present in the wiki.

I will be grateful if someone can teach me how to compile the library to work on the iOS platform and use in an Objective-C app. What will be the right architecture and flags to use.

Thanks a lot.


Replies (13)

RE: How to compile for iOS - Added by Robin Mills over 8 years ago

There are quite a lot of notes on the Wiki concerning building Exiv2 on the Mac. http://clanmills.com/exiv2/macosx.shtml

And I recently added notes about use CMake/Xcode on the Mac:
http://clanmills.com/exiv2/debugging-cmake.shtml and found the following concerning iOS and CMake:
https://code.google.com/p/ios-cmake/

For sure the library works fine with Obj/C and Cocoa on the Desktop. In fact, I discovered that Exiv2 was about 100x faster than Apple's Cocoa classes for extracting meta-data. Additionally, Exiv2 recognizes many more tags as well as makernotes, iptc and xmp metadata.

I have never developed for iOS, however I believe the process is almost identical to MacOSX. You probably have to set some environment variables to cross compile for iOS. In the notes http://clanmills.com/exiv2/macosx.shtml, I've discussed getting the compiler to target particular versions of MacOS-X. I googled up several blogs in which this is discussed. For example:

http://tinsuke.wordpress.com/2011/02/17/how-to-cross-compiling-libraries-for-ios-armv6armv7i386/ You'll see the author has documented his experience.

Perhaps you could "dig into" this subject and report your results back here. If you're successful, I'll acknowledge your findings by linking from http://dev.exiv2.org/projects/exiv2/wiki/How_do_I_build_Exiv2_on_the_XYZ_platform. If you're get stuck, I'll have a look at this next weekend.

Robin

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Hi Robin,

Thanks for your detailed reply. I will try your answer and will let you know ow it goes.

Regards.

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Hi Robin,

Using the links you posted and modifying them a little and hours of trial and error, I was able to cross compile EXIV2 and I obtained the headers and .a file.

I confirmed using lipo -i that indeed i386(simulator) and arm7 code is present is present in the library. I will detail the process later once I have my application running and I have proof of its complete working.

Now, I am facing another problem. XCode is unable to find the C++ standard library.

Here is my setup:

I have one XCode project which targets iOS SDK 6.0.

Inside it, there is a folder called exiv2 and it contains a header and lib folder. The exiv2 header and the .a library are in those folders.

When I compile, I get an error that in version.hpp

#include <string> : no such file or directory

Any ideas on how to link the C++ std in such a setup?

Thanks a lot.

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Hello Robin,

I think I was able to solve the above <string> not found problem by renaming the main.m to main.mm (this is the file where exifv2 is included. Renaming the main file (and linking with libstdc++ ?) got rid of that error.

But following the instructions of the following page : http://tinsuke.wordpress.com/2011/02/17/how-to-cross-compiling-libraries-for-ios-armv6armv7i386/

in the Project Configuration section, the author recommends to choose LLVM/GCC 4.2 as the compiler. This is done to remove the following error : Undefined symbols for architecture armv7: (even though lipo shows armv7 is present.

The problem with using LLVM/GCC 4.2 instead of LLVM 4.1 is that LLVM/GCC 4.2 does not support ARC.

Is there any way to get rid of "Undefined symbols for architecture armv7" error when compiling exiv2 for iOS SDK 6.0 without resorting to LLVM/GCC 4.2 ?

Thanks a lot.

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Hi Robin,

Sorry to say, even after diabling arc, I have come back to square one :

Undefined symbols for architecture i386:
"Exiv2::ImageFactory::open(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So, as of now, the "Undefined symbols for architecture i386" problem is not getting solved.

Please see if you can try and build the library for iOS SDK 6.0 and if you face the same problem.

I have not tried CMake though,

Much thanks for your time.

RE: How to compile for iOS - Added by Robin Mills over 8 years ago

Manuj

I can see you have done as I requested and you did "dig into" this. It's hard solving build engineering puzzles. That's what so great about solving them. It wouldn't be fun if it were easy.

At the moment, I'm overloaded with work in the office and with the Google Summer of Code project on Exiv2. I really can't look at this until the weekend. However let me suggest tools to explore the issues further.

lipo: you can use him to extract (and recombine) different architectures from binary files (libraries, dylibs and executables)

nm -g: use this to see the symbol table (imports and exports) from your binaries

otool -L: use that to see what your binaries are trying to load at run-time

install_name_tool: enables you to modify the dynamic linking tables (which you see with otool -L)

In this case, you probably don't need to know or use install_name_tool, however I'm enumerating essential build engineering weapons.

______________________________

The reason:
#include <string> has to be in a .mm file is because .mm is Obj/C++ and .m is Obj/C.

Statement such as:
#include <string> and
#include <map>

(with no .h) are C++ to include STL headers.

The languages C and Obj/C know nothing about STL (Standard template library).

______________________________

I have several suggestions about how to use the weapons for a successful attack on this:

1) Build a small library that does almost nothing, uses C++ and STL.
- it's easier to learn what's going on when you're dealing with something small.
- you might even get lucky and there's an example on Apple Developer
- it's much quicker to build and link something small than a larger library such as Exiv2.

2) If you can't get something small and easy to work, you may be able to get help on an iOS forum.
- If you ask on an iOS forum (or StackOverflow) about Exiv2, it's very unlikely that anybody will help.
- If you ask for help with simple 20 line C++ library, somebody will probably help.

3) Build Exiv2 on the desktop for i386/ix64 (not universal)
- you can list the symbol table with nm
- your aim is to cross compile a library which offers all the symbols AND an application that links, loads and calls the library.

______________________________

I know this is time consuming and hard - that's why we call it work! I hope that helps. I expect we'll end up discussing this next weekend!

Robin

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Still no luck...

1) I checked with xcrun -sdk iphoneos lipo -i and indeed i386 architecture is supported

Architectures in the fat file: libexiv2_all.a are: armv7s armv7 i386

http://stackoverflow.com/questions/12549489/compile-library-for-armv7s-cputype-12-and-cpusubtype-11

2) Then I used otool -L and saw that i386 *.o are present in the fat

3) Next, I downloaded and ran http://dl.dropbox.com/u/1745859/Blog/tesseract/ios50_tesseract301_leptonica_168/TesseractSample.zip from http://tinsuke.wordpress.com/2011/11/01/how-to-compile-and-use-tesseract-3-01-on-ios-sdk-5/ and tried to integrate exif2 in this project, hoping that since its working otherwise, all like / build settings are correct. The only caveat being that the project is for iOS SDK 5 and the library is for iOS SDK 6. But the project as a whole is getting compiled for iOS SDK 6.

The moment I make any call to exif2 such as Exiv2::Image::AutoPtr imagep = Exiv2::ImageFactory::open("Lorem_Ipsum_Univers.png"); I get the following error

*Undefined symbols for architecture i386:*
"_compress2", referenced from:
Exiv2::Internal::PngChunk::zlibCompress(std::string const&) in libexiv2_all.a(pngchunk.o)
"_crc32", referenced from:
Exiv2::Internal::PngChunk::makeUtf8TxtChunk(std::string const&, std::string const&, bool) in libexiv2_all.a(pngchunk.o)
Exiv2::Internal::PngChunk::makeAsciiTxtChunk(std::string const&, std::string const&, bool) in libexiv2_all.a(pngchunk.o)
"_iconv", referenced from:
(anonymous namespace)::convertStringCharsetIconv(std::string&, char const*, char const*) in libexiv2_all.a(convert.o)
"_iconv_close", referenced from:
(anonymous namespace)::convertStringCharsetIconv(std::string&, char const*, char const*) in libexiv2_all.a(convert.o)
"_iconv_open", referenced from:
(anonymous namespace)::convertStringCharsetIconv(std::string&, char const*, char const*) in libexiv2_all.a(convert.o)
"_uncompress", referenced from:
Exiv2::Internal::PngChunk::zlibUncompress(unsigned char const*, unsigned int, Exiv2::DataBuf&) in libexiv2_all.a(pngchunk.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Will try out other suggestions you mentioned also.

It will be a great achievement for exif2 if we can make it run on iOS.

Regards.

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Hi Robin,

It worked! I am able to extract image metadata using Exiv2 on iOS! (tried it on simulator, not on device)

Thank you so much for your valuable time and helpful solution.

I will document the solution soon this weekend.

BTW, the above problem was caused due to 2 missing frameworks.

Regards,
Manuj.

RE: How to compile for iOS - Added by Robin Mills over 8 years ago

Congratulations.

When I read your mail "Still no luck" and you mentioned crc32, I instantly thought "he hasn't linked zlib". And then, I read your next email and thought "Yeah! He's done it".

Look at this on MacOS-X (mountain lion):

514 rmills@rmills-imac:~/gnu/exiv2/test.build/xcode/src/Debug $ nm -g libexiv2.dylib | grep _crc
                 U _crc32
515 rmills@rmills-imac:~/gnu/exiv2/test.build/xcode/src/Debug $ otool -L libexiv2.dylib 
libexiv2.dylib:
    /Users/rmills/gnu/exiv2/test.build/xcode/src/Debug/libexiv2.dylib (compatibility version 12.0.0, current version 12.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    /usr/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
    /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 56.0.0)
516 rmills@rmills-imac:~/gnu/exiv2/test.build/xcode/src/Debug $ nm -g /usr/lib/libz.1.dylib | grep _crc32
00000000000011e7 T _crc32
0000000000001453 T _crc32_combine
517 rmills@rmills-imac:~/gnu/exiv2/test.build/xcode/src/Debug $ 
You can see that libexiv2.dylib has an unsatisfied external _crc32.
And you can see he's linked to libz
And you can see libz offers _crc32

Easy is't it? So much fun when you put the jigsaw together.


The way open-source works is by people making contributions. So you're not done here until you document this for others. I'm going to be your test engineer. I've never built or run code on an iOS device. I have Xcode, the device emulator and an iPod (with iOS 6.1.3). So you tell me what to do, and I'll test your explanation. We can discuss it here on the forum, or privately by email

Your contribution will of course be recognized for all the world (and your boss) to see. Good Work deserves Recognition and you've done Good Work. Well Done.

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

Dear Robin,

It would make no sense not to share this information. Not only that, I am required by job to document the process, which my company and I will be more than happy to share along with a sample source code.

Currently I am busy with a project deadline. I will do this soon within a day or two and will get back to you.

Regards,
Manuj

RE: How to compile for iOS - Added by Robin Mills over 8 years ago

Manuj

Right. Thanks for the update. To share is the right thing to do. I look forward to your contribution.

Robin

RE: How to compile for iOS - Added by Manuj LHT over 8 years ago

This is for the records:

The library is working wonderfully on the simulator, but on the device I am getting a libstdc++ not found error in release mode and debug too I guess

I have tried linking the libc++ framework but no good.

Somehow, it got deleted from my system. Then I check another computer and it had the file. I tried building it from there but faced the same issue. Then trying it from the third machine, it built without a problem from the same code base. Strange. Its working on the device now, but I still need to figure out whats wrong with my machine and the other one.

RE: How to compile for iOS - Added by Robin Mills over 8 years ago

Manuj

Linking frameworks/libraries and applications on the Mac is easy when it works "out of the box". However when it does not, you're in for some detective work with our old friends otool -L, install_name_tool and possibly nm and lipo. We had a discussion about linking Mac-OSX and I believe it's similar on iOS. http://dev.exiv2.org/boards/3/topics/1278

I've just installed iFunBox on my iMac and browsed into "Adobe Reader". I've dragged it from the iPod Touch to the Desktop and run otool -L on it.

510 rmills@rmills-imac:~/Desktop $ otool -L "Adobe Reader" 
Adobe Reader (architecture armv7):
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
    /usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)
    /System/Library/Frameworks/StoreKit.framework/StoreKit (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/CoreVideo.framework/CoreVideo (compatibility version 1.2.0, current version 1.8.0)
    /System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices (compatibility version 1.0.0, current version 40.0.0)
    /System/Library/Frameworks/OpenGLES.framework/OpenGLES (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 993.0.0)
    /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 2380.17.0)
    /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 600.0.0)
    /System/Library/Frameworks/MessageUI.framework/MessageUI (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/QuartzCore.framework/QuartzCore (compatibility version 1.2.0, current version 1.8.0)
    /System/Library/Frameworks/CoreText.framework/CoreText (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Security.framework/Security (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration (compatibility version 1.0.0, current version 499.5.0)
    /System/Library/Frameworks/MediaPlayer.framework/MediaPlayer (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 65.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 173.8.0)
    /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 793.0.0)
Adobe Reader (architecture armv7s):
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
    /usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.8.0)
    /System/Library/Frameworks/StoreKit.framework/StoreKit (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/CoreVideo.framework/CoreVideo (compatibility version 1.2.0, current version 1.8.0)
    /System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices (compatibility version 1.0.0, current version 40.0.0)
    /System/Library/Frameworks/OpenGLES.framework/OpenGLES (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Foundation.framework/Foundation (compatibility version 300.0.0, current version 993.0.0)
    /System/Library/Frameworks/UIKit.framework/UIKit (compatibility version 1.0.0, current version 2380.17.0)
    /System/Library/Frameworks/CoreGraphics.framework/CoreGraphics (compatibility version 64.0.0, current version 600.0.0)
    /System/Library/Frameworks/MessageUI.framework/MessageUI (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/QuartzCore.framework/QuartzCore (compatibility version 1.2.0, current version 1.8.0)
    /System/Library/Frameworks/CoreText.framework/CoreText (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Security.framework/Security (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration (compatibility version 1.0.0, current version 499.5.0)
    /System/Library/Frameworks/MediaPlayer.framework/MediaPlayer (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 65.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 173.8.0)
    /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation (compatibility version 150.0.0, current version 793.0.0)
511 rmills@rmills-imac:~/Desktop $ 

You can see that Adobe Reader is built for arm7 and links /usr/lib/libc++.1.dylib. You'll be able to do the same. If necessary, you may have to use install_name_tool to link correctly.

You know that I've never built code for iOS. It would help a great deal if you could send code and I will get it work for you. I'll treat your code as confidential if you email to me. Even better - put the code on a web or ftp server and email me with the URL. Any information you can share about how to build the code will be greatly appreciated. My email address is

Robin

    (1-13/13)