6

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.

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!

Eimantas
  • 48,927
  • 17
  • 132
  • 168
yorkshirespud
  • 727
  • 6
  • 14
  • I had already looked at the Compile C lib for iPhone page, but in that post, the original poster's configure script doesn't work for him or me, and that post finished with 'I fixed it with help from this post' and some broken links. I still can't get a cross-compilation to ARM of ZeroMQ working at the moment. I'll keep trying! – yorkshirespud Nov 30 '11 at 07:48

2 Answers2

6

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 )

yorkshirespud
  • 727
  • 6
  • 14
  • 1
    There is one more point to add to above. Testing revealed that the above build produced a library that worked fine in iOS 4 and 5, but crashed on iOS3. See [link](http://iphone.galloway.me.uk/2010/05/iphone-sdk-bug-hunting-gcc-atomic-builtins/) for more information, but the short version is that when building for using the iOS5 SDK and g++ 4.2 or above, the compiler uses operations not supported in iOS3. The solution is to alter `/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk/usr/include/c++/4.2.1/bits/c++config.h` and remove `#define _GLIBCXX_ATOMIC_BUILTINS 1` to build – yorkshirespud Jan 14 '12 at 20:06
  • Thank you for sharing the answer. Did you ever get it working on ios arm64 simulator? – Dinesh Feb 11 '23 at 18:50
2

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 :-)

Community
  • 1
  • 1
poupou
  • 43,413
  • 6
  • 77
  • 174