Compiling MySQL UDFs on Mac OS X

Compiling and installing a User Defined Function for MySQL on Mac OS X seems tricky. There are installation notes, but they seem to be sparse on OS X (the comments are clues, though).

I was looking through the tutorial materials for Roland’s talk, and came up with what I think is the most full-proof way to ensure your UDFs get compiled…

gcc -Wall -dynamiclib -o udf_lightspeed.dylib -lstdc++ udf_lightspeed.c

The above will compile just fine, but MySQL will give you an interesting error saying “no suitable image found”. Its the infamous Error 1126.

Upon further poking, it seemed like the following should work:
gcc -Wall -dynamiclib -o udf_lightspeed.dylib -lstdc++ -lc -I`/usr/local/mysql/bin/mysql_config --cflags` udf_lightspeed.c

And it does. MySQL loads the UDF just fine. But sometimes, you get linker errors, which can be annoying.

So, the full-proof solution to compiling UDFs on OS X, Leopard 10.5? A two-step process:
gcc -c `/usr/local/mysql/bin/mysql_config --cflags` udf_lightspeed.c
libtool -dynamic -o udf_lightspeed.so udf_lightspeed.o -lc

Feel free to add -O2 as an option to GCC. One day I might talk about the amazing mysql_config (use it! Read the documentation, in the meantime.)

Remember, once you’ve your your .dylib, to move it to your plugin_dir (find it by doing SHOW VARIABLES LIKE 'plugin_dir';). Also note that on OS X, it doesn’t matter if the extension is .dylib or .so – either one will do.

Happy UDF usage!

Update: As a reader points out in the comments, probably the easiest way, in a one-step process, is to use the bundle_loader. gcc -Wall -bundle -bundle_loader /usr/local/mysql/bin/mysqld -o udf_return_values.so `/usr/local/mysql/bin/mysql_config —cflags` udf_return_values.c works a charm.

Technorati Tags: , , , , , ,

5 Comments

  1. If you get linker errors, it might be that it expects certain runtime symbols to exist which come from the mysql binary itself. If you want it to properly resolve all symbols at link-time, you should be able to use the -bundle_loader flag. Also, if it’s a loadable module that’s going to be dlopened by MySQL, it’s technically more “correct” to make it a -bundle, not a -dynamiclib.

    Try something like this (I can’t test it since I don’t have any udf sources handy):

    g++ -Wall -bundle -bundle_loader /usr/local/mysql/bin/mysqld -o udf_lightspeed.so `/usr/local/mysql/bin/mysql_config –cflags` udf_lightspeed.c

    You might need to add `/usr/local/mysql/bin/mysql_config –libmysqld-libs` to that as well to resolve libmysqld symbols.

  2. byte says:

    Hi Bejamin!

    Thanks. It looks like bundle_loader makes things much better :)

    Quick testing on a few UDFs I had handy:
    g++ -Wall -bundle -bundle_loader /usr/local/mysql/bin/mysqld -o udf_return_values.so `/usr/local/mysql/bin/mysql_config –cflags` udf_return_values.c

  3. byte says:

    When time permits, must figure out why using g++ generates a “bigger” .so over using gcc (it really shouldn’t make a difference)

    -rwxr-xr-x 1 root wheel 8616 Apr 14 09:16 /usr/local/mysql/lib/udf_return_values.so*
    -rwxr-xr-x 1 ccharles staff 8568 Apr 14 09:25 udf_return_values.so*

    8616 (g++) vs 8568 (gcc)

  4. Anonymous says:

    I realize this is year old, but wanted to express my gratitude for the helpful article; I was wondering what the hell I was doing wrong on my Mac OS X where documentation isn’t as plentiful as it is on *nix.

    Just one minor correction- your instruction had one dash for cflags; in my case, it doesn’t work; I had to use two dashes.

    echo `/usr/local/mysql/bin/mysql_config -cflags`
    returns the sample usage page for this script while this
    echo `/usr/local/mysql/bin/mysql_config –cflags`
    will return the correct include directory path and flags needed to compile

    I’d also encourage you to post something over at MySQL’s documentation, even just a link back to this page for the UDF installation on Mac OS X.

    Again, thanks!

  5. byte says:

    Hi Bejamin!

    Thanks. It looks like bundle_loader makes things much better :)

    Quick testing on a few UDFs I had handy:
    g++ -Wall -bundle -bundle_loader /usr/local/mysql/bin/mysqld -o udf_return_values.so `/usr/local/mysql/bin/mysql_config –cflags` udf_return_values.c


i