Cross-compiling ZeroMQ to ARM for use in a MonoTouch iPhone app configure settings

I’m attempting to use the ZeroMQ library in an iPhone app developed in C# using MonoTouch. I’ve solved almost all of the problems, but have fallen at the last hurdle. I’m using ZeroMQ 2.1.10, and the C# CLR binding/wrapper, and developing in Mac OS X 10.6.8. Here’s the story so far:

I first attempted to use ZeroMq in a simple Mono C# Console app. I built ZeroMQ with ./configure, then make and sudo make install, which installs shared library /usr/local/lib/libzmq.dylib. The ZeroMq C# binding clrzmq.dll is a wrapper that uses the ‘core’ ZeroMq functionality via C Api [DllImport] calls.

  • How to synchronize data amongst devices in Wi-Fi
  • Compile C lib for iPhone
  • The test app didn’t work, which I figured out to be that the standard ZeroMQ ./configure produces a 64-bit output, and Mono is only 32 bit. I then rebuilt ZeroMQ with

    ./configure CFLAGS="-O -arch i386" CXXFLAGS="-O -arch i386" LDFLAGS="-arch i386" --disable-dependency-tracking
    

    My simple C# ZeroMq app then worked correctly.

    Moving on, I then tried to use ZeroMq from inside an iPhone app in the iPhone simulator. I discovered that the iPhone only allows statically linked libraries (no dynamic libraries allowed). This is achieved by changing all the C# wrapper calls to

    [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
    

    and including libzmq.a directly in the MonoTouch project, and setting extra mtouch arguments

    -cxx -gcc_flags "-L${ProjectDir} -lzmq -force_load ${ProjectDir}/libzmq.a"
    

    to ensure the ZeroMQ library is included in the iPhone app.

    When running the app in the iPhone simulator, it crashed out, which I traced to a call made from a zmq_init() to socketpair. I finally traced this to the ZeroMQ library having been built against my build machine’s MacOS headers and libraries, instead of against the iPhone SDK. This was fixed by

    ./configure CFLAGS="-O -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk" CXXFLAGS="-O -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk" LDFLAGS="-arch i386" --disable-dependency-tracking
    

    Success in the iPhone Simulator! The simulator requires i386 static libraries built to the iPhone simulator SDK. I now can use ZeroMQ functionality within an iPhone app in the Simulator ONLY. It does not work however on a real iPhone.

    This is because a real iPhone requires a library that has been built for the ARM architecture, and against the real iPhoneOS SDK.

    (There is a side-issue of building 3 separate libraries – i386, ARM6, and ARM7, and combining all 3 into ‘fat’ library that can be used in any environment. I need to be able to build for ARM before I get to this problem).

    ** Finally, my question!! **

    The last step is to cross-compile build the ZeroMQ library to ARM. I have been trying all day long to come up with the correct switches for this, and studied all the examples on the internet that I can find, but none seem to have a solution that works.

    The closest I have got to working is:

    ./configure CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-g++-4.2
    CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2
    LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld CFLAGS="-O -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
    CXXFLAGS="-O -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk"
    --disable-dependency-tracking --host=arm-apple-darwin10
    LDFLAGS="-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk" 
    AR=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar 
    AS=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as 
    LIBTOOL=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool 
    STRIP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip 
    RANLIB=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib
    

    This produces a config which make compiles the ZeroMq code, but fails with lots of link errors, e.g.:

    ar: libzmq_la-clock.o: No such file or directory
    

    I’ve tried many other configurations, but they don’t even pass ./configure correctly.

    Can anyone help me with a suitable ./configure parameter list to produce an ARM architecture static library? This is all I need to get ZeroMQ working on a real iPhone.

    And and all help much appreciated!

    2 Solutions Collect From Internet About “Cross-compiling ZeroMQ to ARM for use in a MonoTouch iPhone app configure settings”

    Just thought I’d share that I found the answer in the end – the trick was to add CPP="cpp" CXXCPP="cpp" to the ./configure statement, giving:

    ./configure CPP="cpp" CXXCPP="cpp" CXX=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-g++-4.2 CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2 LD=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld CFLAGS="-O -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk" CXXFLAGS="-O -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk" --disable-dependency-tracking --host=arm-apple-darwin10 LDFLAGS="-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk" AR=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar AS=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as LIBTOOL=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool STRIP=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip RANLIB=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib
    

    I used this configuration to successfully build ZeroMQ for ARM, as used in my new iPhone app I Buzzed First (available at http://itunes.apple.com/gb/app/i-buzzed-first!/id490622820?mt=8 )

    That question is not really related to MonoTouch but on how to compile 0MQ on the iOS (ARM). Have a look at: Compile C lib for iPhone

    Hopefully it will help you and also cover the next question: fat universal binaries using lipo. The good news is that, if this works on the simulator, then you likely already covered any MonoTouch related issue 🙂