# Building a cross compiler (compile on Linux, run on Windows)

## gralves

Building a cross compiler (compile on Linux, run on Windows)

Introduction

Ever had those programming assignements from professors who can only run windows? Tired of spending expensive Gbs of HD just to keep a runing copy of windoze so you can compile your programs for windows? Spending hours booting the system just to find an uninitialized pointer bug? Want to change your operational system behaviour using buffer overflow? YOUR PROBLEMS ARE OVER! 

Whatever are your needs this guide will teach you how to build mingw32 on linux. It can be used to compile C and C++ code for windows machines. But be aware, linux system calls will not work (like fork, system, etc).

Before you begin you will need...

A copy of binutils source code

This can be found in several places. If you have installed gentoo from stage 1 you probably have o copy of it on your distfiles directory. Otherwise you can get them by emerging binutils or downloading them from   here.

A copy of gcc source code

Same as binutils. You can also get it here.

A copy of the precompiled win32 api (they need to be compiled for win32 and you don't have a compiler yet  :Smile:  )

This one can be found on MinGW site  on the download page. Click here for a direct download link.

A copy of the precompile mingw32 runtime library

Same as above. The direct link is here.

Let the fun begin...

Decompress everything on the right place.

Easier said than done...

You have to decompress everything in specific directories for it to work. It took me sometime to figure these out. First choose an location for the binaries/headers you you compile. I choosed /usr/local/cross-tools. Any directory will work. You will also have to choose a temporary directory for the compilling job. I used /root/cross.  PS: You don't need to be root to do this unless you want the binaries available to everyone on the system.

After choosing the directories it's  time to start decompressing. Copy everyone of the tars to /root/cross/source and:

```

mkdir /usr/local/cross-tools/i386-mingw32msvc

cd /usr/local/cross-tools/i386-mingw32msvc

gzip -dc "/root/cross/source/mingw-runtime=3.0.tar.gz" | tar xf -

gzip -dc "/root/cross/source/w32api-2.3.tar.gz" | tar xf -

cd /root/cross/source

gzip -dc "/root/cross/source/binutils-2.13.90-20030111-1-src.tar.gz" | tar xf -

gzip -dc "/root/cross/source/gcc-3.2.3-20030504-1.tar.gz" | tar xf - 

```

 Configure binutils

You will want your source code for binutils and gcc imaculate in case you make something wrong in the LONG configuring/making process. Starting over is no fun. So lets create some directories to store the configuration.

```

mkdir /root/cross/binutils-i386-mingw32msvc 

mkdir /root/cross/gcc-i386-mingw32msvc 

```

Then thanks God for bash auto-completion command (TAB) and run these commands(be sure to change the directories for your configuration):

```

cd /root/croos/binutils-i386-mingw32msvc

/root/cross/source/binutils-2.13.90-20030111-1-src/configure --prefix=/usr/local/cross-tools --target=i386-mingw32msvc &> configure.log

```

 Build and install binutils

This one is easy!

```

make &>make.log

```

After some long time, when its over do a cat make.log to make sure everything went ok. If yes all you need to do is:

```

make install &>make_install.log

```

Again check the log file. If everything is OK you are on your way to go!

 Export binutils path

Otherwise gcc won't be able to find it! I had some trouble with that...

```
export PATH=$PATH:/usr/local/cross-tools/bin 
```

 Configure gcc

```

cd /root/croos/binutils-i386-mingw32msvc

/root/cross/source/gcc-3.2.3-20030504-1/configure -v --prefix="/usr/local/cross-tools" --target=i386-mingw32msvc --with-headers="/usr/local/cross-tools/i386-mingw32msvc/include" --with-gnu-as --with-gnu-ld --without-newlib --disable-multilib &> configure.log

```

Check the log to see if everything went ok.

 Build and install gcc

```

make &> make.log

make install &> make_install.log 

```

Don't forget to check the logs!

 Clean the sys-includes

These are used by the gcc build process and are not needed to compile anything else.

```

rm -rf "/usr/local/cross-tools/i386-mingw32msvc/sys-include

```

Using your new toy

To compile:

```

i386-mingw32msvc-gcc <source_name>.c -o <target_name>

```

Have Fun!

----------

## grudge

Cool, this is one of the few reasons left why I still have windows on my machine. I'll check it out tonight and see how well it works. Thanks for the tutorial.   :Laughing: 

----------

## gralves

The only issue I had so far is that the compiled executable won't run correctly under wine (it seems that the C I/O functions don't work) but on a windows machine it runs flawlessly. 

Problably this is just a matter of putting the .dll for mingw32 somewhere where wine can find it. 

I've also found some instructions on how to build directx and opengl code under linux for win32 on http://www.libsdl.org/ (it was from there that I got the idea) but their scripts are somewhat old and I had to read the code to find out how to compile a new version.

----------

## akiross

thanx for this tutorial  :Smile: 

it will be userful!

And, if someone wants to create simple apps with GUI interface, portable under windows, he can use this libraries, which are v simple to use

http://www.wxwindows.org/

bye

----------

## akiross

hei, i got an error:

```

/usr/local/dev-cross/i386-mingw32msvc/lib//libmingw32.a(main.o)(.text+0x97):main.c: undefined reference to `WinMain@16'

```

what is this?

it's the first time i get it... (after install SDL libraries)

what if can be?

thanks

bye

----------

## gralves

 *akiross wrote:*   

> hei, i got an error:
> 
> ```
> 
> /usr/local/dev-cross/i386-mingw32msvc/lib//libmingw32.a(main.o)(.text+0x97):main.c: undefined reference to `WinMain@16'
> ...

 

It is a linking eror. It can't find the WinMAin@16 function... I don't know what it might be.  You can try the MinGW forums...

----------

## zhenlin

WinMain@16 is the entry point, like main()

----------

## MrStaticVoid

Wow...what a great tip!  However, I found instructions including a script which I used to build the compiler.  It does almost exactly the same thing as gralves explained, but it also included the Windows OpenGL and DirectX libraries and it was all automated.  It was nice to just start the script and go to bed and wake up with a cross-compiler.

----------

## akiross

Hi!

I solve the problem with SDL

u need to pass the following library when link:

-lmingw32 -lSDLmain -lSDL (other libraries)

bye

----------

## daysleper

It's also possible to run MinGW under wine.

Just head over to the mingw website and download "MinGW-3.1.0-1.exe". Then execute the installer under wine:

```
wine -- MinGW-3.1.0-1.exe
```

Then you can compile to a Win32-binary like this:

```
wine -- g++ hello.cpp -o hello.exe
```

..and run it like this:

```
wine -- hello.exe 

Hello Windows!
```

Nice -- eh?

If you want other stuff like .. cvs and make .. there's also a msysDTK-1.0.1.exe file you can download and install.  :Smile: 

Edit: On second thought -- you could probably use the cvs and make already installed under Linux (I just did).

----------

## kormoc

DeletedLast edited by kormoc on Mon Dec 24, 2018 9:05 am; edited 1 time in total

----------

## Vanquirius

@kormoc

The ebuilds will work, and are probably an easier method. But according to my memory and the ChangeLog of xmingw-gcc

 *ChangeLog wrote:*   

>   01 Oct 2003; Stefan Jones <:gentoo.org> :
> 
>   Initial ebuild

 ,

such ebuilds were not available at the time this guide was written.

----------

## kormoc

DeletedLast edited by kormoc on Mon Dec 24, 2018 9:05 am; edited 1 time in total

----------

## gralves

Thanks for posting the ebuilds... I hadn't checked on it for sometime and it will be a lot easier to maintain my system uptodate with them.

----------

## capheind

Yeah emerge xmingw-gcc doesn't work on mine. Anyone else having any luck. I just get:

!!! ERROR: dev-util/xmingw-gcc-3.3.1 failed.

!!! Function src_install, Line 69, Exitcode 2

!!! make install failed

----------

## docbill

I'm looking for trick to do just the reverse.  I want to be able to compile Linux applications using Cygwin.  The reason you ask?  For now it just to see if it can be done.

                   Bill

----------

## SeeksTheMoon

I searched this forum and tested a little bit how to exactly use the xmingw-compiler.

1. dev-util/xmingw-runtime  && dev-util/xmingw-w32api have to be emerged BEFORE you emerge the xmingw-gcc or you cannot create c++ code!

2. add /opt/xmingw/bin to your path with

```
export PATH=$PATH:/opt/xmingw/bin
```

and you have to add the xmingw-headers to the CPPFLAGS:

```
export CPPFLAGS="-I /opt/xmingw/i386-mingw32msvc/include"
```

or xmingw will not find windows.h and the other headers.

When you have installed DirectX SDK on a Windows-Partition it might work when you mount this partition and add -I <PATH> to CPPFLAGS for every include-directory you need.

It might be usefull to use gcc's flag "-fms-extensions", which "accepts some non-standard constructs used in Microsoft header files." when you are doing this.

3. simple code can be compiled with

```
i386-mingw32msvc-g++ hello.cpp -o hello.exe
```

where hello.cpp is

```
#include <iostream>

using namespace std;

int main() {

cout<<"Hello World!"<<endl;

return 0;

}
```

You can test hello.exe with wine or winex.

("i386-mingw32msvc-g++" sucks, you may create a symlink named /usr/bin/gw32 if you want.)

4. When you invoke configure-scripts and want to cross-compile, then use

```
./configure --target=i386-mingw32msvc --host=i386-mingw32msvc --build=i386-linux --prefix=/opt/xmingw/i386-mingw32msvc 
```

with the other configure-parameters you may need.

Check the output for lines like

```

checking host system type... i386-pc-mingw32msvc

...

checking whether we are cross compiling... yes

...

checking for i386-mingw32msvc-g++... g++

...

checking for i386-mingw32msvc-ranlib... i386-mingw32msvc-ranlib

checking for i386-mingw32msvc-dlltool... i386-mingw32msvc-dlltool

checking for i386-mingw32msvc-dllwrap... i386-mingw32msvc-dllwrap

checking for i386-mingw32msvc-windres... i386-mingw32msvc-windres

checking for i386-mingw32msvc-objcopy... i386-mingw32msvc-objcopy

...

checking for windows.h... yes

...

```

and so on.

5. complex programs may have a special Makefile for mingw. Use this one instead of the normal Unix-Makefile:

```
make -f Makefile.mingw
```

----------

## sibisco

hello!

My aim is to build a cross compiler from linux to windows. I have tested your application but I   have a little problem to compile my test file. The linux prompt doesn't accept the command.

[root@dyn-9-147-232-208 root]# i686-pc-mingw32-gcc test.c -o i686-pc-mingw32

bash: i686-pc-mingw32-gcc: command not found

Can you help me to solve my problem.

Thanks

----------

## SeeksTheMoon

it is "i386-mingw32msvc-gcc", not "i686-mingw32msvc-gcc"

----------

## sibisco

thanks for your help! 

I have solved my problem : it was due to the PATH variable.

But now I have a new problem : 

How use a makefile with a cross-compiler?

when you write a makefile, does the common "make" is compiled by the gcc of my cross compiler or compiled by the default gcc installed on my system?

----------

## irondog

Programming qt applications for windows in Linux would be cool. 

The problem: qt for windows is not free.

A possible solution: http://kde-cygwin.sourceforge.net/qt3-win32/index.php

 :Smile:  They made a windows version of QT by replacing X11 functions with win32 functions using the GPL qt/x11.  :Smile: 

Here is a similar howto, which describes how to compile qt applications for windows (using a crosscompiler in Linux):

http://www.technosis.de/mingw/crosscompile/

Most important is this line:

 *Quote:*   

> You need the "Qt for Windows" source code and of cource a licence for Qt Windows!! 

 

So, taking this information together we can do this:

Compile Qt/win32 using cygwin, leave windows and write a crossplatform application in Linux with the power of C/C++ and Qt for Free.

----------

## sibisco

Hi!

I have some questions about the cross compiling : 

when we make a cross compiler, I think it's possible to have various targets, but how to do when the targets are very vast ? 

I explain : I have to make a cross compiler which  targets are AIX and Linux. How can I do to manage the different versions (mandrake 9.1 or red hat, AIX 5.1 or AIX 5.2...) ?

Thanks!

----------

## salfter

The xmingw-* ebuilds are long gone.  Something like 

```
echo sys-devel/crossdev ~arch >>/etc/portage/package.keywords && emerge crossdev && crossdev i586-mingw32
```

 is what you want to use to build a cross-compiler for building Windows apps.

----------

## mariourk

I've written a very small and basic program that I normally compile like this:

```

g++ *.h *.cc -o output-file

```

Now I want to compile it for windows. But I'm running into trouble with some includes.

The compiles says it cannot find those files. The only includes I'm using are:

```

#include <iostream>

#include <fstream>

#include <sstream>

#include <string>

```

Could anyone point me in the right direction?

----------

## Colonel Paneek

 *mariourk wrote:*   

> I've written a very small and basic program that I normally compile like this:
> 
> ```
> 
> g++ *.h *.cc -o output-file
> ...

 

The header files for mingw32 are in /usr/mingw32/usr/include

```
emerge sys-devel/crossdev && crossdev mingw32

equery files cross-mingw32/w32api | grep include
```

----------

## dingfelder

fyi:  the mingw32 packages don't seem to be part of prtage any more.

you will need to emerge sys-devel/crossdev which now includes it.

see http://gentoo-wiki.com/HOWTO_MinGW for info

----------

