Cross Compiling wxWidgets Applications on Linux
This document is still under construction by Jens, but I'm working on it. Please be patient.
01:00, 20 March 2008 (CET)
This document describes how to setup Code::Blocks to compile applications that use the wxWidgets toolkit for MS Windows from within Linux.
I tested it on debian sid, but it should also work on other distributions.
Needed software
Code::Blocks
You can download prebuild binaries Code::Blocks from the download page.
If you prefer to compile Code::Blocks yourself, you have the choice between downloading the sourcecode of the actual release as tarball from the official download page or to download the newest version via svn.
A guide to build Code::Blocks from svn can be found in the Nightly Cookbook.
The newest svn-versions are also available as prebuild binaries made available by users.
You can find links to the downloadpages in the actual posts in the [/index.php/board,20.0.html Nightly Builds] forum.
MinGW32
MingW32 is the cross-build version of the Minimalistic Gnu for Windows compiler suite (a port of the Gnu Compiler Suite for the MS Windows platform).
It is part of many linux distributions.
On debian the basepackage is called mingw32 and can be installed by typing
sudo apt-get install mingw32
at the command-line.
It's up to you to find out the name of the package and install it using your preferred package-manager or either compile it by hand.
wxWidgets cross-build
For debian-users I have made prebuild binary packages available on my server. I guess they are also usable on Ubuntu, but you have to try it yourself.
I don't know if there are downloadable packages available in/for other distros, but you can build it on your own.
You can download the source-code either from my server's software pool or from the wxWidgets download page.
Unpack the sources and type configure it with
./configure prefix=/usr/i586-mingw32msvc --host=i586-mingw32msvc --enable-unicode --build=`./config.guess` --disable-shared
The prefix depends on your MinGW32 installation, either does the host. The other switches can be changed as you prefer it, with oine exception (at the moment):
I wasn't able to build any application with the shred version of wxWidgets and to run it on MS WIndows. It only works with statically linked dll's.
You can see the available switches with
./configure --help
If everything wents right you get a message like this:
Configured wxWidgets 2.8.7 for `i586-pc-mingw32msvc' Which GUI toolkit should wxWidgets use? msw Should wxWidgets be compiled into single library? yes Should wxWidgets be compiled in debug mode? no Should wxWidgets be linked as a shared library? no Should wxWidgets be compiled in Unicode mode? yes What level of wxWidgets compatibility should be enabled? wxWidgets 2.4 no wxWidgets 2.6 yes Which libraries should wxWidgets use? jpeg builtin png builtin regex builtin tiff builtin zlib builtin odbc no expat builtin libmspack no sdl no
Now you can build the libraries with
make make install
If you use my binaries you should be able to call wx-config
directly.
As test you can run
wx-config --list
.
The ouput should look like
Default config is gtk2-unicode-release-2.8 Default config will be used for output Alternate matches: base-unicode-release-2.8 Also available in /usr: i586-mingw32msvc-msw-unicode-debug-2.8 i586-mingw32msvc-msw-unicode-release-2.8 i586-mingw32msvc-msw-unicode-release-static-2.8
You can see the cross-compile configurations starting with i586-mingw32msvc-msw.
If you don't see any cross-compile configurations you have to use the appropriate wx-config directly:
/usr/i586-mingw32msvc/lib/wx/config/i586-mingw32msvc-msw-unicode-release-static-2.8 --list
(The instruction may differ according to your configuration.)
If the output shows your cross-build targets, everything is okay. If not something went wrong with compiling your wxWidgets cross-libraries.
In the further part of this document I'll use the paths I used in the example configure-line.
Preparing Code::Blocks
If everything is installed you have to prepare Code::Blocks for cross-compiling.
Therefore you need a special compiler based on GNU GCC compiler
Create Compiler
- Open Settings -> Compiler and Debugger ... -> Global compiler settings.
- Chose GNU GCC compiler.
- Click Copy.
- Give your new Compiler a meaningful name.
- Chose the cross-compiler.
Fix Search directories
- Open the Search directories notebook.
- Change the search directory for the Compiler to
/usr/i586-mingw32msvc/include/
- for the Linker to
/usr/i586-mingw32msvc/lib/
- and the Resource Compiler also to
/usr/i586-mingw32msvc/include/
Fix Toolchain Executables
- Open the Toolchain executables notebook.
- Change the Program Files as follows:
- C Compiler to:
i586-mingw32msvc-gcc
- C++ Compiler and Linker for dynamic libs to:
i586-mingw32msvc-g++
- Linker for static libs to:
i586-mingw32msvc-ar
- Debugger to:
i586-mingw32msvc-gdb
- Resource compiler to:
`wx-config --host=i586-mingw32msvc --rescomp`
- Leave Make unchanged
One word to the debugger executable: there is no cross-debugger available in the MinGW-suite !
But for rudimentary debugging we can use the MS Windows version of the gdb-debugger avaible on the MinGW download site.
But debugging works not reliable, I think it's because there are some ifdef's in the Code::Blocks sources for the debugger-plugin dealing with differences between the linux and the MS Windows versions of gdb and the different application structure. Even if we use a MS WIndows executable as debugger, Code::Blocks believes it works on linux (and that's of course right) and is therefore compiled for the linux gdb.
There is also a real cross-debugger for MS WIndows applications available, that belongs to wine, but the syntax is not compatible with the one of gdb, even if it is possible to use gdb as backend for winedbg.
I will come back to the debugger and how it can be called (a shell-script) later in this document.
Setting up your project
You can of course use a working wxWidgets-project, but for testing I think the best way is to use the wizard and create a brand-new project.
Creating a new build target
If you have opened your project in Code::Blocks, go to the Projects tab in the Manager and right-click it to prepare it for cross-compiling.
Chose Properties... from the context menu and switch to the Build targets-tab.
Select one of the build targets (I used Release for this example), click the Duplicate-button and give it a new name (WinRelease in my case).
Change the Output filename from bin/Release/<filename> to bin/WinRelease/<filename>.exe, and uncheck at least Auto-generate filename extension.
Fixing build options
- In the Build options of the project you have to move
`wx-config --cflags`
from the global Compiler settings -> Other options to the one for the standard build targets (Debug and Release).
- Do the same for Linker Settings -> Other options.
- To make it clear the Other options-tabs of the Compiler settings and Linker settings belonging to the whole project have to be empty (or only include settings that are valid for the Linux and the MS Windows targets).
- Change the compiler for WinRelease from GNU GCC compiler to Mingw GNU GCC Cross-Compiler for Windows or however you called the cross-compiler.
- The appropriate calls to wx-config for the WinRelease must have the parameter: --host=i586-mingw32msvc included and should have the parameter --static set also.
- Until now I haven't been able to make a cross-compiled program run on MS Windows if I did not use the static libraries.
If the wx-config-command does not find the correct wxWidgets configuration, you can also add a --prefix=/usr/i586-mingw32msvc or maybe another prefix if you use self-compiled libraries (it should be the same you used for ./configure).
Compile
Not much to say here.
If everything went right, you should have a real MS Windows-application in your output directory:
file bin/WinRelease/test.exe bin/WinRelease/test.exe: MS-DOS executable PE for MS Windows (GUI) Intel 80386 32-bit
If you want to run it on MS Windows you need mingwm10.dll in the same directory or at any other place in the search path.
It's part of the mingw32-runtime-package and can be found (gzipped) in /usr/share/doc/mingw32-runtime/ (at least on debian systems).
You can create console-projects in a similar way without using wx-config of course.
Running on Linux
Normal run
To run your application on Linux you will need the wine-package.
To start a MS WIndows executable from the console (or from within Code::Blocks) you need the binfmt-support-package or however it is called in your distro.
If you run your test application it should look like this one:
Debugging
Coming soon...