Building a project for iOS or OSX with Armadillo in Xcode

Armadillo is a superb linear algebra library for C++, that makes doing things which are easy in MATLAB, almost as easy in C++ . I recently had to port a fairly complex curve fitting algorithm from MATLAB to an Xcode library, to use in an iPad Unity app. Setting the environment up requires a little care. Armadillo is from the C++ world, and it’s not as simple as copying a .framework. There are two different ways of getting Armadillo to work:

  1. Use armadillo simply as a template library, and link directly to LAPACK and BLAS (sounds complicated but isn’t)
  2. Build the runtime library as suggested in README.md

Armadillo mainly consists of headers which ‘wrap’ the more complicated and verbose commands of whichever library that is actually used for doing matrix calculations. For both iOS and OSX, this is Accelerate.framework, which contains optimised versions of LAPACK and BLAS, the components for doing the linear algebra fast.

Armadillo: To build or not to build

You do not have to build the Armadillo run-time library (e.g. using the installation instructions included), but you can if you wish. This includes which ever libraries the installation routine finds into a package, and conveniently for your purposes copies the headers to a sensible location. Alternatively you can just run Armadillo as a pure template library. This way, you include the headers, but don’t need to include the library. This is probably the easiest way and just requires a simple preprocessor directive before you include armadillo. I repeat: you do not have to build the Armadillo run-time library to get it to work on iOS.

If you try to include the run-time library you made on OSX in an iOS project it will not work! Really the only reason you would want to build this library is if you are not using Accelerate.framework for some reason.

Wait what?

Dylib files are dynamic libraries, which you can essential think of as precompiled code that is loaded at runtime, as opposed to code you compile yourself. In order to write code with the .dylib, you need header files, which tell you (and your compiler) what names to call the functions in the library. Libraries that you use in C++ generally come in this form, with both the library, and the header files. Frameworks are in fact just a neat package of dynamic libraries and headers. Armadillo is special – it’s not really a library per se, but is really just some very clever headers that sit on top of other dynamic libraries, which do the work. Since iOS and OSX come with the Accelerate framework as standard, you can just use Armadillo with that – and not bother creating the run-time library, which essentially is just a repackaging of existing libraries.

Recipe for iOS and OSX without run-time library:

  • Follow the installation instructions for Armadillo in the README.md file found in the downloaded archive. This involves building Armadillo with CMake, which will create a .dylib file and headers, and installing them to /usr/local/lib. OR Copy the headers to your project.
  • Add the header’s path (e.g. your project path or usr/local/include, if you installed Armadillo) to your ‘Header Search Paths’ entry in the target’s build settings.
  • Add Accelerate.framework (included with Xcode) to your linked frameworks and libraries.
  • Add #define ARMA_DONT_USE_WRAPPER to the top of your code.Add #include <armadillo> afterwards – Thats it!
  • If you get an ‘armadillo’ file not found error (highlighting the #include <armadillo> this is because the preprocessor cannot find the headers, so you need to check your ‘Header Search Paths’

Recipe for OSX with run-time library:

  • Follow the steps above.
  • Add the dylib file in usr/local/lib to your Linked Frameworks and Libraries. If you add the alias rather than the library itself, when you update armadillo, you won’t have to update the projects that use it. Note that /usr is hidden and in this current version of Xcode, you have to press Command + Shift + . to show hidden files in the finder window.
  • Add the library’s path (e.g. usr/local/lib) to your ‘Library Search Paths’ entry in the target’s build settings. Also, add the headers path to ‘Header Search Paths’.
  • If you get a linker error such as ‘ld: library not found for larmadillo.9.20.7’ – it is because the library cannot be found by the linker. This occurs if you didn’t update your ‘Library Search Paths’ – or you didn’t copy the library to your projects directory, if that was the route you were taking.
  • Happy linear algebra fun in Xcode!

Leave a Reply

Your email address will not be published. Required fields are marked *