Monday, February 11, 2013

Welcome Aboard

In response to a recent inquiry on the cygwin list, I now have Ruby on Rails working out of the box on Cygwin, and have just uploaded the necessary packages to the Ports repository. To assure proper operation, the newly updated Ruby 1.9.3-p385-2 release is required.

To get aboard with Rails, install the ruby-rails package and its dependencies, then:

$ rails new testapp1
(files are installed, and bundle install should report that existing gems are being used)
$ cd testapp1
$ rails server
(then point browser to http://localhost:3000/,
OR:)
$ unicorn_rails
(then point browser to http://localhost:8080/)
From there on out, you're on your own. Enjoy the ride!

UPDATE: Well, that didn't take long. A security advisory was issued yesterday for Rails, so I have updated the Rails packages to 3.2.12 accordingly. The supported method for updating Rails apps for newer Rails versions is as follows:

  1. Open Gemfile in a text editor and update the version number following the gem 'rails' directive.
  2. Run bundle update rails to update the Gemfile.lock file. Existing gems should be found and used.
  3. Run rake rails:update to update configuration files, using the 'd' option to verify changes first.
More details on this procedure are available on RailsApps.

Wednesday, October 31, 2012

X doesn't always mark the spot

I have added X11 proto and library packages for the Win32 (i686-w64-mingw32) cross-compiler stacks on both Cygwin and Fedora, as well as for the i686-Linux (i686-pc-linux-gnu) stack on Cygwin. This means that it is now possible to compile-test xserver patches for Linux, Cygwin, and MinGW at the same time from one platform.

Unfortunately, building X11 for Win64 (x86_64-w64-mingw32) is going to take more work. Win64 is unique among 64-bit platforms in being LLP64 (32-bit long, 64-bit long long, 64-bit pointers), which breaks the assumption throughout the X11 codebase that a pointer can be cast to a long (which works on other platforms, both 32- and 64-bit). The usual solution to this is intptr_t, but that is C99 and hard requirements thereon are generally avoided in the X11 codebase. Hence, solving this will require massive patching to the headers (possibly including the addition of a intptr_t-like type), and will need to be discussed thoroughly in advance by interested parties.

Friday, December 2, 2011

A Qt hat, isn't it?

Fedora users may have noticed that F16 ships with Qt 4.8-RC. While I'm not sure what the rush was, it did cause an interesting problem when it came to the cygwin-qt cross-compiling package.

Building anything based on Qt requires more than just headers and libraries; Qt's object system requires code to be processed by moc, which generates additional C++ code for signal/slot handling and the like. There is also a number of other tools which "compile" various types of data into C++ code. I had been relying on the native tools in qt-devel to do this, since the generated code is not arch-specific.

The problem here is that moc-generated code is very internal-specific; code generated with one version of Qt will not compile with headers from another version. Since the version of cygwin-qt needs to match that of the Cygwin (Ports) qt4 package, and I have no plans of updating that to 4.8 until its proven stable in conjunction with KDE, this created a bit of an impasse. There was another issue with relying on qt-devel, in that qmake requires patches to build libraries or plugins correctly on Cygwin, which limited cygwin-qt cross-compiling to CMake-based packages.

The solution to all this was to change the cygwin-qt-qmake package, which had previously just included qmake mkspecs, to provide native-built tools from the same version of Qt as cygwin-qt and with the necessary patches. While qmake/moc/rcc/uic are always statically linked with the necessary Qt code, the linguist, qdbus, and qt3support build tools are linked against the Qt libraries; for now, they are also statically linked with their Qt prerequisites.

The updated cygwin-qt and cygwin-qt-qmake are now available for Fedora 14 and up on both arches, along with an updated cygwin-filesystem to support these changes. Even better, thanks to a patched qmake, I was also able to add cygwin-qscintilla and cygwin-qwt packages.

Thursday, December 1, 2011

Spicy Vinagre

One of the more eventful version bumps during the GNOME 3.2 update was with Vinagre, the Remote Desktop Viewer, which supports a number of protocols via plugins.  These plugins used to be managed by libpeas, a GNOME framework which makes it easier to develop and manage plugins.  However, in the case of Vinagre, it was a bit of an overkill, as the only plugins that were needed were those that shipped with Vinagre itself.

So, during the 3.2 development cycle, the devs decided to replace libpeas with their own VinagreStaticExtension class. In theory, a sensible move, but they made one major mistake: they never added any code to actually load the plugins!

Now that got your attention, didn't it?

Of course, if you try vinagre 3.2 on Linux, you may find that it works perfectly (but we'll get back to that).  But only because they used the most unportable, Linux/ELF-centric hack that I've ever seen (and trust me, I've seen my fair share of them).  It took me a while to figure it out at first, but here is what they did:
  1. the plugin init functions are marked __attribute__((constructor)), a GCC extension which causes the indicated function to be called automatically;
  2. the plugins rely on symbols in the main binary, of course, but furthermore...
  3. the executable also relied on symbols in the vnc plugin, and to top it off...
  4. the executable is linked against the plugins!! (If you don't think you misread that, then try again.)
In short, the only reason that this worked is that, by linking the plugins into the executable regardless of symbol dependency, the ELF runtime loader would load the plugin as a runtime dependency, at which time the plugin init function would be called due to being marked as a ctor.

To be fair, technique #1 is also used by LADSPA plugins, and #2 isn't uncommon and can be made to work even on PE platforms. However, #3, while theoretically possible, is impractical with plugins due to a lack of rpath in PE linkage, and relying on #4 wouldn't work at all because with PE only those DLLs whose symbols are required are hard-coded as runtime dependencies. And here's the kicker: even on ELF platforms, this doesn't work if linked with -Wl,--as-needed.

Fortunately, the fix is fairly easy: make the plugins static instead, link them into the executable as before, and actually call the ctors in main(). So not only is vinagre 3.2 working and available with the rest of GNOME 3.2 in Ports, but while I was at it, I added SPICE protocol support as well.

Wednesday, July 6, 2011

Fedora Cygwin repos moved

I have updated the Fedora 14 Cygwin gcc to 4.5.3, and have added the toolchain packages built for F15 as well.

In order to properly support multiple RPM repositories, I had to relocate the Fedora Cygwin repos to Cygwin Ports' FTP area. You will need to manually update the release RPM (with 'rpm -U') followed by yum update in order to get the new packages.

Sunday, July 3, 2011

This Lemur can be found outside of Madagascar

(alternative tagline: did you realize that hippos and lemurs used to be neighbours?)

I'm referring, of course, to Avahi. GNOME relies on Avahi to provide mDNS/DNS-SD (aka Zeroconf) functionality. Until now, that's been missing on Cygwin, and for good reason.

In order to deal with anything beyond wide area browsing, Avahi requires low-level networking support, and it currently only has that support for Linux, BSD, and Darwin. Any other platform, and well, you might think you're out of luck, except that we're in good company: OpenSolaris is also a GNOME distro and has been in the same boat. For technical reasons, they chose to make Apple's Bonjour (mDNSResponder) the primary mDNS/DNS-SD service, and patched avahi-daemon to be a client thereof, circumventing the lack of networking support.

It turns out that this solution works for Cygwin as well. A Cygwin-built mDNSResponder wouldn't work for the same reason a vanilla avahi-daemon won't, but the former does work on Windows (as used by iTunes, Safari, and much more). As for the client, since it communicates with the daemon solely via UDP, a Cygwin-native libdns_sd works just fine with a Windows daemon.

So thanks to FOSS, we have a working Windows mDNSResponder, a portable libdns_sd client, and patches for Avahi to use it. The result? A mDNS/DNS-SD stack that works for both Windows and Cygwin seamlessly. The possibilities are endless.

This does mean that you need a working Windows mDNSResponder running on your machine. While it is open source (Apache-2.0), it requires Visual Studio in order to build, so you'll need to get that binary from elsewhere. You might already have it, as it comes with the aforementioned Windows software (look for the "Bonjour Service" in Services or mDNSResponder in taskmgr); otherwise you can download an installer directly from Apple.

Existing GNOME components which can benefit from Avahi have been rebuilt to enable this support, and a handful new programs and plugins have been added as well. A few packages (mpd, xmms2, and libdmapsharing, the latter of which is used by rhythmbox) which support either stack use libdns_sd directly to minimize overhead. As for KDE, 4.6.5 is due to be released upstream any day now, so this feature will be added there as part of that update.

Saturday, March 12, 2011

Fedora Cygwin RPM repository

I have uploaded the first stages of the Fedora Cygwin RPM repository for Fedora 14 i686 and x86_64. I have added a release RPM which will allow installing the packages with Yum or the various PackageKit frontends. Any questions or issues with these packages should be directed to the cygwin-ports-general list for now.