Tuesday, 3 May 2011

Building VIPS for Windows

image[Update 19/9/16: we now have a containerized build system based on docker. You can do this whole process with a single command and without messing up your host OS. The README has details]

[Update 20/03/15: these notes are now part of the build-win32 repository, look at the README there when you download it]

VIPS (as well as NIP) has an excellent history of providing executables to the Windows users of the world with regular stable releases.
Yet there always seems to be one individual who does not desire to wait for the next stable release, and would really like to see a windows executable with the latest patch built sooner.
That guy is usually me! Particularly once John resolved the n-bit palette tiff reader bug recently. However, there is no Visual Studio build for VIPS, and the normal ./configure && make && make install commands tend to fail horribly on a non-UNIX platform.

Why No Visual Studio Build?

imageIt is all about the dependencies. VIPS has approximately thirty libraries that it depends on, and all of those libraries are native *nix libraries. In order to compile VIPS in Visual Studio, you would need to find win32 Dynamic Linked Libraries (DLLs) compiled for each. No easy task, as many of them do not provide a supported win32 build.
Your other option is build each of the libraries yourself and thus provide your own win32 DLL for linking with VIPS. While a noble idea, and one I would love to see someone else make happen, this quickly becomes complicated by the fact that the libraries that need to be compiled have other dependencies themselves. You quickly find that the number of builds you must support in order to manage building VIPS grows to something even more daunting than the dependencies VIPS is directly linked against.

Cross Compiling - MinGW

MinGW provides a complete Open Source programming tool set which is suitable for the development of native MS-Windows applications,image and which do not depend on any 3rd-party C-Runtime DLLs. (It does depend on a number of DLLs provided by Microsoft themselves, as components of the operating system; most notable among these is MSVCRT.DLL, the Microsoft C runtime library. Additionally, threaded applications must ship with a freely distributable thread support DLL, provided as part of MinGW itself).
Although primarily geared towards developers working on the MS-Windows platform itself, we run a cross-compiler variant of the MinGW tools on Ubuntu to generate win32 applications for deployment to MS-Windows.

What About Those Libraries?

imageThe GNOME project has us covered, given that they do quite a bit of work with WINE and other windows emulators, they need a large number of libraries compiled as DLLs as well!
Someone very clever is about to ask, “Why don’t we just use the GNOME DLL’s as our Visual Studio Links?” Unfortunately, it's difficult to target MSVCRT.DLL in VS, unless you start doing tricks with the driver development toolkit. It is sort-of possible to mix C runtimes in one program, but really not advisable.
The more appropriate answer is that John already had a JHBUILD setup to take advantage of MinGW on Ubuntu, and it worked. Certainly far easier than tackling the creation of a Windows Build.

Getting Started

Head over to github and grab the latest from the jcupitt/build-win32 repository. From there, take a quick peak at the README information that shows up at the bottom of the page. For the 7.24 build, it looks something like this:

7.24/README.md

VIPS WIN32

We use jhbuilder to git, mingw to compile, and good old zip to package the vips source code for WIN32.

JHBuild

JHBuild is a tool designed to ease building collections of source packages, called “modules”. JHBuild uses “module set” files to describe the modules available to build. The “module set” files include dependency information that allows JHBuild to discover what modules need to be built and in what order.

MinGW

MinGW, a contraction of "Minimalist GNU for Windows", is a minimalist development environment for native Microsoft Windows applications.
MinGW provides a complete Open Source programming tool set which is suitable for the development of native MS-Windows applications, and which do not depend on any 3rd-party C-Runtime DLLs. (It does depend on a number of DLLs provided by Microsoft themselves, as components of the operating system; most notable among these is MSVCRT.DLL, the Microsoft C runtime library. Additionally, threaded applications must ship with a freely distributable thread support DLL, provided as part of MinGW itself).

PREREQUISITES

Ubuntu Desktop - This doesn't mean you can't get the process to work on anything else. This is simply what we are using and know to work. Tested on 10.10 and 11.04, 32- and 64-bit. Though you can only make a 32-bit Windows binary for now.

OPTIONAL

VMware Player - Bubba runs his Ubuntu Desktop in a VMWare Player on a Windows 7 Ultimate x64 Desktop host.

DEPENDENCIES

It is possible that you already have some of these installed on your Ubuntu Desktop; however, it is not likely that you have all of them. Better safe than sorry, install them all. You might even want to update the whole kit, just for the heck of it.

Build/Tool Related Dependencies

sudo apt-get install build-essential \
wine \
mingw32 \
jhbuild \
autoconf \
automake1.4 \
automake1.7 \
automake1.9 \
autotools-dev \
docbook-utils \
docbook2x \
gtk-doc-tools

Library Dependencies

sudo apt-get install libatk1.0-0 \
libatk1.0-dev \
libglib2.0-0 \
libglib2.0-dev \
libgtk2.0-0 \
libgtk2.0-dev \
libglade2-0 \
libglade2-dev \
libgsf-1-114 \
libgsf-gnome-1-dev \
libpango1.0-0 \
libpango1.0-dev \
libcairo2 \
libcairo2-dev \
libexpat1 \
libexpat1-dev \
libfontconfig1 \
libfontconfig1-dev \
libfreetype6 \
libfreetype6-dev \
gettext \
libpng12-0 \
libpng12-dev \
libxml2 \
libxml2-dev \
tango-icon-theme \
libcxxtools6 \
libcxxtools-dev \
zlib1g \
zlib1g-dev \
zlibc 
These are Ubuntu binaries and of course we will be building a Windows binary. However, some of the packages we build are not very good at cross-compiling and builds can fail unless they can find a native library as well.

CONFIGURATION

You will need to first check out this repository, if you haven't already.

git This

mkdir ~/dev
cd ~/dev
git clone git://github.com/jcupitt/build-win32.git
cd build-win32/7.24

GNOME win32 Packages

As we are building a win32 executable, we need some DLLs to link against, and the GNOME project kindly provides us with a large number of these ready to use!
Run this script to create some directories for zips, tarballs and the build tree and download all the zips you need from Gnome:
./get-win32-packages.sh
If you desire to modify the packages used, just open up the script and edit the list near the end. This is completely optional though, as the ones checked out "should" work just fine for you needs.
After downloading, run the unpack script to unzip the files to your build area:
./unpack.sh

JHBUILD VERIFICATION

We just want to make sure that jhbuild has everything it needs. If all steps have been properly followed up to this point, this should be a no brainer.
jhbuild --file=jhbuildrc sanitycheck
This will most likely complain that it couldn't find automake-1.8 which is fine, we didn't install that. If it complains about anything else, let me know.

BUILD

jhbuild --file=jhbuildrc --moduleset=vips.modules build libvips

PACKAGE

./package-vipsdev.sh

BUILD NIP2

jhbuild --file=jhbuildrc --moduleset=vips.modules build nip2

./package-nip2.sh

UPLOAD YOUR PACKAGE

Assuming everything has worked perfectly up to this point, you will find vips-dev-7.24.5.zip all packaged up and ready to go. You might upload it to your favorite server via scp like this:
scp vips-dev-7.24.5.zip <YOURID>@<YOURSERVER>:/your/favorite/directory

scp nip2-7.24.5-setup.exe <YOURID>@<YOURSERVER>:/your/favorite/directory

CLEAN UP

It is always good to clean up after yourself. Be careful though, this command will delete the package you just created! You did upload it to your favorite server didn't you?
./clean.sh
You'll need to run the unpack script again if you clean up. You won't need to redownload the zips though.

OTHER NOTES

Version Numbers

The scripts currently default to a versioning system of package-major.minor.micro-release like so 7.24.5-1 in order to make everything drop dead simple.
However, it is really preferred for you to version your own package micro-releases.
You can modify the versions by editing these scripts:
clean.sh
package-vipsdev.sh
package-nip2.sh

Patching

A primary reason one might desire to build their own executable, you simply want to make a few changes to the code, or otherwise control how it was compiled.
First, build as described above:
./unpack.sh

jhbuild --file=jhbuildrc --moduleset=vips.modules build libvips
Now go to checkout/vips-7.24.5 and make any source changes you want. Build again to compile your changes.
jhbuild --file=jhbuildrc --moduleset=vips.modules build libvips
And package your new version.
./package-vipsdev.sh
I suggest you rename your zip to avoid confusion. Call it something like vips-dev-7.24.5-rob1.zip.

Conclusion

We have made it as simple as we possibly can to get your win32 build whenever you want it! There is also something a little bit tantalizing about building for Windows on Ubuntu, it’s like forbidden fruit or something. If nothing else, you should build vips.exe simply so that you can say you have cross-compiled an application!

No comments:

Post a Comment