Tutorial: Open Source on iOS (Part 4): Compiling libvorbis

This is the forth in a series of posts on building open source libraries for iOS. This tutorial uses the scripts and directory structure developed in the first three posts and applies them to compiling the libvorbis open source audio codec. Please make sure you have completed the previous tutorials before attempting this one.

Obtaining the Source Code

Create a directory for your build (in $IDZ_BUILD_ROOT).

cd $IDZ_BUILD_ROOT
mkdir -p libvorbis/1.3.3
pushd libvorbis/1.3.3

Download and decompress the source

curl -O http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz
tar xvfz libvorbis-1.3.3.tar.gz

You now need to change the -O4 optimization in the configure script. Open the file libvorbis-1.3.3/configure file and locate the following section:

        *-*-darwin*)
                DEBUG="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O0 -fsigned-char"
                CFLAGS="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -O4 -ffast-math -fsigned-char"
                PROFILE="-DDARWIN -fno-common -force_cpusubtype_ALL -Wall -g -pg -O4 -ffast-math -fsigned-char";;

Change the -O4 to -O3 and remove all the -force_cpusubtype_ALL flags:

        *-*-darwin*)
                DEBUG="-DDARWIN -fno-common  -Wall -g -O0 -fsigned-char"
                CFLAGS="-DDARWIN -fno-common  -Wall -g -O3 -ffast-math -fsigned-char"
                PROFILE="-DDARWIN -fno-common  -Wall -g -pg -O3 -ffast-math -fsigned-char";;

You will also need to edit libvorbis-1.3.3/lib/os.h. Locate the following section, near line 84:

/* Special i386 GCC implementation */
#if defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
#  define VORBIS_FPU_CONTROL

And change it to:

/* Special i386 GCC implementation */
#if 0 && defined(__i386__) && defined(__GNUC__) && !defined(__BEOS__)
#  define VORBIS_FPU_CONTROL

This disables a special rounding macro used for the i386 architecture that does not seem to work correctly on the simulator.

Building the Static Libraries

You are now ready to attempt a build.

idz_configure armv7 6.0 libvorbis-1.3.3/configure

Lots of messages will print on your terminal, but the last few lines will be:

configure: error: Ogg >= 1.0 required !
make: *** No rule to make target `clean'.  Stop.
make: *** No targets specified and no makefile found.  Stop.
make: *** No rule to make target `install'.  Stop.

It would appear that the build is looking for libogg but does not know where to look for it.

To find information about the command line options to a configure script you use the --help argument.
Type:

libvorbis-1.3.3/configure --help

The relevant line is

  --with-ogg=PFX          Prefix where libogg is installed (optional)

The idz_configure script will append the contents of the environment variable IDZ_EXTRA_CONFIGURE_FLAGS to the command line arguments. Therefore you can retry the build as follows:

export IDZ_EXTRA_CONFIGURE_FLAGS=--with-ogg=/Users/idz/idz_builds/libogg/1.3.0/install-iPhoneOS-armv7
idz_configure armv7 6.0 libvorbis-1.3.3/configure

The build should now succeed.

You can repeat the build for any other architectures you may need. For example, to build for the simulator use:

export IDZ_EXTRA_CONFIGURE_FLAGS=--with-ogg=/Users/idz/idz_builds/libogg/1.3.0/install-iPhoneSimulator-i386
idz_configure i386 6.0 libvorbis-1.3.3/configure

Creating the Pseudo-Framework

Building libvorbis creates three static libraries, libvorbis.a, libvorbisenc.a and libvorbisfile.a, however a pseudo-framework can only have one static library, so we need a method to combine these libraries into a single .a file. Luckily static libraries are only object file archives, so this is not hard to do.

Change into the lib directory of one the install directories:

pushd install-iPhoneSimulator-i386/lib

Make a temporary directory to work in and change into it:

mkdir tmp
pushd tmp

Extract the object files from each of the libraries in turn:

ar -x ../libvorbis.a
ar -x ../libvorbisenc.a
ar -x ../libvorbisfile.a

Combine all the object files into a new library called libvorbisall.a.

ar -rs ../libvorbisall.a *.o

Pop out of the tmp directory and remove it

popd
rm -rf tmp

Since you will need to repeat this process for each architecture it makes sense to generalize this process and create a script automate it. Create the following script file in $IDZ_BUILD_ROOT/bin/idz_combine:

#!/bin/bash
#
# This script combines a number of static library files (.a files) into
# a single (new) output library
#
# If the output file exists it will be overwritten
#

usage()
{
  echo "Usage: $0 output_lib input_lib1 ..."
  exit 1
}

if [ "$#" == "0" ]; then
  usage
fi

#
# Determine the absolute path of the output file
#
if [[ "$1" = /* ]]; then
  ABS_OUTPUT_FILE=$1
else
  ABS_OUTPUT_FILE=$(pwd)/$1
fi
#
# Remember output file as it appeared on command line too
#
OUTPUT_FILE=$1
#
# Determine the input files
#
shift
INPUT_FILES=$@
#
# Print what we are going to do
#
echo "$OUTPUT_FILE <= $@"
#
# We'll do all the work in a temp dir
#
TMP_DIR=$(mktemp -d tmp.XXXXXX)
mkdir -p $TMP_DIR
pushd $TMP_DIR > /dev/null
#
# Extract the .o files from all the libs
#
for lib in $@
do
  if [[ "$lib" = /* ]]; then
    ar -x $lib
  else
    ar -x ../$lib
  fi
done
#
# Create a new output archive by combining all the *.o files
#
ar -rs $ABS_OUTPUT_FILE *.o
#
# Return to the original directory and clean up
#
popd > /dev/null
rm -rf $TMP_DIR
exit 0

When I have more time I will come back and describe what is going on here line by line.

Using this script, all you need to do to perform the combination step is:

pushd install-iPhoneOS-armv7/lib
idz_combine libvorbisall.a *.a
popd

and repeat this for each of your architectures.

These per-architecture combined static libraries can then be combined using the idz_fw script from the previous tutorial:

idz_fw Vorbis libvorbisall.a install-iPhoneSimulator-i386/include/vorbis

In coming posts, I’ll look at how you can use Ogg.framework and Vorbis.framework to play audio on iOS.


About idz

A professional software engineer dabbling in iOS app development.
This entry was posted in Tutorial. Bookmark the permalink.

2 Responses to Tutorial: Open Source on iOS (Part 4): Compiling libvorbis

  1. favormm says:

    Can you help to compile the opencore-amr, I have successfully compiled on iOS4.0 with xcode 4.2 but faild compiled on iOS6 with Xcode 4.5.

    The source at:
    http://sourceforge.net/projects/opencore-amr/files/opencore-amr/

    • idz says:

      If you post the error message you are seeing I might be able to point you in the right direction. You might get a faster response by posting a question on stackoverflow.com.

Leave a Reply