Building mysql-ruby on Windows

Intro

This page shows how to build the mysql-ruby library on Windows, using msys/mingw (gcc).

FIXME: I get segfaults when using the mysql.so generated this way.

Building the mysql client libraries

This uses ideas from Stdcall and DLL tools of MSVC and MinGW.

Step 1: Download the Windows mysql server/client from mysql.com. Choose the "Without installer" option. This should be a zip file. These instructions will assume you have extracted it to c:/mysql.

Step 2: Run the following commands in an msys shell. (dlltool.exe is a mingw program.)

dlltool --dllname /c/mysql/lib/opt/libmySQL.dll --output-lib /c/mysql/lib/libmysqlclient.a --def /c/mysql/include/libmysql.def
ruby extconf.rb --with-mysql-dir=/c/mysql
make 2>errors.txt

Step 3: Check that errors.txt contains errors like

mysql.o: In function `free_mysql':
c:/mysql-ruby-2.4.5/mysql.c:69: undefined reference to
`mysql_close@4'

Step 4: Create the following program and call it make_def.rb:

syms = []
ARGF.each_line { |line|
  match = line.scan(/undefined reference to `([^']*)'/)
  syms << match[0][0] if match.size == 1
}
puts('EXPORTS')
puts('mysql_query')
puts(syms.uniq)

Step 5: Run the following commands:

ruby make_def.rb < errors.txt > symbols.def
dlltool --dllname /c/mysql/lib/opt/libmySQL.dll --output-lib /c/mysql/lib/libmysqlclient.a --def symbols.def -k
make distclean
ruby extconf.rb --with-mysql-dir=/c/mysql
make
make install

Notes

This section explains why we do some of the things above. You don't need to know this to build mysql-ruby.

In the mysql distribution, mysql/lib/Readme says that the libraries were compiled using the cdecl calling convention. However, the header file mysql.h says they are using stdcall, and testing appears to confirm this.

When gcc sees stdcall functions, it expects to use function names like foo@8 rather than just foo, however libmySQL.dll has been compiled with a .def file which told MSVC to use the form without the @<n> decorations.

Therefore gcc fails to find the functions it is looking for when linking against the libmysqlclient.a library which we create directly from libmySQL.dll. This is why we use the error messages from gcc to determine the @<n> values which are necessary.

We add mysql_query to the list of exports because this is used by extconf.rb to check that we can find the library, but the code it generates to test this thinks it is a cdecl function. (Since the mysql.h header is not included.) It doesn't matter that the test code uses the wrong calling convention since we don't run the code - extconf.rb justs tests that we can compile/link it.

The -k option to dlltool tells it that functions in libmySQL.dll won't have @ decorations. Otherwise you will get runtime errors when using mysql (like "Can't find function mysql_foobar@8 in libmySQL.dll).