Tuesday, October 26, 2010

Qt sucks at option parsing

Qt doesn't handle parsing program options (ie --foo=1) very well. But don't worry, boost program options can save the day! The problem is how to hook up boost::program_options to Qt's arguments after it has parsed Qt specific options.

#include <boost/program_options.hpp>
std::string qstr2str(const QString &qstr){
return qstr.toStdString();

int main(int argc, char *argv[]){
QApplication application(argc, argv);
namespace po = boost::program_options;
po::options_description clspec("Options");
("help", "see available options")
("arg1,a", po::value(&arg1)->default_value("banana"), "the arg1 option")
("arg2,b", po::value(&arg2)->default_value(false), "the arg2 option")

QStringList qargs = application.arguments();
std::vector args(qargs.size());
std::transform(qargs.begin(), qargs.end(), args.begin(), qstr2str);

po::variables_map vmap;
po::basic_command_line_parser parser(args);
po::store(parser.run(), vmap);

And with that you have parsed the options from Qt after it's had it's way with them

Saturday, October 16, 2010

cross compiling for android

The NDK, last time I looked, did an OK job of building small jni modules, but what if you needed to use third party libraries? Then you were in for a rough ride. But I managed to get something working together. First go get crystax's NDK so you have a real C++ environment. Not strictly necessary but let's keep surprises to a minimum shall we?

After installation I set the following variables, which you'll probably want to stuff into a file you can source from time to time:
export NDK_HOME=/opt/android/ndk
export TOOLCHAIN_ROOT=$NDK_HOME/build/prebuilt/linux-x86/arm-eabi-4.4.0/
export PLATFORM_ROOT=$NDK_HOME/build/platforms/android-8/arch-arm
You'll also need the following files:
and if you use CMake or it's needed for other libraries (ie OpenCV), here's a toolchain file:

A note on the cmake toolchain file: It is setup mostly to be standalone but there are some complex things going on that agcc/ag++ take care of internally that would be difficult to add to the toolchain file to modify cmake's behavior appropriately. If you have improvements, please be vocal about them!

Anywho, place agcc/ag++ in your path and mark them executable. Then just set CC/CXX appropriately. Source the ndk variables set above and everything should takecare of itself with autoconf/automake projects. For cmake projects, use the cmake file above and the first line lists an example calling. Keep in mind that bionic, the c library used in android, is pretty small though so don't be surprised if you have to patch out some c functions you've never heard of.

Here's an example for installing libtiff to your ndk:
./configure --host=arm-eabi CC=agcc CXX=ag++ \
CC=agcc CXX=ag++ \
CPPFLAGS="-D__i386__ -DANDROID -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -D__ANDROID__ -I/opt/android/ndk/build/platforms/android-8/arch-arm/usr/include" \
CFLAGS="-nostdlib -march=armv7-a -mtune=xscale -mfloat-abi=softfp -mfpu=vfp -mthumb-interwork -ffunction-sections -fstack-protector -fno-short-enums -Wno-psabi" \
LDFLAGS="-Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/usr/lib -L/opt/android/ndk/build/platforms/android-8/arch-arm/usr/lib -Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/lib/gcc/arm-eabi/4.4.0 -L/opt/android/ndk/build/platforms/android-8/arch-arm/lib/gcc/arm-eabi/4.4.0 -Wl,-rpath-link=/opt/android/ndk/build/platforms/android-8/arch-arm/arm-eabi/lib -L/opt/android/ndk/build/platforms/android-8/arch-arm/arm-eabi/lib -WWl,--fix-cortex-a8 -lgcc -lstdc++ -lsupc++ -lm -lc" \
--prefix=/opt/android/ndk/build/platforms/android-8/arch-arm/usr --disable-cxx
make install DESTDIR=/opt/android/ndk/build/platforms/android-8/arch-arm/
Note that this compiles and installs to the android 2.2 platform.

Kudos to Andrew Ross for the original agcc script, which I've modified above.

Friday, October 15, 2010

alfresco and glassfish a nono

Well, not just glassfish v3, but also postgresql. No, really, it's just not worth it to get it in your java container of choice. Sure it may work on first launch, but it may not restart cleanly. And it will take forever to launch. And you will have to tune the memory usage, which doesn't seem to correspond to configs for deploying on tomcat.

Just use the prepacked binaries for this one folks, I've never had a case of this so much as with alfresco. It starts fast, works as it should, no weird errors, and self-recovers much better.