J
Justin Rudd
Is it just me, or is getting anything other than standard ruby a true
ordeal on Windows?
Now I'm sure everyone is snickering right about now, that's OK.
Anyway, I'm trying to write a product using Ruby that will be
downloaded and run locally. I need to support different databases.
MySQL has native Windows binaries. Looking for Ruby bindings to MySQL
led me to http://www.tmtm.org/en/mysql/ruby/. So I download the
archive, extract it, run ruby extconf.rb, and it stops there.
It can't find mysql_query in any of the library paths that it looks
at. So I look at the log file and see that it is basically generate
mini-C programs and if they compile, the stuff is there.
On Windows, there is a mysqlclient.lib file that it is trying to link
to. Hm...why would it still show up unresolved?
Fast forward 3 hours of digging through mkmf to figure out how it is
generating paths... Screw this. I'll just generate the C file myself
and write my own project to generate the library. That wasn't too
hard. Got the project going. Got the shared library compiled.
Hm...where do I put the file? Ah...I put it in the i386-msvcrt
directory in site_ruby. Hm...everything in there is a .so file.
OK...I'll rename mine to mysql.so (is this necessary?)
Now I'll go and do this -
require 'mysql'
Run this through the interpreter...
Get this...
C:/shared/tools/sdks/ruby/lib/ruby/1.8/i386-mswin32/mysql.so: 127: The
specified procedure could not be found. - Init_mysql (LoadError)
C:/shared/tools/sdks/ruby/lib/ruby/1.8/i386-mswin32/mysql.so from
connect.rb:1
Look at my C project, Init_mysql does exist. But it isn't exported.
In the Windows world, I have to export functions from DLLS. So that
things like GetProcAddress work. So I start off by exporting the one
method.
Rerun the interpreter, no errors. WOOHOO!!!
So I extend the script to this...
require 'mysql'
c = Mysql.new('localhost', 'root', 'my_root_password')
c.list_dbs.each { |db|
p db
}
I get a list of all Databases in MySQL instance. Try some inserts,
deletes, etc. Everything seems to be working.
Now here are my problems -
* This took 6 hours
* extconf gave me no ideas that it required a C compiler
* extconf gave me no ideas what was going wrong (I just got a no)
I'm a pretty decent Windows programmer (been doing it for 10+ years
now). And I think I've got to go through the whole process again to
get Ruby DBI working and SQLLite/Ruby (which I probably won't use
since it is GPL). And PostgresQL. But for someone starting out with
Ruby on Windows, would they know they needed a C compiler? Would they
know they needed to add __declspec(dllexport) to that one function?
Now let's contrast this with Python. I go to
http://sourceforge.net/projects/mysql-python/ and they have an EXE I
can download, run it, and I can connect to MySQL in under 5 minutes
(after download).
I love Ruby. And a lot of that love comes from Rails (which I've been
using quite successfully). But building an app is harder than it
should be.
I'm going to document what I did and post it on my weblog along with
the binary file that I generated. Hopefully someone else out there
can make use of it.
ordeal on Windows?
Now I'm sure everyone is snickering right about now, that's OK.
Anyway, I'm trying to write a product using Ruby that will be
downloaded and run locally. I need to support different databases.
MySQL has native Windows binaries. Looking for Ruby bindings to MySQL
led me to http://www.tmtm.org/en/mysql/ruby/. So I download the
archive, extract it, run ruby extconf.rb, and it stops there.
It can't find mysql_query in any of the library paths that it looks
at. So I look at the log file and see that it is basically generate
mini-C programs and if they compile, the stuff is there.
On Windows, there is a mysqlclient.lib file that it is trying to link
to. Hm...why would it still show up unresolved?
Fast forward 3 hours of digging through mkmf to figure out how it is
generating paths... Screw this. I'll just generate the C file myself
and write my own project to generate the library. That wasn't too
hard. Got the project going. Got the shared library compiled.
Hm...where do I put the file? Ah...I put it in the i386-msvcrt
directory in site_ruby. Hm...everything in there is a .so file.
OK...I'll rename mine to mysql.so (is this necessary?)
Now I'll go and do this -
require 'mysql'
Run this through the interpreter...
Get this...
C:/shared/tools/sdks/ruby/lib/ruby/1.8/i386-mswin32/mysql.so: 127: The
specified procedure could not be found. - Init_mysql (LoadError)
C:/shared/tools/sdks/ruby/lib/ruby/1.8/i386-mswin32/mysql.so from
connect.rb:1
Look at my C project, Init_mysql does exist. But it isn't exported.
In the Windows world, I have to export functions from DLLS. So that
things like GetProcAddress work. So I start off by exporting the one
method.
Rerun the interpreter, no errors. WOOHOO!!!
So I extend the script to this...
require 'mysql'
c = Mysql.new('localhost', 'root', 'my_root_password')
c.list_dbs.each { |db|
p db
}
I get a list of all Databases in MySQL instance. Try some inserts,
deletes, etc. Everything seems to be working.
Now here are my problems -
* This took 6 hours
* extconf gave me no ideas that it required a C compiler
* extconf gave me no ideas what was going wrong (I just got a no)
I'm a pretty decent Windows programmer (been doing it for 10+ years
now). And I think I've got to go through the whole process again to
get Ruby DBI working and SQLLite/Ruby (which I probably won't use
since it is GPL). And PostgresQL. But for someone starting out with
Ruby on Windows, would they know they needed a C compiler? Would they
know they needed to add __declspec(dllexport) to that one function?
Now let's contrast this with Python. I go to
http://sourceforge.net/projects/mysql-python/ and they have an EXE I
can download, run it, and I can connect to MySQL in under 5 minutes
(after download).
I love Ruby. And a lot of that love comes from Rails (which I've been
using quite successfully). But building an app is harder than it
should be.
I'm going to document what I did and post it on my weblog along with
the binary file that I generated. Hopefully someone else out there
can make use of it.