Difference between revisions of "Cross-Compiling Under Linux"
(Debian stuff) |
m |
||
Line 118: | Line 118: | ||
== Some more details for Debian folks == | == Some more details for Debian folks == | ||
− | After apt-getting the three packages mingw32, mingw32-binutils and mingw32-runtime from "unstable" as well as the wxWindows source (I took the "2.6.2 all ports combined", but MSW should be enough), use the <tt>--host</tt> option of the configure script (see "Autoconf supports cross-compilation natively" above) for auto-magic! | + | After apt-getting the three packages mingw32, mingw32-binutils and mingw32-runtime from "unstable" as well as downloading the wxWindows source (I took the "2.6.2 all ports combined", but MSW should be enough), use the <tt>--host</tt> option of the configure script (see "Autoconf supports cross-compilation natively" above) for auto-magic! |
If that doesn't work: I found out that I had to set the environment variables mentioned above ("Flags"), however I needed "export CFLAGS=" as well: | If that doesn't work: I found out that I had to set the environment variables mentioned above ("Flags"), however I needed "export CFLAGS=" as well: |
Revision as of 19:58, 23 March 2006
Cross-compiling under Linux
- Install The Mingw Cross-Compiler.
- Compile wxWidgets
- Download wxWidgets source
- Compile with ./configure --prefix=/usr/local/i386-mingw32 --host=i386-mingw32 --target=i386-mingw32 --with-msw --your_optional_switches
make make install
See also:
- Embedding icons in your cross-compiled binary: Cross-Compiling Windows Resources
- Embedding other files: Embedding PNG Images
- IBM DeveloperWorks article
- Cross compiling RLS AVON with MinGW on Linux (simple instructions for installing environment, compiling wxWidgets, and compiling an certain wxWidgets application)
Note: The SDL scripts and these directions cannot be mixed. Note: By disabling threads (with --disable-threads), you can avoid a dependency on the ming dll
Example usage
Once installed, save the following file as winhello.c (stolen from Installing and Using the MinGW Cross-Compiler on Mac OS X:
/* * Hello, World for Win32 * gcc winhello.c -o winhello.exe */ #include <windows.h> int main(int argc, char *argv[]) { MessageBox(NULL, "Hello, world!", "Hello, world!", MB_OK); return 0; }
To build the example, execute the following command:
$ i386-mingw32-gcc winhello.c -o winhello.exe
and run it for example with wine wine winhello.exe .
Contrib libraries
Couldn't compile the contrib directory with the wxMSW 2.4.2 sources, use the latest cvs.
Flags
You might need these flags when compiling:
-Wl,--subsystem,windows -mwindows -DWINVER=0x0400 -D__WIN95__ -D__GNUWIN32__ -DSTRICT -DHAVE_W32API_H -D__WXMSW__ -D__WINDOWS__
And these while linking:
-lregex -lpng -ljpeg -lzlib -ltiff -lstdc++ -lgcc -lodbc32 -lwsock32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lctl3d32 -lodbc32 -ladvapi32 -lodbc32 -lwsock32 -lopengl32 -lglu32 -lole32 -loleaut32 -luuid
environment variables
In order to use the cross-compiler tools you need to replace the normal tools in makefiles. This is easier to do just exporting some environment variables before running configure/make:
export CC=i586-mingw32msvc-gcc export CXX=i586-mingw32msvc-c++ export LD=i586-mingw32msvc-ld export AR=i586-mingw32msvc-ar export AS=i586-mingw32msvc-as export NM=i586-mingw32msvc-nm export STRIP=i586-mingw32msvc-strip export RANLIB=i586-mingw32msvc-ranlib export DLLTOOL=i586-mingw32msvc-dlltool export OBJDUMP=i586-mingw32msvc-objdump export RESCOMP=i586-mingw32msvc-windres
SDL's Script
See also: BuildCVS.txt in the tar of the SDL scripts
http://www.libsdl.org/extras/win32/cross/ contains scripts that automate the compiler build process described above.
Download build-cross.sh, cross-configure.sh, and cross-make.sh.
Run the script build-cross.sh.
Download the CVS version wxAll and uncompress it.
Copy cross-configure.sh and cross-make.sh to the wxWidgets-2.5.2 directory.
Run cross-configure.sh and cross-make.sh and you should be done. :-)
Autoconf supports cross-compilation natively
If your cross-suite is i586-mingw32msvc-{gcc,g++,ld,...}, just do ../configure --with-msw --target=i586-mingw32msvc --host=i586-mingw32msvc --build=i386-linux and all necessary tools will be prefixed automatically.
ATTENTION: Turn off binfmt support before running configure (Debian: /etc/init.d/binfmt-support stop), which invokes wine for .exe files; otherwise configure will think it does NOT use a cross-compiler.
Autoconf/Automake unit testing suites
(maybe this section should go somewhere else?)
It is possible to autotest your code using wine (you are using unit tests, right?). This makes it very easy to script code under Unix to build multiple platforms, then test, without intervention. This section focusses on testing console-able objects.
First familiarise yourself with building test binaries with autoconf and automake. I recommend cppunit (for C++ systems). There's plentiful documentation on cppunit's website on integrating cppunit with Makefile.am. One show-stopping step is the ability to test msw binaries in the same way (make check) one tests unix binaries.
To take advantage of wine (running your tests automatically with wine), first make sure that wine may run headless. If you have access to a graphical terminal then this isn't important (if you're Ok with having wine spout gobbledygock to a window with every run). Make sure your test-directory Makefile.am's have all TESTS tokens suffixed with $(EXEEXT):
TESTS = TestFoo$(EXEEXT)
check_PROGRAMS = TestFoo
...and so on.
Next add a configure.ac (you have upgraded to using .ac instead of .in, right?) line manipulating the macro TESTS_ENVIRONMENT:
AC_SUBST([TESTS_ENVIRONMENT], [$WINE])
In this I assume that WINE has been set with AC_CHECK_PROGS or something (even `WINE = wine'). This will have all tests run in the following format:
$(TESTS_ENVIRONMENT) $${dir}$$tst
Where dir is the path and tst is the test name (remember that EXEEXT). That's it: wine will return the exit code of your running binary. You can also put a special shell or other token in there, but that exceeds the focus of this documentation. This assumed automake-1.9 and autoconf-2.57 but I'm fairly certain it works in earlier versions of both (uncertain about autoconf-2.13 style).
Some more details for Debian folks
After apt-getting the three packages mingw32, mingw32-binutils and mingw32-runtime from "unstable" as well as downloading the wxWindows source (I took the "2.6.2 all ports combined", but MSW should be enough), use the --host option of the configure script (see "Autoconf supports cross-compilation natively" above) for auto-magic!
If that doesn't work: I found out that I had to set the environment variables mentioned above ("Flags"), however I needed "export CFLAGS=" as well:
export CC=i586-mingw32msvc-gcc export CXX=i586-mingw32msvc-g++ export LD=i586-mingw32msvc-ld export AR=i586-mingw32msvc-ar export AS=i586-mingw32msvc-as export NM=i586-mingw32msvc-nm export STRIP=i586-mingw32msvc-strip export RANLIB=i586-mingw32msvc-ranlib export DLLTOOL=i586-mingw32msvc-dlltool export OBJDUMP=i586-mingw32msvc-objdump export RESCOMP=i586-mingw32msvc-windres export CFLAGS=
If you save that in a file, say, don't forget that you shouldn't execute, but source it! Then
./configure --prefix=/usr/local/i586-mingw32 --host=i586-mingw32msvc --target=i586-mingw32msvc \ --with-msw [--your_optional_switches] make make install
(or sudo make install, depending what rights you have on /usr/local/i586-mingw32).
Your wxMSW libraries will be created in the directory you specified with --prefix, here it's /usr/local/i586-mingw32
To test your mingw32 installation with a sample not using wxWidgets, look above ("Example usage").
To test your mingw32 installation with a real wxWidgets example, take minimal.cpp from the official examples. Fortunately, I didn't have to fiddle around with the flags myself, I use wx-config for that - not the system-wide one, but the one compiled with the cross-Windows libraries below /usr/local/i586-mingw32!
i586-mingw32msvc-g++ -c -o minimal.o minimal.cpp \ `/usr/local/i586-mingw32/bin/wx-config --cxxflags` i586-mingw32msvc-g++ -o minimal.exe minimal.o \ `/usr/local/i586-mingw32/bin/wx-config --libs`
Attention, there are are two caveats here that could cost you lots of time (it did cost me lots of time, hope I'll save yours ;-)
- When compiling, be sure to include the -c option. -o with an .o object file isn't enough, mingw32 will try to link!
- When linking, be sure to include first your object files and then the libraries (given by wx-config). When compiling, the order isn't too important, but if you exchange libraries and object files at the linking stage, you'll get lots of undefined references. In fact, mingw32 shows exactly the same behaviour as if you hadn't specified any libraries at all! I don't know if this is a bug, but according to the Debian Bug Report #254185 it seems to be OK.
Finally, when executing your program with wine, qemu (works great!) or even on a real Windows box, don't forget that even if you linked everything statically, you'll also need mingwm10.dll in addition to your executable. Put in in the same directory and execute the binary from there, and everything works. I found mingwm10.dll gzipped in /usr/share/doc/mingw32-runtime/