Did I already mention this? Best thing since sliced bread: A template for creating a static framework for iOS in Xcode. Awesome.
Month: February 2012
Boost on iPhone with nil clash fix
I have set up a github repo that contains boost 1.48.0 with the nil fix from boost ticket #5010 here: https://github.com/root42/boostoniphone-with-objc-nil-fix
This repo is based on the ones by Pete Goodliffe and mz2.
What about C++11 in Xcode?
This started out as a very small problem: I am using C++, Objective C++ and Objective C mixed in one project. This usually works pretty well. However, when including MapKit, the compiler choked on an Objective C++ file. It seems the MapKit.h header wants to use isinf(). This function has been introduced with ISO C 99, but it it is not included in ISO C++ 98. Hence the failure of Xcode’s gcc and clang compilers.
To work around this problem I was thinking of trying to set the project settings to use ISO C++ 11, or C++ 0x, since Xcode’s compilers are not that up to date. This is pretty easy:
And I guess this would work for most people. However, I am also using boost in this project. And I guess it is rather up to date, concerning the new language specification. However this also means that there is a problem with clang’s support of the language. I get a ton of errors in boost when switching to C++ 0x in clang:
In short, I think the C++ 11 support is not quite there yet with Xcode 4.2 and clang 3.0. I will try to post updates when future Xcode releases are coming out. If, alternatively, someone has hints on how to compile boost with clang 3.0, I am also glad to try that out.
Update: There is a fork on gitorious of the boost on iPhone build script, which already uses the clang compiler. I hacked the script even more to use –std=c++0x as a flag and it builds fine. Now I will try to link this new framework to an iOS project compiled with clang using C++ 0x.
Update 2: I found the root of the problem. The fantastic people over at #boost on freenode helped me figuring it out. In short: boost::fusion defines nil, which is an Objective C keyword. Thus we get lots of problems. Objective C defines nil and Nil in objc/objc.h. A minimal program that compiles successfully:
#include <boost/phoenix/core/reference.hpp>
#import <CoreFoundation/CoreFoundation.h>
int main()
{
return 1;
}
Using this command line:
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk
-framework Foundation -Fpath/to/boost/framework --std=c++0x -arch armv7
-stdlib=libc++ -mthumb -miphoneos-version-min=5.0 foo.mm -o foo
If you swap the to include / import statements, the program will not compile, since now the ObjC nil makes boost break. There is a boost ticket tracking this issue, with a proposed patch attached, which renames the boost nil to nil_.
Update 3: The patch works fine, but now I get internal compiler errors from clang. The compile triggers a segmentation violation at some point during the compilation of my project. I guess clang 3.0 is still a bit experimental. I submitted a bug report and will revert to using the default settings of Xcode for the time being.
Using gpsbabel and a USB to serial adapter on OS X to read out a Garmin GPS
For a couple of years I have been owning a Garmin eTrex GPS receiver. It’s a nice little tool, pretty ruggedized and reliable. I use it to track for example hiking tracks and also sometimes for Geocaching. It has a serial interface for downloading the data. However, my MacBook Pro does not have a serial port. So I bought one of the ubiquitous Digitus USB to Serial adapters. With this and gpsbabel (sudo port install gpsbabel, if you have MacPorts), it is really easy to download the track data for example to a KML file to be viewed in Google Earth:
gpsbabel -t -i garmin -f /dev/cu.usbserial-XXXXXX -o kml -F mytracks.kml
The XXXXXX in the device filename varies from device to device, you probably can also use /dev/cu.usbserial-* as the device filename, if you have only one of these things attached to your computer. It is important not to use the tty device file, since it seems not to work. I do not know yet what the exact difference is, but I will come back when I found out.