How do you build PoDoFo on iOS with Openssl support? - ios

I have a project which uses PoDoFo for digitally signing PDF so I am trying to integrate CTOpenSSLWrapper into a single project which uses both PoDoFo and OpenSSL libraries. But when i try to build it, iam getting issues with linking:
The same error repeats with ld: symbol(s) not found for architecture armv7 if I try to run on device.
I have cross-checked every thing:
header search paths
library search paths
Buildphases->compile sources for any missing .m files
But i still have the same issue.
How can i resolve this?

I have cross-checked every thing:
1. header search paths
2. library search paths
3. Buildphases->compile sources for any missing .m files
It appears you are not including the library (only providing the library search path).
Here's what a typical library include looks like for me. Its for OpenSSL, but the same will apply to PoDoFo. In the example below, OpenSSL built for iOS is located in /usr/local/ssl/ios. Headers are located in is located in /usr/local/ssl/ios/include/openssl, and libraries are located in /usr/local/ssl/ios/lib.
Paths:
Library:
If you still have linker errors after adding the library, then perform the following to ensure you library has the architectures you need. I'm using OpenSSL as an example, you should use the PoDoFo library's name.
xcrun -sdk iphoneos lipo -info libcrypto.a
You should see something like:
Architectures in the fat file: libcrypto.a are: armv7 armv7s arm64 i386
If you need an OpenSSL built for iOS, then try this GitHub: noloader/openssl-1.0.1h-ios. Its a fat library, and has all the architectures you might need for iOS.

Related

Will the compiler strip the unrelated arch symbols from dependent static library in product binary file?

I'm a new in framework development, here is my case. I build a private static library to provide it to the vendors to link it.
Currently, I build my library with arch armv7 and arm64 only, this should be work for vendors to debug it in iOS device and archive their apps, but not for debugging in iOS Simulator. The simulator needs the x86_64 ( and even i386 in iPhone 5 Simulator). It isn't friendly to disable the ability to debug it in a simulator. I'm considering to provide a fat architecture of static library for them.
Here is the action
lipo -create libSignatureLibary_armv6.a libSignatureLibary_armv7.a libSignatureLibary_i368.a -output libSignatureLibary.a
After the merge operation, the output library has a double size than the single one.
The question is, will the compiler/Xcode strip the i386 and x86_64 arch symbols from final app product binary? If not, the fat arch library will increase the product app's size directly, right? Should I build two versions of the library for vendors, one for debugging, another for archiving? What's the right solution for this case?
I don't know what keywords I should research, I didn't have an existing product app linking it to verify this, either. (Maybe I should build a new later.)
Don't worry, the linker only uses the .o (relocatable object file, it is the output file of assembler, when you build a static library, a .m file will be translated to a .o file. The static library is a collection of relocatable object files) files for target arch in the static library, so it will strip the x86_64 and i386 .o files when building product binary.
Also the linker won't link the .o file which is not referenced directly or indirectly by compiled files into executable file.

Merging iOS .dylib into framework with lipo breaks bitcode recompilation

I'm trying to build a dynamic iOS framework manually from .dylib files. Binaries are created with cmake and xcodebuild and produce two .dylib files, one containing armv7, armv7s and arm64 and the other x86_64 and i386 architectures. Libraries are compiled with -fembed-bitcode parameter and everything succeeds.
.dylib files are then merged with next command:
lipo -create lib_arm.dylib lib_i386.dylib -output MyFramework
Framework is then created by copying the output from lipo command to:
MyFramework.framework/MyFramework
Headers and Info.plist are manually generated and added to the framework.
This framework is then installed via CocoaPods into the application as a vendored_framework. It is known that CocoaPods will strip the i386/x86_64 libraries from any fat binaries, for App Store distribution.
Application builds, runs, archives and uploads successfully to App Store.
However, since Bitcode is enabled, App Store will process the .ipa, and recompile with bitcode, this is where it fails and I receive an email from App Store, that it failed processing. Following instructions, I can reproduce the error locally with Exporting for Ad-Hoc Distribution and recompiling for bitcode. The error I receive is this:
ipatool failed with an exception: #<Errno::ENOENT: No such file or directory - /lib_arm.dylib>\n
So apparently during the recompilation, there is still a reference or somewhere to lib_arm.dylib, even though it was merged into a fat dylib Mach-O universal binary (file output of the merged dylib binary below):
>> file MyFramework
MyFramework: Mach-O universal binary with 5 architectures: [x86_64: Mach-O 64-bit dynamically linked shared library x86_64] [i386] [arm_v7] [arm_v7s] [arm64]
MyFramework (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
MyFramework (for architecture i386): Mach-O dynamically linked shared library i386
MyFramework (for architecture armv7): Mach-O dynamically linked shared library arm_v7
MyFramework (for architecture armv7s): Mach-O dynamically linked shared library arm_v7s
MyFramework (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
This is pretty much where my compiler/linker knowledge gets out of scope.
So my question is:
Where am I going wrong with this? Maybe bitcode should be compiled differently? Or maybe I am using lipo in wrong way?
Thank you!
After inspecting load commands of the created fat binary with otool -l command, I realized that using lipo itself does not change the LC_ID_DYLIB in the binary and it will reuse one from the first provided library. Using install_name_tool to change the id to correct one of the framework (including #rpath for iOS dynamic frameworks) fixes the error.
install_name_tool -id #rpath/MyFramework.framework/MyFramework MyFramework
Make sure the entire path to binary is included, together with .framework directory.

Embed OpenSSL module in Swift framework so its not needed when importing into application [duplicate]

I have installed OpenSSL in xcode for receipt validation, but it doesn't work.
I download openssl.xcodeproj and openssl-1.0.1f. I extract openssl-1.0.1f and add openssl.xcodeproj to my project.
I edit the Header Search Path to :
/Users/marko/Documents/Razvoj/BIView\ Mobile\ New\ Version/openssl/include/openssl
I added libcrypto.a in Target Dependencies under Build Phases
and added libcrypto.a in Link Binary With Libraries
as was described in http://atastypixel.com/blog/easy-inclusion-of-openssl-into-iphone-app-projects/.
But when I build project it stops with error :
clang: error: no such file or directory: '/Users/ .... -bmgslnakszsfovecplbzoslykrxo/Build/Products/Debug-iphoneos/libcrypto.a'
Why ?
OK, how to build and install it....
It might be easier to use a pre-built version of OpenSSL for iOS. You can find one at this Github account. The OpenSSL from that Github are multi-arch. They have ARMv7, ARMv7s, ARM64, and i386. That means they work with devices and simulators.
Download either OpenSSL 1.0.1e or 1.0.1f. Install it in a location like /usr/local/ssl/ios.
Then, add the headers to your Xcode project. They are located in /usr/local/ssl/ios/include:
Finally, add the multi-arch libs (libcrypto.a and libssl.a) to your Xcode project. They are located in /usr/local/ssl/ios/lib:
You need to add the library as a Framework. See this question: how to add an existing framework in Xcode 5.
Its OK to add the OpenSSL libraries under Frameworks. Its how things are done under Apple/Xcode.
I use the Absolute Path like in the image below because Crypto++, OpenSSL, etc are installed in /usr/local. The image below is a screen capture I have handy of Crypto++, and not OpenSSL's libcrypto.a or libssl.a. But the same applies to all libraries.

Check supported architectures of framework in Objective-C

As requested by Apple in the next February (February 2014), every app submitted to AppStore needs to support Arm64 architecture. In my project, I used many static libraries (*.a) and I can check if these libs support arm64 arch. However, I don't know if some frameworks such as Facebook.framework supports this new arch. How can I check it?
Each framework is really just a directory - not even like a package directory, but a plain directory you can browse directly into with Finder. Go into the .framework folder, at the top level you'll find a file with the same name as the framework (for older frameworks that file may be located under a folder called Versions/A within the .framework folder).
That file is really a static library (.a) file, just without the extension. Check it as you would any static library (using file or lipo -info) and you'll see what binaries the file contains.
You'll also know through XCode though. If you switch your project to support arm64 and the libraries you are linking to do not have arm64 support, XCode will not finish linking when compiling for a device.
Check below command in Terminal
lipo -info yourlib.a
Output like :
Architectures in the fat file: yourlib.a are: i386 x86_64 armv7 arm64
In case Framework.framework
Go to inside framework like below
cd /Your_Path_/CocoaLumberjack.framework
then run command
lipo -info CocoaLumberjack

How to Use LibXtract with iOS project?

I am trying to extract some features from audio files, MFCC to be accurate. Then I found a C library LibXtract, that would do the job for me.
I am trying to use LibXtract in iOS project, I have followed this tutorial
http://inote.apptrek.net/2011/10/howto-compile-native-c-codes-to-a-library-for-ios-development-in-xcode-take-mosquitto-for-an-example/
but I got some problems in process, first I got this warning
ld: warning: ignoring file ......./libLibXtract.a, missing required architecture i386 in file ..../libLibXtract.a
and those errors
Undefined symbols for architecture i386:
"_xtract_asdf", referenced from:
-[VoiceRecAppDelegate applicationWillResignActive:] in VoiceRecAppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So I would like to ask for your help in this problem, I would like to extract the MFCC from scratch with only obj-C code if possible.
Regards,
Omar
It sounds like you are trying to build your application with the Simulator as a target, but the LibXtract static library was not built for the i386 architecture.
You can confirm this with:
lipo -info /path/to/libxtract.a
The result from lipo should list the i386 architecture.
If it doesn't, then check that iphonesimulator is included in the Supported Platforms build setting in your LibXtract Xcode project and that i386 is included in the list of architectures.
It is also possible to compile autotools-based libraries for iOS/Simulator from the command line. Some instructions for this can be found here. Note: these are a little out-of-date so some of the options may need tweaking, although the principle remains the same.
However, it is far simpler to compile LibXtract into your application by dragging the LibXtract sources into your application's Xcode project!
I generally tend to have a "Libraries" group in my projects, under which I place third party sources (like LibXtract), as follows:
When dragging the files into your project ensure that you check the checkbox for your application in "Add to targets".
The LibXtract sources will then be compiled into your application and you can remove libxtract.a from your linker settings (or frameworks).

Resources