Shoes Federales- MinGW Issues

This is the third part of some blog posts about building Shoes and cross compiling. Part 2 gives a basic description of the Linux arrangement for cross compiling. This post is about MinGW and cross compiling for Windows.

This is not my first rodeo with MinGW and Shoes. I failed the first time a few years ago. Some might say it’s still not correct. Lets settle on it’s better and might be as good as it gets.

The Wine emulator runs many Windows programs on Linux or OSX. Shoes is not one of them (yet). Still, you’ll need Wine. I installed 1.6.something although 1.7.something would probably be a good idea I should get around to, one of these days.

There is no MinGW chroot configuration that I found on the internet (or none that were worth the effort). You can cross compile Shoes, and Ruby, and all their dependencies if you are patient and keep your goal in mind. To confuse things, I created some directories in /srv/chroot: mingw32, mingwgtk2. The first one is very minimal. It was enough to demonstrate the Shoes using Gtk3/Windows will run on Windows. The second one, mingwgtk2 is much more complete. You select between these in the env.rb associated with the rake linux:setup:mingw32 task.

Since Shoes on Gtk3 isn’t complete (for any platform) I’m only going to talk about the arrangement in /srv/chroot/mingwgtk2. It’s not a chroot – it’s just a place to build things and copy from. In Ubuntu synaptic, install the i686-w64-mingw32-gcc — your name may vary but the *-w64-ming* is the newer compilers that can produce both 32 and 64 bit. I’m using 32 bit (64 bit Windows 7 will run those productions well enough). Then get a copy of gtk+-bundle_2.24.10-20120208_win32.zip and inflate it. Mine looks like this.

ccoupe@bronco:/srv/chroot/mingwgtk2$ ls
bin gtktest lib src
etc include man ssl
gtk+-bundle_2.24.10-20120208_win32.README.txt info manifest usr
gtk+-bundle_2.24.10-20120208_win32.zip knap share

You may not have some of the subdirectories, yet. Notice include, lib, bin. Create the src dir
and copy your ruby source code over there. By the time your done downloading and compiling and configuring everything, the src directory is going to look like this:

ccoupe@bronco:/srv/chroot/mingwgtk2/src$ ls -1
cjc-curl-cfg.sh
cjc-ffi-cfg.sh
cjc-gdbm-cfg.sh
cjc-gif-cfg.sh
cjc-iconv-cfg.sh
cjc-jpeg-cfg.sh
cjc-openssl-cfg.sh
cjc-ruby-cfg.sh
cjc-yaml-cfg.sh
curl-7.34.0
dieterv
gdbm-1.8.3
gdbm-1.8.3.tar.gz
giflib-4.2.3
giflib-4.2.3.tar.bz2
jpeg-9
jpegsrc.v9.tar.gz
libffi-3.0.9
libffi-3.0.9.tar.gz
libiconv-1.14
libiconv-1.14.tar.gz
openssl-1.0.1f
openssl-1.0.1f.tar.gz
patch-gdbm-1.8.3
ruby-1.9.3-p484
ruby-1.9.3-p484.tar.gz
tarnyko
tml
yaml-0.1.4
yaml-0.1.4.tar.gz

You might not have the dieterv, tarnyho, and tml directories. They came with the packages I downloaded.. That scopes out the hard part of the tasks ahead. Some of those are optional Ruby dependencies (ffi, gdbm, iconv, openssl, yaml) and some are Shoes dependencies (curl,gif,jpeg,ruby). Build the ruby dependencies first. (configure, make, make install)

Everything started with a Mother configure:

ccoupe@bronco:/srv/chroot/mingwgtk2/src$ more cjc-ffi-cfg.sh
#! /bin/bash
# execute it instead of ./configure
export CC=i686-w64-mingw32-gcc
export CPPFLAGS="-I/srv/chroot/mingwgtk2/include"
export LDFLAGS="-L/srv/chroot/mingwgtk2/lib"
./configure
--build=x86_64-linux-gnu
--host=i686-w64-mingw32
--prefix="/srv/chroot/mingwgtk2"

Many of the cjc-{pkg}-cfg.sh are the same. I’m only to talk about the ones that are special. Obviously you’ll have to change the paths to match your setup. Don’t freak out when it doesn’t work. It’s easy to miss a character or two. This isn’t the place to rant about autoconf and configure. Just accept that you aren’t going to change it. –host is the system you are building for and –build is the system you are using to build with, except you’re using CC for the compiler and Includes and libs are different. DO NOT make up values for –host or –build. DO NOT expect configure to guess your compiler (because it will guess and it may also seem to work). Review the terminal output every time you run the configure.

gdbm
I should write a long ranting post about this bad boy. You need to find the patches the RubyInstaller folks used and apply them. Until you get it right. Copy your Mother script and add
--enable-libgdbm-compat to it, in the proper place, of course. Expect trouble.

For iconv add --enable-shared to your configure. No, I don’t remember why.
Do the same for yaml.

openssl
Oh God! I thought gdbm was hard. openssl doesn’t use autoconf but it looks like it does only IT DOESN’T and it doesn’t respect the CC env variable. There is very little on the web about cross compiling this sad puppy.
ccoupe@bronco:/srv/chroot/mingwgtk2/src$ more cjc-openssl-cfg.sh
#! /bin/bash
# execute it instead of ./Configure
export CPPFLAGS="-I/srv/chroot/mingwgtk2/include"
export LDFLAGS=-L/srv/chroot/mingwgtk2/lib
./Configure
--cross-compile-prefix=i686-w64-mingw32- mingw zlib-dynamic shared
--prefix="/srv/chroot/mingwgtk2"

Congratulations, you’ve built the Ruby dependencies. Or you built Ruby and came back here to rebuild the missing ones. Been there, done that.

Ruby
#! /bin/bash
# execute it instead of ./configure
export CC=i686-w64-mingw32-gcc
export CPPFLAGS="-I/srv/chroot/mingwgtk2/include"
export LDFLAGS="-L /srv/chroot/mingwgtk2/lib"
#export PKG_CONFIG_PATH="/srv/chroot/mingwgtk2/lib/pkgconfig"
./configure --enable-shared --enable-load-relative
--disable-install-doc
--enable-pthread
--build=x86_64-linux-gnu
--host=i686-w64-mingw32
--prefix="/srv/chroot/mingwgtk2/usr/local"

–enable-pthread doesn’t do that for Windows. It could, but it doesn’t in 1.9.3. –enable-load-relative which was so important on Linux? – not so important for Windows. Doesn’t hurt so we might as well keep it as a reminder.

Check the output of the Ruby build.

I think I mentioned you have to do a make install, didn’t I? That copies things into the –prefix locations (include,lib,bin). Only you don’t want to be root (it’s not needed).

Shoes dependencies (gif,jpeg, curl)
gif and jpeg just use copies of the Mother configure script. Easy.

curl is not needed at runtime for Shoes/Windows but you have to have one when to compile. No is not the time to fix Shoes (it’s not as easy as you’d think). Build a minimal curl. (yes you could enable ssl and tls and god what else, but why?)
ccoupe@bronco:/srv/chroot/mingwgtk2/src$ more cjc-curl-cfg.sh
#! /bin/bash
# execute it instead of ./configure
export CC=i686-w64-mingw32-gcc
export CPPFLAGS="-I/srv/chroot/mingwgtk2/include"
export LDFLAGS="-L/srv/chroot/mingwgtk2/lib"
./configure
--build=x86_64-linux-gnu
--host=i686-w64-mingw32
--without-gnutls
--without-ssl
--without-zlib
--disable-ldap
--disable-ldaps
--disable-dict
--disable-telnet
--disable-pop3
--disable-imap
--disable-smtp
--disable-gopher
--disable-manual
--disable-rtsp
--disable-versioned-symbols
--disable-tls-srp
--without-librtmp
--without-libidn
--prefix="/srv/chroot/mingwgtk2/usr/local"

After all of that, building Shoes for MinGW/Windows/Gkt2 is just a small matter of how you want to
deal with pkgconfig. You can write a shell script to find all the .pc and rewrite the prefix inside the .pc to the path of your ‘not really a chroot’ Or you can use some of the rewrite code I left in the env.rb rakefile. Or some combination. I’ll show you the sh/sed script but it’s up to you to not blinding execute it in the wrong directory. Don’t be root.
find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done

Shoes Native build.
After all the work on the Gtk2 and ruby cross compile, it was dead easy to create a rake file target and tasks.rb and env.rb that uses the Windows native controls.

Very Important
All of these Shoes/Windows share a problem: Occasional hangs. Thread deadlock. I’m convinced this is mostly a Ruby 1.9.3 problem. Running under Wine, it’s 100% reproducible. There’s no obvious reason that ruby and Shoes (with or w/o Gtk) should be fighting over a critical section, but they do.

Leave a Reply

Your email address will not be published. Required fields are marked *