Friday, July 15, 2011

How to build OpenSSL in Xcode

I extensively googled for how to build OpenSSL library in Xcode for iOS. I found the following links most useful:

* TUTORIAL: IPHONE APP WITH COMPILED OPENSSL 1.0.0A LIBRARY

Describes how to use already built OpenSSL static library in an Xcode project, how to build static libraries of OpenSSL for different architectures (i386, armv6, armv7) from terminal, how to make universal fat library with lipo command.

* TUTORIAL: SCRIPT FOR BUILDING OPENSSL FOR IOS (IPHONE/IPAD)

Script to build for both simulator and device.

* Easy inclusion of OpenSSL into iOS projects

Points to the following two Xcode projects on github that hides all the 'black magic':
1. Xcode project for OpenSSL by Stephen Lombardo
2. Xcode project for OpenSSL by Michael Tyson

Michael Tyson's project is easier as it simplifies Lombardo's project.

Since our target is to use cross-project reference technique wherever possible due to its greater flexibility in building for different architectures(i386, armv6, armv7), I went for Xcode project approach and used the one created by Michael Tyson.

The procedure is given below:
1. Download the OpenSSL source code directly from http://www.openssl.org/source/
2. Clone the openssl-xcode git repo to make a local copy
3. Put the downloaded OpenSSL source tar.gz into the same folder as openssl.xcodeproj.
4. The extracted OpenSSL distribution can also be placed in a folder called 'openssl' within the same folder as openssl.xcodeproj, or just extracted within the same folder as openssl.xcodeproj.
5. Then open openssl.xcodeproj in XCode and initiate a build

A possible problem:
In the Xcode project window, under Products directory, there is only libcrypto.a static library. As far as I know, OpenSSL build is supposed to produce two static libraries - libcrypto.a and libssl.a. However, I found libssl.a within the same folder as xcodeproj file. I sent a mail to Stephen Lombardo, original Xcode project creator for OpenSSL, still did not get any reply to the query - why libssl.a is not present in the Products folder of Xcode window.

Update #1:
The problem I guessed might happen actually happened when I tried to use the intended module from a test project. A good number of link errors related to SSL were produced. Googling with the first link error phrase SSL_CTX_free confirmed that libssl were not linked properly. I did not know how to add an additional library to Products folder (under Groups and Files pane in Xcode project window) so that it can be linked properly. Adding libssl.a file to Products folder in a straightforward manner did not help remove those link errors.

While trying out in an adhoc manner, I finally came up with the following procedure that could eliminate those SSL-related link errors:

Add libssl.a to the Products folder under Groups and Files pane in openssl project's window:

Step 1: Add New Target ssl:

Right click on Targets under Groups and Files pane.
Select Add -> New Target...
A dialog with title "New Target" will appear. On the left, under iPhone OS category, select Cocoa Touch. Then on the right, select Static Library.
Click Next button. Write ssl for Target Name. openssl should be selected for Add To Project.
Click Finish.

Step 2: Enter info about target ssl:

A new window titled Target "ssl" Info will appear from the previous step.

We need to add crypto as a dependency of ssl. Under General tab, Between Direct Dependencies and Linked Libraries, click + and select crypto, then click Add Target.

Select Build tab. Type search in the search box.
Under Search Paths category, for User Header Search Paths key, add value $(openssl_SRC) as path, set Recursive checkbox. openssl_SRC is an Xcode Source Tree variable defined from Xcode Preferences. It refers to the directory in which openssl.xcodeproj file is.
For Header Search Paths key, add value $(openssl_SRC)/openssl/include
Close the window.

Step 3: Link
Under Groups and Files pane, drag libssl.a from Products folder to Targets -> ssl -> Link Binary with Libraries folder.

Now the other projects that referred to openssl project with the help of cross-project reference mechanism should have both libcrypto.a and libssl.a static libraries when openssl.xcodeproj is expanded in client project's Xcode window.

Additional necessary steps for client projects:
Now that a new static library libssl.a has been added to openssl project, client projects must know about it. If libssl.a is added to openssl project before any client project refers to openssl project via cross-project reference mechanism, this is not necessary.

Let's assume openSslClient project is using openssl project.

Right click on openSslClient under Targets, select Get Info. A new window titled Target "openSslClient " info will appear.

Under General tab, add ssl to Direct Dependencies.

Under Build tab, User Header Search Paths and Header Search Paths should have appropriate values for openssl as it was done earlier for libcrypto.a. openssl.xcodeproj was added to openSslClient project through cross-project reference, following an excellent article by Clint Harris.

Close window.

Under Groups and Files pane, expand openssl.xcodeproj and drag libssl.a from there to Targets -> openSslClient -> Link Binary with Libraries folder.

Update #2:
Stephen Lombardo replied to my mail. He suggested adding a second target for ssl. I have already done this :-)

3 comments:

  1. Hi, did you manage to build openssl for all three architecture i386, armv6, armv7 in one build? I found by using Michael Tyson's project I can only build openssl separately for each of them but can't build one single lib that comprises of all architecture.

    ReplyDelete
  2. Do these instructions apply to XCode 4.6?

    ReplyDelete
  3. My family all the time say that I am wasting my time here at web,
    except I know I am getting experience everyday by reading thes
    good articles or reviews.

    Feel free to surf to my site :: does panic away work

    ReplyDelete