I am pleased to announce some significant progress on a project I have been hard at work on since the beginning of the month. I have not yet posted a status update or even a broad overview of this project at all. Therefore I am writing this article to accomplish both of those goals and perhaps also include a brief tutorial.
After attempting to cross-compile a Gimp plugin for 64-bit Windows, I quickly discovered that the process was difficult, confusing, and nearly impossible to properly complete. I immediately came to the conclusion that some sort of "intermediate tool" was needed in order to ease the pain of cross-compiling libraries and applications. This tool should take care of setting up environment variables, invoking the appropriate build system with the appropriate commands, and perform some helpful utility functions as well.
One of the other conclusions I came to was that forcing a user to cross-compile all of the GTK+ dependencies (and their dependencies, etc.) in order to merely cross-compile a single GTK+ application was ridiculous. Instead, a central repository should exist that contains prebuilt packages for many common libraries. This repository should facilitate easy installation and include information about inter-package dependencies, etc.
From those conclusions, wincross was born.
All of the packages are currently available in the wincross PPA, which can be added to any Ubuntu 12.04 or 12.10 machine using the following command:
sudo apt-add-repository ppa:win-cross-dev/win-cross ; sudo apt-get update
There are currently about 35 libraries packaged, all of them available for both 32 and 64-bit editions of Windows. Basic libraries, such as zlib, libpng, and libogg are included as well as entire frameworks like GTK+, wxWidgets, and Irrlicht. Each source package provides three binary packages:
The first includes development headers and static / shared libraries for 32-bit editions of Windows. The second includes equivalent files for 64-bit editions of Windows. The third package provides a convenient method of installing the first two, cutting down on the amount of typing required.
After adding the PPA above, the first thing you will want to do is install the wincross Python module:
sudo apt-get install python-wincross
Note: this package provides both Python 2k and Python 3k files, ensuring compatibility with current and future Ubuntu releases.
Once you have wincross installed, you can begin cross-compiling applications. Let's begin by creating a simple GTK+ demo application - nothing fancy, just a single window onscreen that we can move around:
#include <gtk/gtk.h>
int main(int argc, char * argv[])
{
/* This will point to the window we create. */
GtkWidget * window;
/* Initialize GTK+ with our command line arguments. */
gtk_init(&argc, &argv);
/* Create a toplevel window and make it visible. */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(window);
/* Quit the app when the window is closed. */
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
/* Run the GTK+ main loop. */
gtk_main();
return 0;
}
I'll assume the above file is saved with the filename "main.c". We also need a simple Makefile that wincross can use to compile our application:
CFLAGS = $(shell pkg-config gtk+-3.0 --cflags) LFLAGS = $(shell pkg-config gtk+-3.0 --libs) -mwindows simple.exe: main.o $(CC) main.o -o simple.exe $(LFLAGS) main.o: $(CC) -c main.c $(CFLAGS)
Now that we have the source code and the Makefile, we can begin the compilation procedure. Open a terminal, change to the directory with the above two files, and run the following command:
wincross make
You will probably receive an error stating something like "Package gtk+-3.0 was not found in the pkg-config search path." This is simply telling us that we don't have the GTK+ development headers and libraries installed yet. Let's take care of that now:
sudo apt-get install mingw-gtk
Don't be alarmed if quite a few packages are listed for installation - GTK+ has a number of dependencies which must be installed in order to compile and link the application above. After the installation completes, you can rerun the "make" command and this time it should succeed.
If you attempt to copy the newly created "simple.exe" executable to a Windows system and run it, you will quickly run into a problem. All of the required DLLs are missing. Thankfully, you can find nearly all of the DLLs you need in the packages you installed earlier. However, how do you know which DLLs you need? Also, isn't manually copying a bunch of DLLs tedious and error-prone?
wincross comes to the rescue here with a simple utility command:
wincross collect-dlls
Heads-up: you will need to run sudo update-dlocatedb before running the above command until a wincross bug is fixed. Running this command updates the database that wincross uses to look for DLLs.
mkdir build # we'll put the app's files in here mv *.exe build # copy the executable there mv *.dll build # copy the DLLs there wincross create-nsis --directory=build --name='Simple Demo' --version=1.0 >installer.nsi makensis installer.nsi
The last two lines perform the real magic. wincross scans the directory we pointed it to ("build") and creates an NSIS installation script. Then we feed that installation script into the NSIS compiler which will generate an installer we can now distribute to our users. wincross does most of the heavy lifting when generating the installer, including guessing what our primary executable is (we only have one, "simple.exe"). If wincross is guessing wrong, you can set it straight by passing the "--primary-executable" argument.
Here is a screenshot of the DLLs and the application running on Windows 7:

Although this has been mentioned before, the steps above are nearly identical if you want to build a native 64-bit executable instead of a 32-bit one. Simply append "--architecture=64" to all of the "wincross" commands and you'll end up with a 64-bit executable instead. It's that easy.
You can explore some of wincross's other commands by typing:
wincross --help
This will give you a list of all of the supported commands. You can find out more about a specific command by typing:
wincross [command] --help
Absolutely! With a project of this scale, we are always looking for more people to help with packaging, compiling, installing, and testing. Just drop me an email (using the address on the About page) or request to join the Launchpad team.
There are currently no comments posted for this item.
Please login to comment.