FIXME: I get segfaults when using the mysql.so generated this way.
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
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).