rpm  
I'm Cross!
(Install Microsoft and Mac OS X Cross-Compilers)

Installation of Linux-hosted Cross-Compilers and Libraries targeting Microsoft Windows and Mac OS X
"Blue Angels" by Lynn Rothan

Contents


What is IMCROSS?

IMCROSS is a simple, scripted method of installing cross-compilers and cross-compiled libraries on a Linux (or possibly other *nix) system, so that you can develop programs targeted to run on Microsoft Windows and Mac OS X at the same time and in the same environment as you develop Linux versions of those programs.  For the Mac, I focus just on Mac OS X versions 10.4 and 10.5, though some cross-built programs may work in earlier versions.  (For example, with current versions, most or all sample programs supplied with IMCROSS work properly on Mac OS X 10.3.)  Similarly, I focus on supporing C/C++ development, but Fortran and Objective-C cross-compilers are provided.  Creation of installer programs for Windows (setup.exe) or Linux, or "application bundles" for Mac OS X, is supported as well.  IMCROSS makes it easy for you to set up such a cross-compilation environment without having to do a bunch of research and maneuver through a bunch of incomplete howtos.

Of course, when I say "simple" and "easy" it should be kept in mind that I mean "relatively simple" and "relatively easy".

Here's a bird's-eye view of what's believed to work vs. what's not supported or not believed not to work at present, among the major tools and core cross-platform toolkits supported:

Major Tool or Toolkit
Windows
Mac OS X
10.4
10.5
XP
Vista
PPC
Intel
PPC
Intel
C, C++
YES
YES
YES YES YES YES
Objective-C
YES YES YES YES YES YES
Fortran 77, Fortran 95
77
77
NO
NO NO NO
wxWidgets
YES YES YES YES YES YES
GTK+
YES YES NO TBD NO YES
FLTK
YES YES YES YES YES YES
Allegro
YES YES YES YES YES YES


Introduction

I run several open-source projects which I develop and mainly use on Linux, but for which I want to create Microsoft Windows and Mac OS X versions as well.  (See, for example, my Apollo Guidance Computer simulation, my DO-178B documentation software, or my Project Gutenberg markup program.)  Usually what this has meant in the past is that I compile my programs and debug them on Linux, and then as an afterthought I fire up a Windows or Mac OS X box, copy all the source code over to it, build the program ... and then iterate when it doesn't work right.  This approach is problematic for a variety of reasons, not the least of which are that it's time-consuming and I don't enjoy it, so the Windows-based executables for my programs tend to lag the Linux versions by months or years, with the Mac OS X executables lagging even more ... or absent entirely since there's only a finite amount of time and enthusiasm.

A much more satisfactory approach would be to be able to build the Windows and Mac OS X versions of the executables at the same time as the Linux executables are built, directly from the Linux box on which I'm developing.  (And by "Linux", I don't mean to exclude other *nix-based environments, such as FreeBSD or Solaris.  It's just that I have much less contact with those.)  If the software you're developing is a command-line program and you're only interested in Windows targets, that turns out to be pretty easy, and I've been doing it for years.  Linux-hosted versions of the MinGW GNU-gcc based Windows-targeted C/C++ compiler can be downloaded and installed fairly easily.

The difficulty level—or at least the difficulty of finding helpful information—goes up dramatically if you need to produce a GUI program or a program incorporating common libraries not included with MinGW.  And it goes up astronomically for Mac OS X targets, particularly if you must have the most up-to-date versions of tools (since nobody who is enthusiastic about Apple has the least interest in developing Apple code on non-Apple platforms).  Even supposing that you figure out (say) how to install some library such as the wxWidgets cross-platform GUI library in a way that lets you use it in a cross-compilation, you will be sure to have forgotten how to do so if you ever need to install it again on some other computer ... as inevitably you will need to do when your own computer dies or is upgraded.  So you google ... google ... google ... and pray.

At any rate, in the course of figuring this out for myself for one of my projects, I idly scripted the cross-compiler/cross-library installation, so that I wouldn't have to solve the problem again in the future.  It occurred to me that other people might benefit from having this installation script.  So here it is!  It has subsequently become somewhat of an obsession, so I keep improving it beyond my actual personal needs.


What Do You Get (by running the IMCROSS script)?

You get the following core functionality, or some subset thereof as influenced by your own choices and/or the target operating system.  What's shown are the versions supported by the current IMCROSS snapshot.

Tool or Library
Win32
Mac OS X
C/C++ compiler toolchain (gcc)
3.4.6 (MinGW)
4.0.1 ("darwin9 fat binaries")
Fortran?
Yes
No
Objective-C?
Yes
Yes
libiconv
1.9.1
1.9.1
libxml2
2.6.31
2.6.31
regular expression library
PCRE 7.6
Native
pthreads library
POSIX Threads for Windows 2-8-0
Native
zlib compression/decompression library
1.2.3
Native
wxWidgets cross-platform toolkit
2.8.9 ANSI
2.8.9 Unicode or ANSI
GTK+ cross-platform toolkit library, and
associated libraries such as those listed
just below.
2.14.7-1
2.14 latest
(Mac OS X 10.5 only
Intel only)
glib
2.18.4-1
At present, it is not feasible
to build these libraries from
source, so we accept whatever
is buildled with the pre-built
GTK+ binaries, and that
may differ for each person
who downloads them.  For
now, we simply assume that
the versions are the same
or later than the Win32
versions listed to the left.
pango
1.22.4-1
atk
1.24.0-1
cairo
1.8.6-1
gettext
0.17-1
libpng
1.2.34-1
libjpeg
6b-4
libtiff
3.8.2
freetype
2.3.6
fontconfig
2.4.2-tml-20071015
expat
2.0.0
FLTK cross-platform toolkit library
1.1.9
1.1.9
Allegro cross-platform toolkit library
4.2.2
4.2.2
readline command-line editing library
5.0-1
6.0  (Note that the native Mac OS X "readline" is really editline, a partial work-alike, which is why we supply a replacement for it.)
Installation-program builder
InstallJammer 1.2.5 for Linux/Win32 IMCROSS templates
and documentation

Almost as important in some ways, you get a Makefile ("Makefile.samples") with sample programs, showing you how to simultaneously build Linux, Windows, and Mac OS X executables using the toolchains and libraries mentioned above.  It also shows you how to make Windows or Linux installer programs, and how to make Mac OS X installation packages.
In addition to the core functionality listed above, you also get less-complete, much less-tested "contributed" functionality from users, at present comprising:

Description of "contributed" library
Windows?
Mac OS X?
Samples?
Installed by
IMCROSS defaults?
Status
(based informal checkout or developer comments only)
Credits
Open Lock Daemon (OLD) (libold) YES
YES
YES
NO
Functional.
Ron Burkey
Simple Directmedia Layer (SDL) library YES
YES
YES
NO
Partially functional (no work in progress).
Ron Burkey
GNOME Structured File Library (libgsf) YES


NO
Functional in Windows, not yet in Mac OS X, no sample program.
Eric Smith
Qt 4 cross-platform toolkit
YES

YES
NO
So far, for Windows only.  Note that the Qt libraries, include files, utilities, etc., are installed in a non-standard IMCROSS location.  Rather than being in .../i386-mingw32/lib, .../i386-mingw32/include, etc., they are installed in .../i386-mingw32/qt4/lib, .../i386-mingw32/qt4/include, etc.  This is similar to what happens in a native Linux Qt installation, so I'm not inclined to change it. 
Sebastian Held



Licensing

IMCROSS is made available under the GNU General Public License (GPL), but frankly the distinction between the GPL and any other "open source" license for IMCROSS itself is pretty irrelevant, since you're unlikely to want to distribute IMCROSS to anyone else.  It's important to recognize that each software package installed by IMCROSS has its own license chosen by that software's developers, and that license may or may not be the GPL.  You need to evaluate the licensing of each package you want to use for the software you intend to distribute to others.  Moreover, if you choose to distribute DLLs (Windows) or dylibs (Mac) with your software, and you choose to distribute all of the DLLs and dylibs that IMCROSS itself installs, you'll have to simultaneously satisfy the licenses for every package installed, whether or not your specific program uses all of the DLLs and dylibs.  IMCROSS itself cannot have a problem with this licensing issue since any packages being installed are downloaded at compile-time from the developer-sites of those packages rather than included with IMCROSS, and that's why I feel justified in not researching the issue myself.

I will not try to describe the licensing for each package here.  The most I will say is that I only have IMCROSS install what I think of as "open source" libraries and tools.  But you need to evaluate these licenses for yourself rather than relying on me to do so for you, and maybe get a legal opinion as well.  You undoubtedly know this already, but nevertheless you've been warned!

Licensing Aggravation with Apple SDK

The Apple SDK contains the headers, startup code, and system libraries needed to compile code for the Mac OS X platform.   This SDK is available for free download from Apple, and I'll describe in a moment how you can do that.  Nevertheless, the process of getting this stuff via download from Apple is extremely inefficient, and involves tools not normally available on Linux computers.  Because of those practical difficulties, I'd prefer to provide the SDK at the IMCROSS website (for automatic download by IMCROSS during installation), rather than ask you to perform a bunch of pointless labor-intensive steps.  But it's questionable whether this conforms to Apple's developer license.  In response to a request for futher clarification and/or special permissions, Apple's Software Licensing has sent an unambiguous refusal to allow downloads of the SDK from the IMCROSS website.  Oh, well!  I'm sure they know that you're just so keen on developing Mac code that you'll forge ahead in spite of any little obstacles thrown in your path.

Here's the process for downloading the SDK from Apple, and for processing it into a form useful to IMCROSS.  The SDK is provided by Apple as part of a much larger package called Xcode.  Unfortunately, the download/preparation process differs for different versions of Xcode.  You may or may not be able to perform the indicated steps in Linux, and therefore may need to use a Mac, so I've provided instructions for both.  (Thanks are due to Kalle Kataja for reopening the issue of pure-Linux processing of the Xcode download, after I had given up on it!)  As a visual aid, I've colored the default version expected by IMCROSS green, and grayed out alternate possibilities.

Xcode version
Instructions for preparing entirely in Linux
Instructions for preparing with some Mac OS X assistance
Xcode 3.x
(for current version of IMCROSS)
(These instructions tested with Xcode 3.1.2 build 2621)
  1. Go to developer.apple.com and create a free account for yourself, download Xcode 3.x.
  2. Download, build, and install the program dmg2img.  This is an open-source (GPL) program.
  3. Uncompress the Xcode dmg file which you downloaded into an img file, which for the sake of argument we'll suppose will be named "Xcode.img":  "dmg2img -i DownloadedDmgFile -o Xcode.img".
  4. Mount the img file just created into the filesystem.  For the sake of argument, we'll suppose that this is done at the mountpoint ~/mnt:  "mkdir ~/mnt ; sudo mount -t hfsplus -o loop Xcode.img ~/mnt".  (This supposes that your version of Linux has compiled-in support for the hfs+ filesystem.  It may be necessary to explicity load the kernel module, as for example "sudo modprobe hfsplus".
  5. Install the xar program.  For Linux distributions like newer Fedora and Ubuntu, this can be done through yum or apt.  If not, you can get it from Google Code.
  6. You'll notice a file called ~/mnt/Packages/MacOSX10.4.Universal.pkg.  This is an Apple "flat package" which needs to be unpacked into a directory structure using xar:  "xar -xv -f ~/mnt/Packages/MacOSX10.4.Universal.pkg".  It is best to do this in an empty directory.
  7. One of the files resulting from this unpacking, "Payload", is itself an archive which needs to be unpacked into a directory structure:  "zcat Payload | cpio -id", thus creating a directory called "SDKs".
  8. Make a tarball from this directory with the command "tar --bzip2 -cf macosx-headers-10.4u-version.tar.bz2 SDKs/MacOSX10.4u.sdk", where "version" indicates the version of Xcode used.
  9. Copy the tarball to the IMCROSS directory
  10. Customize your IMCROSS build-settings, so that XCODE_VERSION=version.
(These instructions tested with Xcode 3.0)
  1. On Mac OS X 10.5 (10.4 will not work) perform the following steps:
    1. Go to developer.apple.com, create a free account for yourself, download Xcode 3.x.
    2. Install Xcode on the Mac.
    3. From a command-line, 'cd' to /Developer, where you should find a directory called "SDKs".
    4. Make a tarball from this directory with the command "tar --bzip2 -cf macosx-headers-10.4u-version.tar.bz2 SDKs/MacOSX10.4u.sdk", where "version" indicates the version of Xcode used.
    5. Copy the tarball to the IMCROSS directory on the Linux workstation you want to use.  (The Mac is no longer needed beyond this point.)
  2. On the Linux box, perform the following steps:
    1. Customize your IMCROSS build-settings, so that XCODE_VERSION=version.
Xcode 2.2.1
(for original version of IMCROSS)
Not tried.  However, a simplified variant of the Xcode 3 instructions above, without steps 5-7, may work for you.
  1. On a Mac, perform the following steps:
    1. Go to connect.apple.com, create a free account for yourself, and log in.
    2. Go to "Downloads". 
    3. Go to "Mac OS X".
    4. Go to "Xcode Tools 2.2.1", and download the .dmg file (about 850MB).
    5. Double-click the .dmg file just downloaded.
    6. Go to "Packages"
    7. Find "MacOSX10.4.Universal.pkg" but do not double-click it!  Instead, right-click it and choose "Show package contents".
    8. Go to "Contents"
    9. Drag-and-drop Archive.pax.gz to the desktop.
    10. Somehow, transfer this file to your Linux box.  (The Mac is no longer needed beyond this point.)
  2. On the Linux box, perform the following steps:
    1. Unpack the archive with the command "gunzip <Archive.pax.gz | pax -r".
    2. The unpacking just done will have created a directory called "Developer".
    3. Within "Developer", you'll find a directory called "SDKs".  Make a tarball from this directory with the commands "cd Developer" and "tar --bzip2 -cf macosx-headers-10.4u-2.2.1.tar.bz2 SDKs/MacOSX10.4u.sdk".
    4. Copy the tarball to the IMCROSS directory.
    5. Customize your IMCROSS build-settings, so that XCODE_VERSION=2.2.1.
Xcode 2.5
(used by some people in place of 2.2.1 for original version of IMCROSS)
Not tried.  However, a simplified variant of the Xcode 3 instructions above, without steps 5-7, may work for you.
  1. On a Mac, perform the following steps:
    1. Go to developer.apple.com, create a free account for yourself, and log in.
    2. Download Xcode 2.5 (about 900MB).
    3. Double-click the .dmg file just downloaded.
    4. Go to "Packages"
    5. Go to "Packages" on the next screen as well.
    6. Find "MacOSX10.4.Universal.pkg" but do not double-click it!  Instead, right-click it and choose "Show package contents".
    7. Go to "Contents"
    8. Drag-and-drop Archive.pax.gz to the desktop.
    9. Somehow, transfer this file to your Linux box. 
  2. On the Linux box, perform the following steps.  (The Mac is no longer needed beyond this point.)
    1. Unpack the archive with the command "gunzip <Archive.pax.gz | pax -r".
    2. The unpacking just done will have created a directory called "SDKs".
    3. Make a tarball from this directory with the command "tar --bzip2 -cf macosx-headers-10.4u-2.5.tar.bz2 SDKs/MacOSX10.4u.sdk".
    4. Copy the tarball to the IMCROSS directory.
    5. Customize your IMCROSS build-settings, so that XCODE_VERSION=2.5.


Some versions of Xcode additionally contain other SDKs, such as those for Mac OS X 10.2.8, 10.3.9, or 10.5.  If you had these, you could theoretically perform compilations against those Mac OS X versions rather than against 10.4u.   IMCROSS doesn't have any provision as such for installing them, but all you have to do is to copy one or more of them to the installation directory's SDKs sub-directory.  How to use them is a question I don't have the answer to.



Design decisions and problems

Decisions

IMCROSS is not actually a shell script as I implied above.  It's really a makefile used with GNU make.  The makefile:
Toolchain and library version codes, as well as the URLs for downloading the source code, are hard-coded into the makefile.  Also hardcoded are installation-directory names and program prefixes (such as "i386-mingw32").  You're free to modify any or all of those within the configuration settings, though obviously I won't vouch for the results.

Where possible, IMCROSS builds tools and binaries from source rather than installing existing binaries.  I have no real rationale for this, except that I think it's more valuable to know how to build the binaries than how to merely install the binaries.  Examples where I flatly couldn't figure it out (or where figuring out exceeded any rational time-budget) are Allegro and GTK+, so all of these were installed from binary packages.  While this is both quick and convenient, it also makes it almost impossible to adapt or to repair these libraries.

Where feasible, Windows  and Mac OS X libraries are built for static linking (*.a), rather than as shared libraries (*.dll or *.dylib).  This is a conscious decision on my part.  Even though it results in executables that are much larger than the corresponding Linux executables, it means that you can more-often distribute your program simply by copying the executable files (and any supplemental files that are specific to your project), rather than distributing a bunch of .dll or .dylib files at the same time.  What's wrong with dynamic libraries?  Well, figuring out which .dll or .dylib files are needed, and figuring out how to get them installed on the target Windows or Mac OS X computers, is an annoyance Linux developers don't need.  A Linux developer shouldn't have to worry about complaints from users like "Your program won't run because XYZ123.DLL is missing, you insensitive clod!" and answering the user with comments like "But I don't know anything about troubleshooting Windows or Mac OS X!" may be a less satisfactory response than you imagine.  (Your opinion may differ from mine, and you're free to modify the script to change this assumption if you like.)

For Mac OS X, Open Darwin 'odcctools' is used in place of Apple's 'cctools'.  I believe the distinction is that the Open Darwin tools have had their build system improved (to use 'configure' and what-not), so that building cross versions of them is easier than for the pure Apple tools.  On the other hand, the Open Darwin project has been discontinued, so ongoing maintenance of the tools is nil; fortunately, odcctools is also used for iPhone software development on Linux, and so iPhone development enthusiasts still support it to a certain extent.

And then there are the unavoidable exceptions to these rules.  So here is a complete inventory of static vs. dynamic, for the core IMCROSS libraries:

Library
Windows static link?
Windows DLL?
Mac OS X?
PCRE (regular expressions) YES

n/a (native)
POSIX Threads for Windows YES
YES
n/a (native)
zlib
YES

Native system .dylib
wxWidgets
YES
YES
IMCROSS static and .dylib
GTK+ and friends (glib, pango, etc.)

YES
GTK+ .dylib (needs to be included with the executable)
Allegro
YES
YES
IMCROSS static
FLTK
YES

IMCROSS static
libiconv
YES
YES
IMCROSS static
libxml2
YES

IMCROSS static
readline
YES (in theory)
YES
IMCROSS static

Problems

The principal technical problems with IMCROSS at the present time, in roughly descending order of importance, are:
  1. The present version of wxWidgets as cross-compiled for the Mac apparently has string-conversion functions (such as wxString-to-Mac Unicode) which are not thread-safe.  In other words, string conversions must be confined to a single thread, or else protected by mutexes.
  2. The Windows version of wxWidgets-based cross-compiled programs show some slight behavioral differences from the Linux or Mac OS X versions of those programs.  You can see this in the provided sample program.  This may be due to Unicode vs. ANSI builds of wxWidgets.  I do not believe that it will be possible to do a Unicode build in Windows until MinGW upgrades to gcc 4.
  3. The Apple version of gcc does not support Fortran, and Fortran is not yet supported for Mac OS X in IMCROSS.
  4. The Mac tools gcc 4 or later to build.  (gcc 3 or earlier does not work.)

Download (and change-log)

Version
Link
Win32 target
Mac OS X  target
Tested
Comments
April 26, 2009
IMCROSS-20090426.tar.gz
readline 5.0-1 (New!)
readline-6.0 (New!)
Build platforms
Ubuntu 8.04 65-bit
Fedore Core 5 32-bit

Target platforms
Mac OS X 10.5.6 Intel
Mac OS X 10.4.11 PPC
Windows XP Home
[Focus of this version:  Minor features and updates.]

The GNU readline library has been added to the core functionality, because I found that I needed it.  The Windows version used is older, because patches are needed for the Windows platform that don't seem to be available with newer versions.  It should be noted that while Mac OS X appears to have readline, what it really has is a partial work-alike (editline) that is not 100% API-compatible.  Pay special attention to the make-rules for the sample program provided to see how to override the Mac OS X native library, if you wish to do so.

wxWidgets now builds both static and shared libraries.  However, the shared libaries are only lightly tested at this point.

On Windows, SDL now builds static libraries from source rather than installing a binary tarball of dynamic libraries.  Some of the observed deficiencies which caused the prebuilt binaries to be used previously turn out to be due to a generic problem (and workaround) with SDL on Windows rather than with the library build as such.

InstallJammer has been updated to v1.2.12 (from 1.2.5).  I can't give you any specific reason for making this change.

Updating
 
If you have already cross-built SDL, you'll have to undo it with the following manual steps in the IMCROSS installation directory:  delete i386-mingw32/bin/SDL.dll, i386-mingw32/bin/sdl-config, i386-mingw32/include/SDL/, and i386-mingw32/lib/*sdl*.  In the IMCROSS build directory, remove Contributed/SDL/setup*.  Then rebuild IMCROSS.  Note also the changes in the workaround that will have to be made to the build-procedure for your SDL-based application code.
March 21, 2009
IMCROSS-20090321.tar.gz
(No change)
(No change)
Build platforms
OpenSUSE 11.1
Fedora 10
Ubuntu 8.10

Target platforms
Mac OS X 10.5.6 Intel
Mac OS X 10.4.11 PPC
Mac OS X 10.3.9
[Focus of this version:  Mac tools on gcc 4.3 platforms]

Thanks to Thomas Giesel, IMCROSS's Mac OS X tools can now build on gcc 4.3 platforms.  As Thomas has pointed out, the problem is not gcc 4.3 at all; rather, it is a goofy bug in glibc 2.8, which just coincidentally appears on the same machines.  At any rate, Thomas has tracked down this problem and supplied a fix for it, so as far as I know the full range of IMCROSS tools and libraries can now be built on any gcc 4 Linux platform.

Updating

Simply run 'make'.
February 19, 2009
IMCROSS-20090219,tar,gz
(No change)
(No change)
Build platforms
Fedora 8 32-bit

[Focus of this version:  Bug fix.]

The ANSI vs. Unicode feature of yesterday's snapshot had a bug, in that the disabling of Unicode-enabled builds of wxWidgets for Win32 was not done correctly.  This causes a failure to install IMCROSS on systems which have a Unicode-enabled native wxWidgets installed.

Updating

There is no need for this bug fix unless you used yesterday's snapshot and experienced a failure.  If so, simply download and re-run 'make'.
February 18, 2009
IMCROSS-20090218,tar,gz
(No change)
(No change)
Build platforms
Fedora 8 64-bit
Ubuntu 8.04 64-bit
(K)ubuntu 8.04 32-bit

Target platforms
Mac OS X 10.5.6 Intel
Mac OS X 10.4.11 PPC
[Focus of this version:  Mac OS X Tools on 64-bit Linux distributions.]

Mac OS X Tools:  Thanks to John Meacham, we have a fix for the problem of not being able to build the Mac OS X toolchain and libraries in 64-bit Linux.  In other words, you can now build the Mac OS X toolchain and libraries in 64-bit Linux without using a funky workaround.

wxWidgets:  In previous snapshots, we always did an ANSI build for Win32 and a Unicode build for the Mac.  Now we instead try to match the build types to the build type for the native Linux wxWidgets.  This works if the native build is ANSI.  However, if the native build is Unicode, we will still make the Win32 build ANSI since we don't yet have the capability of doing a Win32 Unicode build.  These are just the defaults; the setting can be customized using the WX_TYPE variable.

Updating

At last an easy one!  There's no good reason to upgrade unless you are on a 64-bit Linux box and want to use the Mac OS X tools and libraries.  Just run 'rm setup_macosx* ; make', remembering of course that if you haven't been building the Mac tools then you may not have all of the prerequisites listed in the build-instructions.
February 15, 2009
IMCROSS-20090215.tar.gz
wxWidgets 2.8.9
gtk+
2.14.7
wxWidgets 2.8.9
gtk+
2.14.7 (New! 10.5 Intel only)
Build platforms
Fedora Core 1 32-bit
Fedora Core 5 32-bit
Fedora Core 6 32-bit
Fedora 7 32-bit
Fedora 8 32-bit
Fedora 9 32-bit
Fedora 10 32-bit
OpenSUSE 10.1 32-bit
OpenSUSE 10.3 32-bit
OpenSUSE 11.1 32-bit
(K)ubuntu 7.04 32-bit
(K)ubuntu 8.04 32-bit
Ubuntu 8.04 64-bit
Ubuntu 8.10 32-bit
(The red platforms
cannot build
the Mac toolset.)

Target platforms
Windows XP Home
Mac OS X 10.4 PPC
Mac OS X 10.5 Intel

[Focus of this version:  Support for Intel architecture and XCode 3 on Mac OS X 10.5, addition or updating of gtk+ and wxWidgets support for all platforms, bugs on various build-platforms fixed, auto-configuration.]

General:
  • By default, the make option "USE_HOME=yes" is now assumed, and if you want to return to the former default behavior you have to explictly say "make USE_HOME=no".  In plain English, this means that instead of installing by default in /usr/local and /opt/mac, installations are by default done in ~/IMCROSS.  See the notes in the customization section for the reasons behind this change.
  • By default, core libraries like wxWidgets, as well as tools like Fortran and Objective-C, are now installed only if the native Linux dev packages of the libraries are already installed (or if the libraries have been installed from source).  The resulting installations will usually be much quicker and much smaller, as well as taking much less bandwidth.  I suspect this removes most of the need for customizing IMCROSS installations.  However, you can still customize if you like to force the libraries to be built without regard to the presence or absence of the native forms.
  • Lots of problems that prevented IMCROSS from building on various platforms have been fixed.  I hope it should build on almost any Linux distribution, but there are some limitations on platforms which can build the Mac tools.
  • At the beginning and end of the installation, IMCROSS displays a summary of all the tools and libraries it will install, as well as a list of the prerequisites needed.
On Mac OS X:
  • Intel on Mac OS X 10.5 now works—i.e., the programs now work when run on the Mac, rather than merely compiling but bombing when you try to run them.  Thanks to Nils Tonagel for supplying some info on this and prodding me to keept trying!
  • SDK 10.4u from Xcode 3 is now supported.  While it has not been my intention to break Xcode 2, I do not think that Xcode 2 still works with IMCROSS, and I don't care enough about it to follow up on it.  (The problem is that I don't think Intel on Mac OS X 10.5 can be made to work from Xcode 2.)
  • gcc and cctools versions updated from 'darwin8' to 'darwin9'.
  • PPC64 architecture is no longer supported as an architecture separate from PPC.
  • wxWidgets (currently-supported version) is known to have non-thread-safe string conversions.
  • gtk+ is now available but presently (I believe) only for 10.5 and only for Intel.
  • Mac OS X tools are thought to build only on 32-bit CPUs (not 64-bit CPU), only for gcc 4.0, 4.1, or 4.2, and only if Objective C is installed natively.  Possible workarounds are described with the build-instructions below.
On Windows:
  • gtk+ updated from 2.12.9 to 2.14.7 due to unavailability of previous download bundle. 
  • IMCROSS now uses a different downloading method for gtk+ which may be less vulnerable to retirement of the needed online package bundles.  Thanks to D. Haley and Steven Holloway for pointing out this problem.
Updating

In spite of the vast number of changes, the principal reason for updating would be to get improved Mac OS X support, so read the limitations discussed above to see if you will even be able to build the Mac tools and libraries.  Because the changes are so major, if you wish to upgrade I'd suggest the following:
  1. Archive your existing IMCROSS installation directories in case you need to fall back on them later.
  2. Completely wipe the existing IMCROSS installation directories.  Be careful, obviously, if you installed in the previous default /usr/local not to wipe non-IMCROSS programs.
  3. Archive your existing custom configuration file, if any, but then delete the original.
  4. Do "make clean_imcross".
  5. do "make".
June 4, 2008
IMCROSS-20080604.tar.gz
(No core change)
(No change)
SUSE 10.0
Windows XP Home
Fedora 9
[Focus of this version:  Contributed features.]

Sebastian Held's contributed Qt 4.4 build for Windows now has a sample program, and I'm willing to say that it works, and hence that Qt is working.  I did encounter problems with a different sample program, but I think that may be either error on my own part, or else some interaction between Qt and MinGW that you'd have encountered even without cross compiling.

I fixed a problem with the installation of the Qt utilities, in that their naming had to be changed in order to be consistent with Qt's qmake utility.  Specifically, the utility programs named 'moc', 'rcc', and 'uic' had to be renamed 'moc.exe', 'rcc.exe', and 'uic.exe', even though they are in fact Linux programs rather than Windows programs.  Without this renaming qmake may create application-code Makefiles that abort due to not being able to find the appropriate utility programs.

Developer system requirements:  No change from 20080603.

Updating:  The same comments apply as for 20080603, with one addition: if you already installed Qt using the 20080603 IMCROSS snapshot, you need to make the following mods to the installation:
cd where/you/installed/IMCROSS/i386-mingw32/qt4/bin
ln --symbolic moc moc.exe
ln --symbolic rcc rcc.exe
ln --symbolic uic uic.exe
If Qt is enabled, then 'make samples' should now be able to build sample_Qt.exe for you.
June 3, 2008
IMCROSS-20080603.tar.gz
(No core change)
(No change)
SUSE 10.0
[Focus of this version:  Contributed features.]

The contributed Qt 4.4 now cross-compiles for Windows.  (Thanks to Sebastian Held!)  I have personally tested merely that the build goes through to completion, and don't yet have a sample program working.  Hopefully, I'll be able to rectify that in a day or two.  Sebastian reports that Qt works, but I have had to make a few modifications, so don't blame him if it isn't really fully working yet.  As usual with contributions, the build is inhibited by the presence of the constant NO_Qt=yes in the default configuration.  If you have a custom configuration, and don't want Qt, it would be a good idea to add this constant since the build takes a monstrously long time!  Since there is no sample program yet, Contributed/Qt/Makefile.win32 contains some abbreviated instructions for compiling application code using the library.

There is now a GIT repository for IMCROSS, created by Johannes Schindelin.  Thanks, Johannes!

I now have information on cross-compiling from Linux to an iPhone/iPod Touch target system.  (Thanks to Jason Pollock.)  I'm undecided as yet whether to try and incorporate this into IMCROSS.  If anyone has an opinion, please let me know.

Various fixes related to portability of the IMCROSS installer.  If you're happy with your installation, you don't need them.

Developer system requirements:  If you want to install Qt, there will be approximately 95 MB of additional downloads and approximately 76 MB extra of libraries and what-not after installation.

Updating:  If you want to install Qt, make sure that 'NO_Qt=yes' is commented out in the default or custom configuration file, and then do 'make'.  You don't need to rebuild the sample programs, since there's no sample program for Qt yet.  If you don't want Qt, make sure there's a line reading 'NO_Qt=yes' in your custom configuration file (if any), but you don't need to actually do anything else.
Current ...
RegressionTests-windows.zip

If you simply want to try the cross-compiled sample programs without installing IMCROSS to see what you'd be getting or to help us perform testing, you can download just the pre-compiled sample programs.
RegressionTests-macosx.tar.gz
Older ...
Older-changes page
The table you're reading now contains the change-log just for current or recent versions of IMCROSSIf you to look at the change-log for older versions, please visit the older-changes page.
GIT repository
Older tarballs are routinely eliminated from the IMCROSS site as a space-saving measure, but you can visit the GIT repository created by Johannes Schindelin (thanks, Johannes!) if you want to retrieve their contents.  Since the GIT repository is maintained independently of IMCROSS, it may lag the current development snapshot somewhat.


Usage

Running the Installer for the Cross-Toolchains and Cross-Compiled Libraries

Some prerequisites are needed to run the installer.  As of 20090210 the installer will check for all of the prerequisites that it can, and then report and abort if any are missing.  Depending on which tools and libraries you are installing, these prerequisites include autoconf, bison, flex, patch, wget, zip, unzip, subversion, and pax.  The installer will also insist that the IMCROSS installation directory be in your PATH, and that it follow all instances of /usr/bin and /usr/local/bin in the PATH.

Unfortunately, at present we cannot build the Mac OS X toolset and libraries on some platforms.  The following constraints must be obeyed, and IMCROSS checks these constraints at the same time as it checks other prerequisites.  If it finds them lacking, it will default to disabling building the Mac OS X toolsets and libraries.
Some other things which you need but which IMCROSS can't or won't perform an up-front check for are:
The actual IMCROSS installation is pretty simple:
  1. Unpack the downloaded tarball to create the IMCROSS directory.  But don't do it directly under your home directory, since that is the default location (~/IMCROSS) for the installed files.  (Sorry about that.) 
  2. If you are going to build the Mac OS X toolchain and libraries, you need to follow the instructions given earlier for downloading XCode 3 from Apple and extracting the SDK from it.
  3. From a command-shell, 'cd' into the IMCROSS directory and do 'make'.
By default, for 20090210 and later, IMCROSS will generally only install those cross-build tools and cross-compiled libraries for which you already have a native version of the tool installed.  The rationale for this is that some of these libraries are very large, and if you don't have the native form of the library already installed it's unlikely you're doing cross-platform development work using it.  However, in most cases there's no technical reason why you absolutely have to have the native tool installed to use a given cross tool.  So if the assumption that you didn't want a given library is incorrect, you can use the custom/override-settings technique of the next section to force a given cross-tool or cross-library to be installed; though a more straightforward method may simply be to install the native libary in question (in the "dev" or "devel" package) and then to re-run IMCROSS.

As mentioned above, IMCROSS's Mac tools cannot be built on some Linux platforms.  In this space I used to give an elaborate workaround that might allow you to build the tools and then install them on such a platform.  Since the number of offending platforms has dwindled to a pleasing few, let me simply say that if you still have a problem, my recommendation would be to install a free virtual machine (such as VirtualBox) and install a 32-bit version of Fedora 8 on it, then install IMCROSS in the virtual machine.

Trouble-shooting a failed installation

I've not experienced any of these problems personally.

Customization of installation

If you want to customize your IMCROSS configuration, there are two methods:
In a practical sense, use of Makefile.override-settings is superior to use of Makefile.custom-settings.  While both methods provide persistent settings that survive upgrades to IMCROSS itself, the Makefile.custom-settings method is much more likely to require manual fixes than is the Makefile.override-settings.  The reason for this is that Makefile.custom-settings needs to contain all of the same settings as Makefile.default-settings, while Makefile.override-settings need merely contain those settings which are different.  Perhaps an example would clarify this point:  Suppose that the only setting you are interested in changing is the NO_MAC variable.  With the Makefile.custom-settings method, the Makefile.custom-settings file would contain a complete copy of Makefile.default-settings, differing only in the way the NO_MAC variable is handled.  With the Makefile.override-settings method, Makefile.override-settings would contain only a setting for the NO_MAC variable, but none of the other contents of Makefile.default-settings.  If IMCROSS was upgraded later, the Makefile.default-settings file could easily contain new variables, or changes to existing variables other than NO_MAC, and you'd need to determine all of these differences so that your Makefile.custom-settings file could be fixed.  The Makefile.override-settings file, on the other hand, would likely be fine as-is and would need no manual modifications.

Of particular interest is that while some libraries (such as zlib) are viewed as critical and are always installed, there are some libraries that can be omitted if you don't want them, thus saving download bandwidth and disk space.  For example, you could eliminate wxWidgets and GTK+ if you liked, or you could eliminate the entire Mac OS X toolchain/libraries.   Additionally, "contributed" libraries can always be skipped (and by default are skipped) by placing "NO_name=yes" in the custom/override settings, where "name" is the name of the contribution (according to its directory name IMCROSS/Contributed/name).  As mentioned in the preceding section, from snapshot 20090210 and onward, the default configuration adjusts most of these settings based on whether or not you have the native versions of the libraries installed, so I suspect that there's usually little need to customize this aspect.

Something which may additionally be important to some people is that there is the ability as of snapshot 20080521 to perform the entire IMCROSS installation in directories other than the defaults.  The default in IMCROSS 20090210 and later is to simply install everything in ~/IMCROSS.  But in more detail, the directory setup looks like this:

Default IMCROSS installation directories
${PREFIX_WIN32}/


For IMCROSS versions prior to 02/2009, the default was /usr/local/, whereas it is now ~/IMCROSS.  Set ${SUDOWIN} to "sudo" or to "" to control write-access by IMCROSS to this directory, depending on whether or not root access is required.

bin/

This is where you find links to programs like i386-mingw32-gcc and powerpc-apple-darwin9-gcc.

${TARGET_WIN32}

 By default, "i386-mingw32-".


bin/
*.exe, *.dll, shell scripts like wx-config, etc.


lib/
*.a


include/
*.h


man/
man pages for i386-mingw32


qt4/
bin/, include/, lib/, etc. for the contributed Qt library, if enabled.


etc.

${JAMMER_DIR}/


Where InstallJammer is installed.  For IMCROSS versions prior to 02/2009, the default was /usr/local/InstallJammer, whereas it is now ~/IMCROSS/InstallJammer.  Set ${SUDOJAM} to "sudo" or to "" to control access by IMCROSS to this directory.
${PREFIX_MACOSX}/


For IMCROSS versions prior to 02/2009, the default was /opt/mac, whereas it is now ~/IMCROSS/mac.  Set ${SUDOMAC} to "sudo" or to "" to control write-access by IMCROSS to this directory, depending on whether or not root access is required.

SDKs/

Apple SDKs.

bin/

Executables, shell scripts like wx-config, etc.

lib/

*.a

libexec/

*.dylib

include/

*.h

etc.



As mentioned above, the default settings differ in early IMCROSS versions to those in later versions.  You can revert to the former settings (such as /usr/local rather than ~/IMCROSS) by putting "USE_HOME=no" on the 'make' command line or else setting it as an environment variable.  Alternately, the variables mentioned above can be customized as described above in Makefile.override-settings or Makefile.custom-settings.

This kind of change to the defaults is very annoying.  The reason it was done is that I ordinarily recommend that the installation directory for IMCROSS be placed at the end of your PATH, while Linux distributions which have /usr/local/bin in their PATH typically place it early in the PATH.  This can result in having programs like pkg-config or wx-config that are provided with IMCROSS overriding the native versions of those programs, thus breaking the ability to build some native-Linux versions of applications.  There is also the big benefit that if installed in ~/IMCROSS instead of /usr/local, no administrative permissions are needed.  So while I apologize for the inconvenience, I think that the change is a necessary one.

More details of installation

A useful option in some cases is 'make clean_imcross' to completely wipe the previous installation directories and temporary build directories, so that 'make clean_imcross default' would rebuild everything cleanly (but without having to redo any downloading if you retained the downloaded source tarballs).

Afterward, you'll find various links for the compiler-toolchain programs in the 'bin' subdirectory of the installation directory, so it's useful if this directory is in your PATH (usually at the end of your PATH).  Typically this will be ~/IMCROSS/bin (formerly /usr/local/bin) by default. 

In the IMCROSS/ directory from which you ran the installer—not to be confused with the ~/IMCROSS/ installation directory!—upon successful completion you'll have the following new files:
In theory, the entire IMCROSS/ directory can be deleted at this point.  Personally, I'd recommend retaining it in case you might like to obtain a newer version of IMCROSS later.  The files itemized above are present to tell IMCROSS which versions of which tools have been successfully built and installed, so if you keep them, then IMCROSS will later only need to rebuild the specific tools and libraries which have changed (or which are completely new), making successive installations much quicker.  If you like, you can reclaim the space used by the tarballs, which can be quite subtantial, with the command 'make diet', which replaces each tarball that was successfully built by a tiny file of the same name.  Note, however, that the tarballs may be useful if you want to propagate the development environment to other workstations.  You could undo 'make diet' later with 'make binge' to re-perform all of the downloads but without doing any rebuilding of the software packages.

Upon unsuccessful completion, the directory called "IMCROSS/temp-cross-compiler-build" may not be empty.  The amount of space used by this directory can be enormous, so you may want to delete it.  There could also be (unnecessary) directories named "build" and "output".

Cross-Compiling Some Actual or Sample Programs

The IMCROSS/Samples directory contains sample programs demonstrating functionality from many of the included libraries, and IMCROSS/Makefile.samples gives the build-instructions for each of them, so Makefile.samples is a resource that should be of interest to every developer who installs IMCROSS.  The main purpose is to demonstrate appropriate build-procedures related to the libraries.  For example, IMCROSS/Samples/wxWidgets contains code that uses the wxWidgets library.  There's also an IMCROSS/Samples/CommandLine directory that illustrates a simple command-line program.  Some of these programs don't do much, though some are surprisingly nice, but they do demonstrate how you can cross-compile and link your own programs by imitating what's in the Makefile and what's in the sample programs (where some slight source changes are illustrated that accommodate Windows vs. Linux differences).   Incidentally, the EXE versions of the programs all run under WINE as well as Windows, assuming your copy of WINE is correctly configured.
If you simply want to try the cross-compiled sample programs before installing IMCROSS to see what you'd be getting or to help us perform testing, it is possible to download just the pre-compiled sample programs (except for gtk+ sample programs which are just too darned big).

To build the complete set of sample programs, 'cd' into IMCROSS and run 'make samples'.  The command creates a bunch of executables with names like "sample_*".  Actually, the full naming convention is:
For example, there will be executables sample_wxWidgets (Linux), sample_wxWidgets.exe (Windows), and sample_wxWidgets_macosx_fat (Mac OS X) having the same functionality but executing on three different platforms. 

Concerning the Mac OS X targets, two points should be noted:  Firstly, unless otherwise stated the universal binaries contains just the Intel and PPC architectures, since I haven't found many system libraries that support the PPC64 architecture.   (With snapshot 20081006 and later, PPC64 support is no longer even present in the default compiler configuration.)  Secondly, my test machines are presently limited to Windows XP and Mac OS X 10.2.8, 10.3.9, 10.4 (PPC), and 10.5 (Intel); therefore, any feedback about broken (or working) sample programs or libraries would be helpful.

Since 'make samples' compiles the sample programs for Windows, for Mac OS X, and for Linux,  you'll have to have all of the tools and all of the native versions of the libraries (except PCRE and pthreads-w32, which aren't needed on Linux) installed on your computer if you expect to get all of the Linux sample programs.  Remember, the only thing we've done is to install Windows and Mac OS X versions of tools and libraries, so there's no guarantee that you have Linux versions of any of them installed, even though by default IMCROSS only installs cross-libraries for which the native libraries already exist.  But I've tried to make the Linux compilations fail gracefully if any of them are missing, instead of aborting the build, so you'll still get all of the Windows and Mac OS X sample programs.

Alternately, you could do one of the following:
I don't suppose the exact nature of these sample programs is particularly interesting to anybody, but just for the record, here's a list of sample programs for core IMCROSS functionality.  There's also further info on how to run some of these programs in the "Testing the IMCROSS Installation" section below.

Sample Program
Target System
Language
Description
sample_CommandLine.exe
Windows
C
"Hello, world!"

For Mac OS X, this is one of the sample programs that includes a PPC64 architecture.
sample_CommandLine Linux
sample_CommandLine_macosx_fat
Mac OS X
sample_Fortran.exe
Windows
Fortran
Enter the integer lengths of 3 sides of a triangle, and the program will print the lengths along with the area of the triangle.  Hint:  After running the program, you'll be presented with a blank line; enter "2 3 4", without the quotes.  I cut-and-pasted this program from the Wikipedia article on Fortran, and then modified it substantially to make it work.  (Alas! while I was an expert in Fortran 25 years ago, I couldn't write a line of it to save my own life now.)
sample_Fortran Linux
sample_gtk_dynamic.exe Windows
C
A sort of tic-tac-toe game.  It's not really tic-tac-toe, but it's an array of 3×3 squares; you click on the squares until you have 3 in a row (horizontally, vertically, or diagonally), and then a congratulatory message appears.  This is an example program from the GTK+ tutorial, and not something I've created.  The suffix "_dynamic" appears to remind you that you need DLLs to run the program.

The program sample_gtk_installer.exe is a Windows installer for sample_gtk_dynamic.exe. There is also a Mac OS X package IMCROSS-gtk.app.tar.gz.  In general, these are not provided online here and have to be rebuilt locally, because the necessary inclusion GTK+ dll or dylib libraries makes them too big to be worth it for me to waste the bandwidth providing them to you.
sample_gtk_installer.exe
sample_gtk Linux
sample_gtk_macosx_i386
Mac OS X
sample_libxml2.exe
Windows
C
Reads a specified input XML file from a file listed on the command line, and outputs info about the elements found in it to the standard output.  I didn't actually write this; it's a sample program from libxml2 itself.  If you want to modify this sample program, be sure to read the copyright notice in the accompanying file.
sample_libxml2
Linux
sample_libxml2_macosx_fat
Mac OS X
sample_Objective-C.exe
Windows
Objective-C
Simply displays the message "Recipient says hello!", but does it using the extremely funky methods of Objective-C, with "message passing".  The source code was cut-and-pasted from the Wikipedia article on Objective-C, and therefore is under the GNU Free Documentation License (FDL).  What that says about reusability of the code, I can't begin to say!
sample_Objective-C
Linux
sample_Objective-C-2.exe
Windows
Objective-C
An alternate "Hello, world!" program in Objective-C.
sample_Objective-C-2
Linux
sample_Objective-C-2_macosx_fat
Mac OS X
sample_pthreads_dynamic.exe
Windows

C
Runs main plus two threads.  The main program prints a message once per second for 30 seconds, while thread #1 prints a message once per second for 10 seconds and thread #2 prints a message once per second for 20 seconds.  Note that in Windows, pthreadGC2.dll must be used with the "dynamic" version of the sample program.
sample_pthreads.exe
sample_pthreads Linux
sample_pthreads_macosx_fat
Mac OS X
sample_RegularExpressions Windows
C
A super-simplified grep, that lists all of the lines in an input file which contain a specified regular expression.  Use the "--help" switch for usage info.
sample_RegularExpressions Linux
sample_RegularExpressions_macosx_fat
Mac OS X
sample_wxWidgets-2.8.exe Windows
C++
Demos various stuff you can do with the wxWidgets wxTextCtrl class.  If you run it, its usage will be self-explanatory.  I didn't write it; I just copied it directly from the samples/text directory of the wxWidgets-2.8.7 source tree.  Consult the wxWidgets licensing info if you want to mod it.

Deploy to Mac OS X by copying the tarball onto the desktop.  When the user double-clicks it, an icon for the application will appear on the desktop.
sample_wxWidgets Linux
IMCROSS-wxWidgets.app.tar.gz
Mac OS X
sample_zlib.exe Windows
C
Decompresses or tests the integrity of a file compressed with gzip, just like gunzip or 'gzip -d', but without all the fancy options.  This is a sample program from the zlib source tree, although I had to make a couple of trivial modifications to get it to compile and run on Windows.  These changes are noted within the comments of the source file.  As usual, check the licensing within the sample file if you want to reuse the code.

It turns out that the sample program apparently uses a feature of zlib that was only introduced at zlib 1.2.3.  I don't know when zlib 1.2.3 began to be used on Mac OS X, but I do know that it was not yet in use for Mac OS X 10.2.8, and therefore the sample program will not run on Mac OS X 10.2.8 or prior.
sample_zlib Linux
sample_zlib_macosx_fat
Mac OS X
sample_allegro_dynamic.exe Windows

C
A simple shoot-em-up game, complete with graphics and audio.  This was copied right out of the Allegro source tree.  The license is "gift-ware", so I don't suppose thare are any restrictions on it, but as always you should verify it for yourself rather than relying on my judgement. 

In Windows, if you want to run this sample program, make sure you add the files demo.dat and readme.txt (from the Samples/allegro directory) to the directory containing the executable.  Since the Allegro library is provided in both static and DLL forms by IMCROSS in Windows, both statically-linked and DLL-based forms of the sample program are provided as well.

In Mac OS X, deploy by copying the tarball onto the desktop.  When the user double-clicks it, an icon for the application will appear on the desktop.  This sample program is unique among the various GUI-based sample programs, in that it is the only one which will run on Mac OS X versions as early as 10.2.
sample_allegro.exe
sample_allegro Linux
IMCROSS-allegro.app.tar.gz
Mac OS X
sample_fltk.exe
Windows
C++
A Mandelbrot fractal viewer.  (Hint:  right-click the mouse at various points in the graphic.)  I copied this program from the FLTK source tree.  Note that in Windows the threaded FLTK applications require distribution of the pthreads-w32 file "pthreadGC2.dll", but this particular sample program is not threaded and doesn't need it.

On the Windows architecture, there is another cross-compiled FLTK based program that might be of some interest.  Though not an IMCROSS sample program as such (because it doesn't obviously illustrate the methods used for cross-compilation), you'll find a utility called fluid.exe, which is a cross-compiled version of the fluid rapid-application development program distributed with FLTK.  I don't think there's much need for it, since the native Linux version of fluid is what you'll want to use, but it's still mildly interesting.  I don't cross-compile fluid in Mac OS X.

Deploy to Mac OS X by copying the tarball onto the desktop.  When the user double-clicks it, an icon for the application will appear on the desktop.
sample_fltk
Linux
IMCROSS-fltk.app.tar.gz
Mac OS X
sample_readline.exe
Windows
C
This is a simple command-line program that accepts commands you type in, and then displays them after you type them it.  However, it provides all of the editing and history features of readline, such as scrolling forward and backward through the command history, or searching the command history.
sample_readline
Linux
sample_readline_macosx_fat
Mac OS X

I suppose I should make it clear that I don't necessarily know the optimum or approved compiler/linker command-line switches for cross-compiling these Windows-targeted and Mac OS X targeted programs, but I've tried to make the build-instructions for the sample programs as close to the library developers' expectations as I could.

Here is a list of sample programs for the "contributed" libraries:

Sample Program
Target System
Language
Description
Contributed/Qt/sample_Qt.exe
Windows
C++
Trolltech Qt 4.

The sample program is one of the example programs from the Qt 4.4 source tree.  It is a trivial wizard (in fact, it's called "trivialwizard") which purports to collect registration info from you ... but doesn't really send any information to me!  Note that the Windows version of the sample program requires QtCore4.dll, QtGui4.dll, and libpng13.dll at runtime.

It may or may not be worth noting that this is not the first Qt example program I tried.  The first, "portedasteroids", is apparently a game similar to our Allegro sample program.  It cross-compiled without error, but I couldn't get it to run in Windows.  On the other hand, I couldn't even get it to compile natively in Linux, so I don't necessarily claim that it was IMCROSS's fault.
Contributed/Qt/sample_Qt Linux
n/a
Mac OS X (future)
(none)
n/a
n/a
GNOME Structured File library (libgsf).
In Contributed/SDL:
sample_SDL_checkkeys[.exe][_macosx_fat]
sample_SDL_graywin[.exe][_macosx_fat]
sample_SDL_loopwave[.exe][_macosx_fat]
sample_SDL_testalpha[.exe][_macosx_fat]
sample_SDL_testbitmap[.exe][_macosx_fat]
sample_SDL_testblitspeed[.exe][_macosx_fat]
sample_SDL_testcdrom[.exe][_macosx_fat]
sample_SDL_testcursor[.exe][_macosx_fat]
sample_SDL_testdyngl[.exe][_macosx_fat]
sample_SDL_testerror[.exe][_macosx_fat]
sample_SDL_testfile[.exe][_macosx_fat]
sample_SDL_testgamma[.exe][_macosx_fat]
sample_SDL_testgl[.exe][_macosx_fat]
sample_SDL_testhread[.exe][_macosx_fat]
sample_SDL_testiconv[.exe][_macosx_fat]
sample_SDL_testjoystick[.exe][_macosx_fat]
sample_SDL_testkeys[.exe][_macosx_fat]
sample_SDL_testloadso[.exe][_macosx_fat]
sample_SDL_testlock[.exe][_macosx_fat]
sample_SDL_testoverlay2[.exe][_macosx_fat]
sample_SDL_testoverlay[.exe][_macosx_fat]
sample_SDL_testpalette[.exe][_macosx_fat]
sample_SDL_testplatform[.exe][_macosx_fat]
sample_SDL_testsem[.exe][_macosx_fat]
sample_SDL_testsprite[.exe][_macosx_fat]
sample_SDL_testtimer[.exe][_macosx_fat]
sample_SDL_testver[.exe][_macosx_fat]
sample_SDL_testvidinfo[.exe][_macosx_fat]
sample_SDL_testwin[.exe][_macosx_fat]
sample_SDL_testwm[.exe][_macosx_fat]
sample_SDL_threadwin[.exe][_macosx_fat]
sample_SDL_torturethread[.exe][_macosx_fat]
Linux (no suffix)
Windows [.exe]
Mac OS X [_macosx_fat]
C
The Simple Directmedia Layer (SDL) library. 

The sample programs are simply all of the test programs in the SDL source tree.  I can't give you an exhaustive explanation of what they do.
Contributed/old/sample_old.exe
Windows
C
Alberto Bertogli's Open Lock Daemon (OLD) is a Linux-based program that acts as a "lock server":  clients elsewhere on the network request "locks" (which are abstract and are not associated with any specific file or other object) and the lock server grants or denies those locks.  This can be used to allow a distributed set of clients to behave cooperatively in terms of resources, if they respect the locking mechanism.  Although the server runs only on Linux or perhaps other *NIX systems, the clients can run on other platforms, and there is a library, libold, that the clients use to access the lock server.

The sample program is a test program copied from the libold source tree.  It is a client program that simply gets a given number of locks (chosen from the command line) from a given running lock server (also chosen from the command line), and then terminates.  It was originally conceived as a speed test for the lock server.  In addition to demonstrating the libold library, it also verifies at the same time that socket operations work correctly.
Contributed/old/sample_old
Linux
Contributed/old/sample_old_macosx_fat
Mac OS X

Testing the IMCROSS Installation

Summary of Known Test Results

Test results obtained by users, resulting from the test strategy and procedures outlined within the remainder of this section, are collected here for your viewing pleasure, except when requested otherwise.  Steven Holloway (thanks Steven!) has provided an impressive collection of test reports on several key system types to which I don't have access.  Here is how I'd summarize the formal data so far:
Since this version of IMCROSS auto-detects installed native libraries and tailors the default builds to what's installed, not all libraries or tools were built on every build-platform tested.  The table below shows what we actually attempted to build in the tests quoted in the release notes above.
Distro. on
build-machine
gcc
Bits
Real
vs.
Virtual
Machine
Fortran
Objective
C
Mac
OS
X
libxml2
GTK+
wxWidgets
FLTK
Allegro
Fedora Core 1
3.3.2
32
Virtual
Yes Yes
Yes (failed)
No
Yes
Yes
No
Yes
OpenSUSE 10.1
4.1.0
32
Virtual
No
No
No
Yes
Yes No
No
Yes
Fedora Core 5
4.1.1
32
Real
Yes Yes Yes Yes Yes Yes Yes Yes
Fedora Core 6
4.1.2
32
Virtual
Yes No
No
Yes No Yes No
Yes
Fedora 7
4.1.2
32
Virtual
Yes Yes Yes Yes Yes No
No
Yes
Fedora 8
4.1.2
32
Virtual
Yes Yes Yes Yes Yes Yes
Yes
Yes
(K)ubuntu 7.04
4.1.2
32
Virtual
No
No
No
Yes
No
No
No
Yes
OpenSUSE 10.3
4.2.1
32
Virtual
Yes
Yes
Yes
Yes
Yes Yes
Yes
Yes
(K)ubuntu 8.04
4.2.4
32
Virtual
Yes Yes Yes Yes Yes Yes Yes Yes
Ubuntu 8.04
4.2.4
64
Real
Yes Yes Yes (failed)
Yes Yes Yes Yes Yes
Fedora 9
4.3.0
32
Virtual
Yes Yes
Yes (failed)
Yes
Yes Yes Yes
Yes
Fedora 10
4.3.2
32
Virtual
Yes
Yes
Yes (failed) Yes Yes Yes Yes Yes
OpenSUSE 11.1
4.3.2
32
Virtual
Yes Yes Yes (failed)
Yes Yes Yes Yes Yes
Ubuntu 8.10
4.3.2
32
Virtual
No
Yes
Yes (failed)
No
No
No
No
No
Distro. on
build-machine
gcc
Bits
Real
vs.
Virtual
Machine
Fortran
Objective
C
Mac
OS
X
libxml2
GTK+
wxWidgets
FLTK
Allegro
(K)ubuntu 8.04
4.2.4
32
Virtual
No Yes Yes Yes Yes Yes Yes Yes
Ubuntu 8.04
4.2.4
64
Real
No
Yes Yes
Yes Yes Yes Yes Yes

Strategy for Testing

There are four interesting questions that arise with respect to the validity of using IMCROSS to cross-compile applications for Windows and Mac OS X:
  1. Does your local installation of IMCROSS conform to the master IMCROSS installation (mine)?
  2. Do the cross-compiler toolchains installed by IMCROSS work properly?
  3. Do the cross-compiled libraries installed by IMCROSS work properly?
  4. Do the installation programs or packages created by IMCROSS work properly?
Some of these objectives are easy to verify, and others are not.  Because I would like IMCROSS to be tested as thoroughly and as objectively as possible, some aids have been added to IMCROSS that assist in this goal.  Test aids and procedures are covered in the next 3 subsections.

At present, these considerations apply only to "core" IMCROSS tools and libraries.  "Contributed" libraries are not presently covered, though these ideas may be extended to them in the future.

Validation:  I. Regression testing of build-processes

(The tests described in this section are known not to work very well, presumably because of compile-time information such as locales or timestamps that change from build-to-build.  But the concept is interesting anyhow.)

One advantage of using a cross-compiler system like IMCROSS is that we can have some expectation that the cross-compiled binaries should be byte-for-byte identical, whether produced on an ancient Fedora system or the most up-to-date Ubuntu.  Therefore, we should be able to check the validity of your installation of IMCROSS as compared to mine by checking to see if the sample binaries it produces are the same. 

In IMCROSS this is handled as follows:
When 'make samples' is run, a report from the regression test is made, called "regression_report.log".  If you want to email me this report—particularly if there are failures—it might be useful feedback.  Let me warn you that the report does contain information about your machine, such as what version of Linux you're running, your CPU type and memory, version of gcc, and so on, so if you're terribly concerned about your privacy then don't send me the report.  (Here is a sample report, in case you're interested.)

Admittedly, this can be expected to work only up to a certain point.  For example, if the compiler constant __DATE__ was used by any of sample programs, then the build-date of the sample program would be embedded in its executable, and so the comparison would fail.  Fortunately, none of the sample programs actually does use __DATE__.  On the other hand, the compiler itself might do something like this, or might embed some other localization or serialization info.  Indeed, if were to compare the executables prepared by i386-mingw32-gcc, you'd find that even when the source code and compiler have not changed, the executables from compile to compile always differ at binary offsets 0x88-0x8B and 0xD8-0xDB.  Executables prepared by powerpc-apple-darwin9-gcc have no such feature.  I unashamedly zero out these fields when the MD5SUMs are created, on the assumption that they are timestamps inserted by the compiler or linker.

There is also a problem with the Objective-C sample programs, in that they seem to contain other data that varies with every compile, but which isn't predictable enough for me to filter out.  Perhaps this is something to do with serialization of objects.  At any rate, whatever it is, it prevents the Objective-C programs from being validated in this way.

Validation:  II.  Regression testing of cross-compiled command-line programs

The behaviors of all of the command-line sample programs created by IMCROSS 'make samples' can be verified in an automated way, since they accept input (either from files or from the keyboard) and produce predictable output.  Here are the steps to performing such a test
  1. Obtain the regression test packages.   There are two possible methods:
    1. Download them.  This is the approach you should take if you should take if you merely want to help us in testing, rather than installing and using IMCROSS yourself.   Because of resource limitations, only the packages for the latest IMCROSS snapshot are available at any given time.
    2. Or build them.  The command is "make clean samples create_regression_data".  What this does is to build all of the sample programs, then run all of the native Linux versions of the sample programs to collect their data signatures, then create an archive containg the data signatures, the cross-compiled sample programs, and a script to be run on the target machine.  There are two archives created:  RegressionTests-windows.zip and RegressionTests-macosx.tar.gz.
  2. Put the regression test packages onto the target machines:  Copy either RegressionTests-windows.zip or RegressionTests-macosx.tar.gz, whichever is appropriate, onto the machine on which testing is going to be performed.  Unzip the package using the appropriate tools.  Usually, the most straightforward way to do this is to put them on the desktop and then to double-click them.
  3. Run the tests:  From a command line, descend into the RegressionTests directory just now created.  Run the test either as "CheckRegressionData" (Windows) or "./CheckRegressionData.h" (Mac OS X).  The test takes a minute or so to run.
If you pipe the report into a file and email it to me—particularly if there are failures—it might be useful feedback.  Let me warn you that the report does contain information about your machine, such as what version of Mac OS or Windows you're running, so if you're terribly concerned about your privacy then don't send me the report.  (Here are a sample Windows report and a sample Mac OS X report, in case you're interested.  You'll notice that each shows one test failure.  For Windows, the test failure is in Fortran, and has to do with the formatting of the data; the failure isn't terribly surprising, since the Fortran cross-compiler for Windows was Fortran 77, while the native Linux compiler was Fortran 95.  For Mac OS X, the failure was that the Objective-C-2 sample program could not be executed; this was expected since the Mac OS X version is shown as 10.2.8, which is very out-of-date.)

Validation:  III.  Testing of cross-compiled GUI programs and installers

All of the materials needed to run and/or install the GUI-based sample programs (other than gtk+-based programs) are included in the RegressionTests-windows.zip and RegressionTests-macosx.tar.gz files described in the preceding section, so if you have done the command-line regression tests in the previous section, you're already prepared to start looking at the GUI tests.

While the tests in the preceding two sections were automated, there is no automated way to test GUI programs or their installers.  All you can do is to run them and see if they "act right".  So the subsections below give you some basic things to look at if you want to do that.

Sample readline program

Instructions TBD.

Sample wxWidgets Program on Windows

For Windows, I've created no installation program for this sample program.  You can run the program from a command line simply by cd'ing into the RegressionTests directory and running sample_wxWidgets-2.8.exe, or else by locating it with a graphical file manager such as "My Computer" and double-clicking it. 

In either case, a window something like the following (click to enlarge) should appear:



The instructions in the program window, particularly in the right-hand pane, say it all.  What I normally do is to click the mouse on the right-hand pane to give it focus, scroll upward to make sure that the top of the text is visible, and then hit ctrl-R a few times.  (Hitting ctrl-R deletes the characters at positions 4-8 on the first row by "ABC"; the very first time you do it, "Allows more..." becomes "AllABCore...".)

Sample GTK+ Program and Installer on Windows

I don't provide the GTK+ sample application for direct download simply because the need to include the dynamic libraries in the Windows installer makes the installer so big.  So you will have to build the installer locally using IMCROSS if you want to try it.

Having built the installer, you then need to install the sample program.  In Windows, you can run the installer (sample_gtk_installer.exe) from a command line or else by locating it with a graphical file manager such as "My Computer" and double-clicking it.  

In either case, you can run the sample application itself by double-clicking the IMCROSS-logo icon which has been added to the desktop.  A window containing 3×3 array of buttons will pop up:



As you can see from the  logo, I actually took this screenshot from a Linux box, and the appearance is slightly different in Windows.  For example, a GTK logo appears instead.  When you run it in Windows, a console window may also pop up.  At any rate, if you click the mouse on the buttons, then they become depressed:



After you have clicked enough buttons, you'll eventually have 3 in a row, horizontally, vertically, or diagonally.  At that point, a congratulatory message appears in the terminal window ("Yay!") and the buttons return to their original undepressed states.

Sample FLTK Program on Windows

Since I've created no installation program for this sample program, you can run it  from a command line simply by cd'ing into the RegressionTests directory and running sample_fltk.exe, or else by locating it with a graphical file manager such as "My Computer" and double-clicking it.  A window something like the following (click to enlarge) should appear:



If you move the cursor anywhere on the image and right-click the mouse, a 2nd window will pop up with another image.  While the fractal in the window above always looks just like what's shown, the image in the new window will differ depending on the position of the mouse cursor, and so it may not be exactly as shown:


Sample Allegro Program on Windows

Since I've created no installation program for this sample program, you can run it  from a command line simply by cd'ing into the RegressionTests directory and running sample_allegro.exe or sample_allegro_dynamic.exe, or else by locating one or the other of these with a graphical file manager such as "My Computer" and double-clicking it.  (Since there are two versions, both should be tested.)  You should see a splash-screen (with music!) something like the following



that goes by quite quickly, followed by a couple of configuration screens in which you can just accept the defaults:




Then there will be a welcome screen, complete with a voice message, a moving star field in the background, and scrolling message at the bottom of the window (click to enlarge):



You can proceed to the actual game by hitting the space bar.  There will be a sequence of transitional screens, which go by too quickly for me to capture, followed by the game screen (click to enlarge):



Within the game, rotating asteroids float into the frame, and you can shoot (space key) or move your spaceship to the right or left (with the right/left arrow keys).  You want to avoid being hit by the asteroids, because that destroys the ship and you have only 3 lives.  All of this stuff (shooting, destroying, being destroyed) is accompanied by sound effects.

Sample wxWidgets Program and Installer on Mac OS X

First, install the sample program:
  1. Copy IMCROSS-wxWidgets.app.tar.gz  from the RegressionTests folder onto the desktop.
  2. Double-click it to cause stuffit to install the application.  An icon for "IMCROSS-wxWidgets" should appear, with an icon similar to the logo at the upper right of this web page.
When you run the program, a window will appear that's similar to the one shown above under the heading "Sample wxWidgets Program on Windows", and the test instructions given there more-or-less apply.  (I apologize, but I haven't an appropriate Mac box at hand right now to get a "real" screen shot for it or to really test these instructions.)  There will, however, be some differences due to the macification that wxWidgets has done.  For example, the menu bar will be at the top of the screen as you'd expect, rather than attached to the application window as shown in the screen shot.  Also, alt-R  is used in place of ctrl-R, as is apparently typical in Mac OS X keyboard shortcuts.

Sample GTK+ Program and Installer on Mac OS X

I don't provide the GTK+ sample application for direct download simply because the need to include the dynamic libraries in the Mac application bundle makes the app bundle so big.  So you will have to build it locally using IMCROSS if you want to try it.

Having built the app bundle, you then need to install the sample program.  The easiest way to install the application bundle is to place it (IMCROSS-gtk.app.tar.gz) on the desktop and then double-click it to unpack it.  You can then run the program itself by double-clicking its desktop icon.  The behavior will be as described above for the Windows version of the sample program.

Sample FLTK Program and Installer on Mac OS X

First, install the sample program:
  1. Copy IMCROSS-fltk.app.tar.gz  from the RegressionTests folder onto the desktop.
  2. Double-click it to cause stuffit to install the application.  An icon for "IMCROSS-fltk" should appear, with an icon similar to the logo at the upper right of this web page.
The window that pops up and the behavior of the program will be identical to what's described above under the heading "Sample FLTK Program on Windows".

Sample Allegro Program and Installer on Mac OS X

Note that this sample program can be run in Mac OS X 10.2.8, and possibly in earlier versions, and thus can be tried out even if a relatively up-to-date Mac OS X box is not available.

First, install the sample program:
  1. Copy IMCROSS-allegro.app.tar.gz  from the RegressionTests folder onto the desktop.
  2. Double-click it to cause stuffit to install the application.  An icon for "IMCROSS-allegro" should appear, with an icon similar to the logo at the upper right of this web page.
The window that pops up and the behavior of the program will be identical to what's described above under the heading "Sample Allegro Program on Windows".

Deployment of Cross-Compiled Applications:  I. Simple Deployment

Windows

For programs not based on GTK+ or on the pthreads-w32 DLL, all you have to do is to distribute the EXE files you create (and any auxiliary files specific to your project, of course). 

For GTK+ programs, you additionally need to distribute the DLLs.  Rather than trying to figure out which DLLs are needed, I'd suggest just distributing all of the DLLs.  (That's a technical opinion, not a legal one.  Legally, you have to obey the licensing provisions of the individual libraries.)  The DLLs can go wherever DLLs go in Windows; putting them in the same directory as the EXE files seems to work.

Statically-linked pthreads-w32 based programs are stand-alone, but dynamically linked ones require distribution of the file pthreadGC2.dll.  This statement applies also to FLTK based programs that use threading, since FLTK threading is based on POSIX threads.

Mac OS X

For simple console programs, where compatible system libraries exist on the target computer as on the build computer (which presently targets Mac OS X 10.4), deployment seems to be just a matter of copying the executable.  Empirically, all of the sample programs that are console-based can be deployed in this manner, and work correctly when run on Mac OS X 10.4.

GUI-based programs generally don't work using this method.  Instead, the proper deployment method for a GUI-based program is to create an application bundle, which is a topic covered later.  Moreover, for applications based on libraries like GTK+ that are provided only for dynamic linking, you'll need to distribute the application code along with the appropriate .dylib files rather than just the application code itself.

Running a simple console program on a version of Mac OS X earlier than 10.4 may or may not be possible, regardless of the deployment method, because the necessary system libraries may not be present or may be too old.  It may be possible to install or update system libraries on the target system to overcome this problem, an observation that's not useful for deployment to end users but may be useful to developers working with an out-of-date Mac OS X on their test systems.  For example, I have found with Mac OS X 10.2.8 that updating the zlib, libiconv, and libxml2 system libraries allows many of the sample programs to run that would not otherwise do so.  Such updates can be performed by using the same source-code tarballs for these libraries that IMCROSS has already downloaded for you.  On your Mac OS X target system, simply unpack the tarballs, do "configure --prefix=/usr --enable-shared", "make", and "sudo make install".  On the other hand, some of the sample programs can never work on earlier Mac OS X systems because they require updates to system libraries like libstdc++ or libgcc, which as far as I can tell is impossible.

Deployment of Cross-Compiled Applications:  II. Creating an Installation Program for Windows (setup.exe) or Linux

Alternately, you may want to build an installation program, such as setup.exe for Windows.  While it is not so critical to have an installation program for Linux-based software, there's no doubt that it would be nice to be able to build one for Linux as well.

To address this issue, IMCROSS installs InstallJammer, which is a program that can be used to construct such installer programs.  (If you don't want InstallJammer itself installed, you can use a custom IMCROSS configuration to eliminate it and ignore the rest of this section.)  While the particular installation-builder program used isn't really critical for the purposes of IMCROSS, InstallJammer nevertheless has a number of very convenient features that make it attractive:
So the idea is this:
  1. You run the InstallJammer GUI to create a Windows (and/or Linux) installation configuration for your application code.  This creates an InstallJammer project file (*.mpi) containing all of the configuration information.
  2. You insert the appropriate commands in your application program's Makefile that will cause the command-line version of InstallJammer to build your installer using the project file and your executable (and other) files.  (Probably you also need the Makefile to perform routine transformations of the InstallJammer project file, such as altering the directories used or the version codes.  Since the project file is a text file, this can be done with sed or awk scripts.)
  3. Deploy the installation program to your users.
I've added the appropriate steps and other explanatory material to the sample_gtk_installer.exe target in the IMCROSS Makefile.samples, so please read the notes there to see how to proceed for yourself.

One thing you'd probably like to have is a Windows-type .ico file so that you can associate a nice image with the Windows destop icon for your application.  The easiest method I've found for creating the .ico file is to use the free web service iconvert, where you just upload an image such as a .png or .jpg file and get the .ico file in return.  It will also make Mac .icns files at the same time, so it's really convenient.

Deployment of Cross-Compiled Applications:  III. Mac OS X Application Bundles

Skeleton of a simple application bundle

The bad news is that even if you have a valid executable for a perfectly fine and error-free GUI program, it still may not execute on the Mac without having to add some extra goo first.  The good news is that adding that extra goo isn't too difficult and essentially eliminates the need for an installer program.

The correct way to deploy a Mac OS X application is to embed it within an application  bundle.   An application bundle is a directory hierarchy containing the executable, information about the executable, other files needed by the executable, and so forth.  The bundle is then typically archived as a single .dmg file for distribution to users.  Fortunately, since as far as I know there is no readily-available open-source way to create .dmg files on Linux, the bundle can also be distributed as a tarball.  When the user double-clicks a tarball that's on his Desktop, it is expanded by stuffit, and then is recognized by Mac OS X as an application bundle because of the nature of the contents.  Furthermore, this is an installation mechanism that Mac users are familiar with.

Among the IMCROSS sample programs, I provide application bundles for all programs having GUIs.  The method I use is very simple: There is a template application bundle sub-directory in the IMCROSS/Samples directory, and the only thing that has to be done at build time is to slightly customize that template and create a tarball, all of which is done by Makefile.samples.

One point which may be confusing to non-Mac people (such as myself) is that it may appear from the description I'm giving of application bundles that Mac OS X treats the application bundle itself as the application, rather than the executable.  So it may appear (for example) that the trick of using an application bundle might make an application usable from the Mac OS X desktop but that the application still wouldn't be accessible from a command line, since an application bundle is just a directory in the file-system rather than an executable file.  But no ... it is a curious fact that once it is inside of an application bundle directory structure, the executable for a GUI application can be executed from the command-line perfectly, whereas if it is removed from the application bundle it probably cannot be.  This means that you can still use mechanisms such as shell scripts or shelling out from other programs to execute programs and to pass them command-line parameters, as long as those executables appear within an application bundle's directory structure.

Let me stress at the outset that there is no complete Linux solution for creating application bundles.  While simple application bundles can be created from Linux, more complex ones require the use of the Apple-provided development tools SetFile and Rez.  These tools are included in the free download of Xcode from Apple, but they only run on Mac OS X:
With that said, we need to learn how to create application bundles to the extent that it's possible for us to do so.  Application bundles are created automatically when developers work with Xcode on Mac OS X, but obviously that's of little help to us on Linux, so application-bundle creation must instead be done within the makefile (or whatever) used to build the application code or the installer for the application code.  As far as I can see, the simplest possible application bundle looks like this:

Application.app/
Contents/
Info.plist
MacOS/
Application
Resources/
Application.icns
... data files needed by the executable ...

Skeleton of a simple Info.plist

Info.plist is an XML file that provides information about Application, and as far as I can tell the simplest possible Info.plist file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CFBundleExecutableFile</key>
    <string>Application</string>
    <key>CFBundleName</key>
    <string>ApplicationName</string>
    <key>CFBundleIdentifier</key>
    <string>ApplicationUTI</string>
    <key>CFBundleIconFile</key>
    <string>Application.icns</string>
  </dict>
</plist>

ApplicationName is what's displayed in menu bars.  Apparently, Application is what's displayed with the desktop icon.

ApplicationUTI is a Uniform Type Identifier for your application.  What you use is up to you, I guess, as long as it obeys the "reverse-DNS syntax".  For example, for all of the IMCROSS sample programs for which I choose to create application bundles, I use a UTI of "org.sandroid.imcross.sample".

Application.icns is a file that contains an image of the icon for the application.  One thing you'd probably like to have is a Mac-type .icns file so that you can associate a nice image with the Mac desktop icon for your application.  The easiest method I've found for creating the .icns file is to use the free web service iconvert, where you just upload an image such as a .png or .jpg file and get the .icns file in return.  It will also make a Windows .ico file at the same time, so it's really convenient.

But there are some other methods as well.  I haven't found any way to produce such a file in Linux.  (Gimp doesn't do it.  ImageMagick claims to do it, but when I get such a file onto the Mac, it is an invalid file.) The way I created the icons for the sample programs was to make a 128×128 JPEG, and then to use the Mac developer utility called IconComposer to turn it into an icns file.  I don't know if this is still a currently-available program.  I have also successfully used a program called Img2Icns for this purpose; this is a commercial program so I normally wouldn't recommend it for open-source applications, but they will give you a feature-limited free version that was certainly adequate for my purposes; it also had the advantage of accepting an arbitrary-size JPEG.

Necessary modifications to source code

Once you get over the disappointment of finding out that you need to create application bundles at all, you may realize that application bundles are a very convenient way to distribute software because of the fact that they are self-contained: if there are icons, they're in the application bundle; if there are libraries, they're in the application bundle; if there are data files, they're in the application bundle; etc.  Therefore, in many cases there is no "installation" as such of an application, since once the application bundle is in place there is nothing more to do.  Nor is an "uninstall" program needed.  Nor are extended permissions needed to install or to run the application.

Nevertheless, the fact that all supplemental files are included within the application bundle probably means that any assumptions you've made in the Linux or Windows versions of the application as to the paths of such supplemental files are probably wrong.  To "play nice" with the application-bundle method, such supplemental files are generally placed in the "Resources" folder of the application bundle.  That means that your source code must be modified in a way that allows it to locate the Resources folder.  The following code snippet can be adapted to your source code to accomplish this:

#ifdef __APPLE__
#include <CoreFoundation/CFURL.h>
#endif
.
.
.
  // Suppose, for example, that you wanted PathToMyResource to
  // contain the pathname to the directory where your supplemental
  // files are stored.
 
char PathToMyResources[256] = "/Path/On/Linux/Or/Windows";
#ifdef __APPLE__
  // We'll make pathPtr point to the application bundle itself.
  const char *pathPtr;
  pathPtr = CFStringGetCStringPtr (CFURLCopyFileSystemPath (CFBundleCopyBundleURL (CFBundleGetMainBundle()),
                                                            kCFURLPOSIXPathStyle),
                                   CFStringGetSystemEncoding());
  sprintf (PathToMyResources, "%s/Contents/Resources", pathPtr);
#endif

Alternate Versions of Cross-Compiled Libraries

You can install alternate versions of libraries by creating a custom IMCROSS configuration, as long as the alternate versions are available from the same ftp site or website as the default versions.  (Of course, I don't vouch for compatibility amongst the different libraries if you do so.)  In general, only the last version of library which you installed will be available for your use in cross-compiling.  In other words, every time you install a new version of a library, it overwrites previously-installed versions.  (But see the next section.)

As an example, suppose you wanted to install PCRE version 7.1 rather than the version IMCROSS installs by default.  In Makefile.override-settings or Makefile.custom-settings, you'd replace the existing line "PCRE_VERSION=7.6" with "PCRE_VERSION=7.1".

Some libraries (such as wxWidgets) are affected by multiple such variables that work together to define the full version code.

Multiple Simultaneous Alternate Versions of Cross-Compiled wxWidgets

wxWidgets is a very useful programming framework, but it suffers from the tendency its developers have to break the API at each release.  For example, wxWidgets 2.8 has incompatibilities with 2.6 that cause programs written for one of them to be unbuildable on the other without source-code changes.  Similarly, 2.6 is incompatible with 2.4, 2.4 is incompatible with 2.2, and so on.  Usually, fixing such problems is not difficult, but it is very frustrating.  If you've written a program for a different version of wxWidgets than IMCROSS installs by default, you may not wish to drop everything to fix those problems, and may wish to continue using a previous version.  It's also a great disinclination to distribute wxWidgets applications as source code.

On the other hand, wxWidgets conveniently differs from the other libraries IMCROSS installs, in that multiple versions of it can be installed, and you can select the version you want to use at application compile-time.  Or at least, you can have multiple releases 2.x installed, but you couldn't have multiple point releases like 2.8.x installed.

The previous section ("Alternate Versions of Libraries") describes the basic technique of installation of an alternate version.  If, for example, you wished to install wxWidgets 2.6.3, in your custom IMCROSS configuration you'd put "WXVER=2.6" and "WXMINOR=3", and then do 'make' to rebuild IMCROSS.  If you did so and then afterward invoked the command '...installation-directory.../bin/wx-config --list', you'd see messages like the following:

    Default config is msw-ansi-release-static-2.6

  Default config will be used for output

  Alternate matches:
    msw-ansi-release-static-2.8

As the messages indicate, the default version (which has now changed to 2.6) will be used when you compile without making any further provision.  However, you can use an alternate version by altering the invocation of "wx-config" used when compiling your application.  For example, to explicitly choose to use version 2.8 instead of the default, you'd add the switch "--version=2.8" to the "wx-config" invocation.  There's some trickery in Makefile.samples illustrating this.

The last version of wxWidgets installed always seems to be the default version chosen by wx-config.  Unfortunately, I don't know a satisfying way to change the default, but one way to do it is this:  If you look in the installation directory, you'll notice that 'wx-config' is actually just a link to another file such as 'wxrc-2.8' or 'wxrc-2.6'.  That link determines the default, and all of the other 'wxrc-X.X' files that aren't linked are what can be chosen using wx-config's "--version" switch.   So if you change the link you'll change the default version of wxWidgets used.

wxWidgets is versioned so that stable releases have version numbers of the form 2.n, where n is an even number, whereas development versions have n odd.  I don't claim to have tried every version, but here are some notes on the versions I have taken the trouble to download:

wxWidgets release
Point version
Works with IMCROSS—at least for Win32?
2.8
2.8.9
Yes.  (This is the current IMCROSS default, and currently the latest release in the 2.8 series.)
2.8.7
Yes.
2.6
2.6.4
Yes.  (This is the final point release in the 2.6 series.)
2.6.3
Yes
2.6.2
Yes.
2.4
2.4.2
No, fails to configure.  (It can probably be made to work, but I haven't figured out the secret maneuvers to do so.)
2.4.1
Same as above.
2.3
2.3.4
Same as above.

Cloning an IMCROSS installation

If you need more than one developer-workstation running the same toolchain, it is convenient to be able to clone the binaries of an existing IMCROSS installation, as opposed to going through the lengthy process of running the IMCROSS makefile on each workstation.  With IMCROSS snapshot 20080521 or later, it is possible to do this in some cases, but not in others, with the determining factor being the degree of similarity of the workstations. 

One drawback is that the cross-compilers won't work on the cloned system if the tarball is unpacked into a directory with a different name; for example, if the installation directory was originally /home/auser/IMCROSS on the build-machine and you later cloned it at /home/buser/IMCROSS on a different machine, it would not work.  You could work around this by unpacking the IMCROSS binaries wherever you like, and then adding a symbolic link at the original build location (e.g., "ln --symbolic /home/buser/IMCROSS /home/auser/IMCROSS"), but obviously that's a workaround of limited value.

As a test I have just now cloned an IMCROSS installation built on my Fedora Core 5 workstation to Fedora Core 1, Kubuntu 7.04, and Fedora 7 workstations.  This worked on the Kubuntu 7.04 and Fedora 7 workstations—by which I mean that when I built the IMCROSS sample programs they were all byte-for-byte identical with the originals.  But it failed on the Fedora Core 1 workstation—by which I mean that failed system-library dependencies caused the Apple compilers not to run at all, and while the Windows compilers produced sample programs they were not identical to the originals (although for all I know, they could have been functional).  Your mileage may vary.

The technique is simple:  On the orginal IMCROSS build system make a tarball of the binaries, preserving pathnames, and then unpack that tarball on the clone systems and (optionally) adjust the PATH accordingly.  The binary tarball for the 20080521 snapshot  is about 180 MB, which is large but less than half the size of the source downloads that would be needed. Similarly, the installation of the binary tarball may take 5 minutes, but a full IMCROSS build from source may take a couple of hours.  So the tradeoffs are clear.

Note also that if you are interested in building the IMCROSS sample programs to verify operation, you need to have the IMCROSS Makefile(s) and sample programs on the cloned system, including customized settings (Makefile.custom-settings) and/or the USE_HOME environment variable.

For example:
Original build system
export USE_HOME=yes Use ~/IMCROSS as installation directory for the build
cd Where/IMCROSS/Makefile/Is/Stored
make Full build of IMCROSS into ~/IMCROSS
cd ~
tar --bzip2 -cf IMCROSS-binary.tar.bz2 IMCROSS


Cloned machine
cd ~
tar --bzip2 -xf IMCROSS-binary.tar.bz2 Creates ~/IMCROSS directory from binary tarball
export USE_HOME=yes
cd Where/IMCROSS/Makefile/Is/Stored
make clean samples Creates sample programs and regression_report.log

To descend to the surreal for a moment, note that if you did any of this you'd be violating Apple's license.  If prepared as suggested above, the binary tarball would necessarily contain Apple's SDK, which Apple's license does not allow you to distribute to others.  To be consistent with Apple's license, you should omit the SDK from the tarball and force each of the users of the cloned systems to download Xcode and extract the SDK for himself or herself.  Thus, when I tell you that it is possible to make a binary clone of an IMCROSS installation, I mean that it is technologically possible rather than that it is legally possible.


Future possibilities

(From the Making-it-easier-for-Linux-programmers-to-develop-Windows-and-MacOsX-programs department)

Here are some things which come to mind which would help bring the 3 platforms into closer parity.

Framework for user-contributed enhancements

There have been several user-inquiries which imply to my mind that people may be interested in modifying IMCROSS to install their own favorite libraries, and perhaps to contribute that work back to the IMCROSS project.  In other words, there are the "core" IMCROSS libraries which I've provided, and these could be joined by "contributed" libraries that you provide.  Beginning with the 20080513 snapshot, there is now a framework for such contributions. 

My general intention is that only the core IMCROSS tools and libraries should be built in a default IMCROSS installation.  If you have custom IMCROSS settings, on the other hand, you'll need to modify the Makefile.override-settings or Makefile.custom-settings file to control whether such contributions are built or not.  If you don't want the contributions built, add lines like "NO_name=yes" (where "name" is the name of the contribution's sub-directory under IMCROSS/Contributed, such as "NO_MyLib=yes" in the example that follows).  Conversely, if you do want the contribution built, you should remove such lines.   I mention this because some users are clearly distressed at the installation time and resource usage of a full IMCROSS installation, and may envision an endless stream of bandwidth-sucking downloads and disk-draining libraries that aren't explicitly needed by everybody.

To see how to create a contribution, consider the following hierarchy of directories and files:

IMCROSS/
Makefile
Makefile.osx
Makefile.samples
Makefile.common
Makefile.default-settings
Makefile.override-settings
Makefile.custom-settings
Makefile.contribution-template
Samples/
...
temp-cross-compiler-build/
...
Contributed/
...
MyLib/
Makefile.win32
Makefile.macosx
Makefile.samples
MyLib.mpi
Sample/
...
temp-cross-compiler-build/
...
...
...

The build script for each contributed library is placed in its own sub-directory of IMCROSS/Contributed.  There, it mimics the structure of IMCROSS itself, wherein it has makefiles for the Win32 build, for the Mac OS X build, and for the sample-program build.  Moreover, it has subdirectories for storing the sample programs, and for creating temporary files during compilation.   It can participate in the variables (including the custom settings) of the main IMCROSS build, by including the file IMCROSS/Makefile.common.  Moreover, the file IMCROSS/Makefile.contribution-template provides a pretty detailed head-start and explanation on how to create MyLib/Makefile.win32, MyLib/Makefile.macosx, and Mylib/Makefile.samples.

The main IMCROSS makefile automatically includes any subdirectories it finds under Contributed/ when it performs an installation or builds sample programs, so there's no modification needed to the core IMCROSS scripts to begin working on an enhancement.

Of course, the hard part is still up to you, and that's figuring out how to actually compile the libraries on the various platforms and to provide working sample programs for them.  In addition to the makefile-template just mentioned, I've also provided an example in the form of a "contributed" library so that you can see an almost-fully worked-out example.  (I say "almost" because the sample program is a command-line program, so I didn't generate any Windows installer or Mac OS X application bundle for it.)  The library is Alberto Bertogli's Open Lock Daemon (OLD) library, libold.  The library is very small, and that's basically the reason I chose it to demonstrate the framework, but it's useful as well; I use it in one of my own open-source projects, the RTCA DO-178B documentation system program known as Do178Builder.


Some Typical Problems Writing Cross-Platform Programs

I don't mean to imply that the ability to easily install the cross-compiler toolchain and cross-compiled libraries on your Linux development workstation necessarily makes writing cross-platform programs simple or straightforward, but merely that if you have such a cross-platform program it will now be easier to compile and maintain since it can all be done from a single workstation. 

I suppose that most people who are interested in IMCROSS are already used to writing cross-platform programs and/or using cross-platform toolkits, so I'd not presume to offer any advice on cross-platform programming in general to such veterans.  But on the off-chance that there are any newbies to this area, such as Linux developers who are interested in beginning to write cross-platform programs, a few comments on cross-platform programming may be useful.  The remainder of this section is provided for people like that, so if you are already an experienced cross-platform programmer, please ignore it.

RAD for Cross-Platform Toolkits

If you are writing a program from scratch, a useful method of dealing with many of cross-platform problems is to base the program on a cross-platform toolkit such as wxWidgets, GTK+, Allegro, FLTK, Qt, or others, which provide a common API that can be used regardless of the target platform.  If you are working with an existing program that you wish to port to Windows (or from Windows, I suppose), dealing with these problems is much trickier.

There can be a fairly heavy learning curve associated with cross-platform toolkits, and that manual creation of GUIs with these toolkits is not really something the novice wants to do when trying to come up to speed quickly, so using specialized development tools related to the toolkits can be an attractive choice.  These "RAD" or "GUI builder" applications let you use graphical methods to construct the GUI, and then perform enough C or C++ code generation to get a project started very quickly, sometimes in as little as a few minutes.  The tools I'd recommend are the following, though I don't claim to have exhaustive knowledge of all tools that are available:
From a very IMCROSS-centric point of view, since IMCROSS supports wxWidgets and GTK+, using wxGlade and Glade makes a lot of sense.  As a kind of proof-of-concept, I recently used wxGlade and IMCROSS to cobble together a simple GUI front-end for my previously command-line-only open-source project GutenMark.  (I had not previously used wxGlade, though I had briefly used Glade a couple of times before.)  It took about three days to complete the GUI front-end, but considering that users had been grieving for years about the lack of a GUI (as well as the lack of an installer program, which I created at the same time), it was a reasonably efficient use of time.

Windows Cross-Platform Problems

There are a number of Windows incompatibility problems that are encountered on a routine basis, which are typically solved by using conditional compilation based on whether or not the WIN32 symbol is present or not.  Here is a selection of such problems, for your consideration:
#ifdef WIN32
#define NEWLINE "\r\n"
#else
#define NEWLINE "\n"
#endif

to your program, and then instead of using strings like "This is my string\n" use "This is my string" NEWLINE.  Functions like printf already deal with "This is my string\n" properly, and so you don't need a workaround for simple uses like that.

Mac OS X Cross-Platform Problems

In the version of wxWidgets we're currently using, the functions for converting between different character-string types (Unicode, ASCII, "wide-character") are not thread-safe, and your program will crash if you are doing such conversions in multiple threads.  You at present therefore need to confine such manipulations either to a single thread or to protect them with mutexes.  One unobvious way that you might be using multiple threads is if you have an instance of a class which is a global variable and whose constructor does some string manipulations.  The global constructor is not run in the same thread as the main program, so your program may crash instantly at startup.  (This happened in my own GUItenMark program, in which I used a global variable to hold the name of the home directory, and the name of the home directory was fetched by the constructor.)

A specific problem with cross-compiling an application for the Mac is that you cannot use the "-g" command-line switch in gcc to add debugging information.  If you do, at some point the compiler will try to execute the (non-existent) utility dsymutil to bind the debugging information and will (of course) fail to do so.  While irritating, this is not a great limitation, since you couldn't have debugged the Mac executable on Linux anyway, and therefore would have had to fire up a Mac ... and once you had done that, it might be relatively easy to build the debugging version of the application's executable directly on the Mac.  Or it might not, since your makefiles are going to be adapted to the Linux environment rather than to the Mac environment.  I don't know any particular reason why dsymutil couldn't be built as a Linux executable, assuming one had the source code for it, so if anyone knows about such things please let me know.

In more general terms, for the Linux developer, the problems encountered in moving a program to Mac OS X are different in nature than the problems encountered in moving a program to Windows, because there is much more similarity in the APIs for the foundational system libraries between Linux and Mac OS X.  There are still significant differences in the GUI area, so a cross-platform toolkit is still helpful in dealing with these problems.

I would venture that the greatest problem encountered is that while Linux and Windows GUIs are basically similar to each other (except for differences in rendering style), they do not match the Mac OS X GUI paradigm and some Mac OS X users may reject software applications solely on that basis, regardless of the functional value provided by the application.  As a strictly open-source developer, that doesn't bother me much since I'm providing the Mac OS X versions of programs merely as a courtesy.  But a commercial developer doesn't have the luxury of drawing such a conclusion, and needs to make his/her software application conform to the expectations of the users.  In other words, just making your program run on Mac OS X may not be enough if it doesn't act like a Mac program when it does run.

An example of such a paradigm mismatch is in the concept of menu-bars.  In Linux or Windows, the menu-bar for an application appears at the top of the window for that application, and if there are multiple applications open at the same time, there may be multiple menu-bars visible (one at the top of each application window).  In Mac OS X, a single menu-bar is visible, at the very top of the screen, and that is the menu-bar for the application window that happens to presently have focus.  The application windows themselves have no menu-bars, and when a new application window receives focus the menu-bar at the top of the screen is replaced by the menu-bar of the newly-focused application.  So if your program has a menu-bar at the top of its window rather than the top of the screen, a Mac user may instantly conclude that your program is a Windows program rather than a Mac OS X program and refuse to use it.

As someone who admittedly doesn't care whether my software conforms to the Mac OS X paradigm or not, I'm not a good source of advice about such problems.  The example above was actually taken from the wxWidgets wiki article on wxMac issues, and a solution to the problem is presented there if you happen to be using wxWidgets.  (IMCROSS's wxWidgets sample program, which was copied from the wxWidgets source tree, already contains that fix and you can see the fix in action by running the sample program.)  I'd recommend that wiki article (and the wiki articles linked there) as a good read, even if you aren't using wxWidgets.  Problems of integration of application GUIs with the Mac desktop seem to have been given considerable thought in wxWidgets.

As a single positive bit of advice, I'll point out that C/C++ source-code differences for the Mac OS X platform can be accomplished by conditional compilation based on the existence or non-existence of the __APPLE__ symbol.  For example,

#ifdef __APPLE__
#define NEWLINE "\r"
#elif defined (WIN32)
#define NEWLINE "\r\n"
#else
#define NEWLINE "\n"
#endif

Linux Cross-Platform Problems

Since the motivation behind IMCROSS is the desire to develop applications on Linux and then to distribute them easily to Windows and Mac OS X users, it would seem that the Linux version of the application is the last problem you would need to worry about.  In a sense this is true, since your application will undoubtedly run perfectly on Linux and do exactly what you expect it to do, if built from source.  The problem—or at least a problem I've encountered—is distribution of your application to Linux users in binary form.  Ironically, IMCROSS provides you with the capability of statically linking your Windows and Mac OS X executables, or at least (in the case of GTK+ based applications) provides you with a known set of dll/dylib shared libraries that can be distributed without fear, but simply building a Linux binary on a stock Linux box has no such provisions.

In other words, the Linux executables of your applications may be difficult to distribute because they typically will depend on conditions on the build-system which are not duplicated on other Linux users' systems.  Even if you distribute all of the necessary shared libraries, will those libraries even work on the users' systems?  Indeed, can you be sure that you won't break the users' systems?

In my analysis, this problem breaks down into two separate problems:
GTK+ and its associated libraries like glib are the biggest problem.  GTK+ libraries are likely present on almost every Linux computer that would be used to develop cross-platform applications, are always shared rather than static libraries, and indeed are difficult even to build as static libraries.  Replacing them without breaking your workstation would be a terrifying experience for most developers.  Using the competing wxWidgets toolkit does not circumvent the GTK+ problem, since on Linux wxWidgets invariably is based on GTK+, and so even statically-linked Linux wxWidgets based applications almost always need GTK+ shared libraries.  It is possible to build a Linux variant of wxWidgets that depends on X11 libraries rather than GTK+ libraries, but frankly it doesn't work very well and I wouldn't recommend it.

It should be noted that while software such as ELF Statifier exists which "statify" your programs by binding all necessary shared libraries to the executable, my experience with them to date has not been promising.  Your own mileage, of course, may vary.

Various people have written about this problem in a general way, and here are some particularly useful weblinks on the subject I've found:
Now here's my own, purely-pragmatic, IMCROSS-centric take on the problem.  It seems to me that the only feasible approach to solving these problems, unless you're okay with the user always compiling your program from source or with taking the chance of breaking your normal workstation, is to have a dedicated Linux build box, which can be a virtual machine, with specially prepared Linux libraries on which you can build distributable Linux binaries.  It's possible to set up such a machine so that all the access you need is non-interactive, and the only practical downsides are the reduced speed of the build and the resources used.

Here is an approach which has worked for me, on my Virtual Apollo Guidance Computer project (which provides a conglomeration of command-line based, wxWidgets based, and to a lesser extent Allegro based programs).  For this project, I can produce a binary distribution containing no shared libraries at all, which seems to work perfectly on a range of target systems as diverse as the following:
(Sorry to be so specific here, but I'm loath to claim any empirical approach like this will work everywhere.) 

Here is how my dedicated build-box is prepared:
Then build away, and good luck to you!


Q&A

(Actually, just "A")

©2008-2009 Ronald S. Burkey.  Last updated 2009-04-26 by RSB (info at sandroid.org)