How to compile for Windows under Linux?

Pages: 12
Let's say I am running linux and my friend is running Windows. I want to compile my program into a Windows ".exe" file rather than a linux binary. How do I go about doing this? I tried opening the source files in Code::Blocks under a Virtual Windows Machine, but it kept giving me hell about setting up libraries (which I had already set up). Is there any easy way to render my program to .exe in linux?

The library currently giving me trouble is SDL and SDL_image. It's a simple program that graphs arrows on the screen depending on which arrow key you press. The linux version I am running is Xubuntu 12.04 LTS and I am working with Code::Blocks IDE.
Try this: http://icculus.org/~dolson/sdl/ (You probably want to use the latest SDL version instead of 1.2.9)
Will take a deeper look at that later. Currently in a hurry, about to leave for dinner and not quite understanding what's said in that.
Last edited on
Thanks for that. It is now recognizing SDL's existance. However, none of its functions seem to be recognized. Here are the errors MingW is spitting out now:

||=== SDL Lesson 08, Debug ===|
obj/Debug/main.o||In function `_Z4exitv':|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|49|undefined reference to `_SDL_FreeSurface'|
obj/Debug/main.o||In function `_Z12applySurfaceiiP11SDL_SurfaceS0_P8SDL_Rect':|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|34|undefined reference to `_SDL_UpperBlit'|
obj/Debug/main.o||In function `_Z9loadImageSs':|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|21|undefined reference to `_IMG_Load'|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|24|undefined reference to `_SDL_DisplayFormatAlpha'|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|25|undefined reference to `_SDL_FreeSurface'|
obj/Debug/main.o||In function `_Z4initv':|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|38|undefined reference to `_SDL_Init'|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|39|undefined reference to `_SDL_SetVideoMode'|
obj/Debug/main.o||In function `_Z8SDL_mainv':|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|57|undefined reference to `_SDL_PollEvent'|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|68|undefined reference to `_SDL_SetVideoMode'|
/home/syntax/C++/LearningCPP/SDL Lesson 08/main.cpp|72|undefined reference to `_SDL_Flip'|
/usr/i586-mingw32msvc/lib/libmingw32.a(main.o)|| undefined reference to `_WinMain@16'|
||=== Build finished: 11 errors, 0 warnings ===|

And just to be clear, the same code compiles and runs perfectly in g++ and a linux executable.
Last edited on
If there is no easy solution for this, can anybody recommend a simple openGL tutorial for C++ I can follow? I want to make my apps as cross-compatible as possible and I understand that openGL is better supported by mingw. However, as I am new to the language, openGL is kinda scary at the moment.
Last edited on
You just need to set up your windows development environment properly. The first lesson of this tutorial walks you through this process.

http://www.lazyfoo.net/SDL_tutorials/lesson01/windows/index.php
That is why I have Ubuntu on one drive and Vista on another with my source code on a third one. I just make my own ports.
I don't really understand why the SDL functions names has an underscore before them in the error message. The error is a linker error so make sure you link SDL and SDL_image correctly.
Too much trouble. I already tried following that tutorial you linked, iseeplusplus...this is just getting too complex. Is there any wrapper that I can use to wrap a linux executable into a .exe? I really don't care about speed or filesize at the moment. Once I get to that point, I'd probably be able to set up mingw properly.

I'm pretty sure cygwin can do this, right? If so, how do I set it up?
Is there anything that can do this?

If not, I'll go ahead and continue checking the settings and filesystem to see if I did something wrong. I'm fairly certain that I did everything correctly, however...but I may be mistaken.
The error is that you're not linking with the relevant SDL libraries. The _ is prefixed to C function names, that's why the linker is complaining about missing _SDL_... functions. __ is prefixed to C++ function names. That's why user functions starting with these prefixes are reserved respectively for these languages.

If you want to write portable GUI apps between Windows/Linux, you have to use a portable graphics library.

You really should stick with it and sort out the linking problems. If you move to a different library, you'll have exactly the same issues to deal with, that is, you have to set up the environment to use the library headers and libs; there's no getting away from it.
Last edited on
Oh. Thanks for explaining that bit about the _ prefixes on the function names. How do you suggest I obtain one of these 'portable graphics libraries' for SDL? And what steps would I have to take to set it up? Sorry if it seems like I am asking to be spoon-fed, but I'm actually about to get on a plane and have no time to google it. Thank you all for the help.
Maybe is better to just run windows itself in a virtual machine, with a windows compiler installed inside it. (I know setting up something in linux is a very hard thing to do) That way you could also test your resulting program.
I've already partially set that one up. I think I made the same mistake with the SDL libraries as I did in linux, though. It gives me the same errors.
Maybe you should just the download codeblocks mingw setup, on your windows virtual machine.

NOTE: The codeblocks-10.05mingw-setup.exe file includes the GCC compiler and GDB debugger from MinGW.


http://www.codeblocks.org/downloads/26#windows

And then just follow the instructions step by step in lazy foo's tutorial.
I've already partially set that one up. I think I made the same mistake with the SDL libraries as I did in linux, though. It gives me the same errors.

Sounds like you simply forgot to link the appropriate libraries. You seem to be using SDL_image, so you need to set that up as well. If you think you already did that, you should list all the steps you've taken so far, so we can see what you did wrong.

Edit: I verified that this works fine:
1. Download SDL: http://www.libsdl.org/release/SDL-devel-1.2.15-mingw32.tar.gz
2. Extract the lib and include folders to /usr/i586-mingw32msvc
3. Download SDL_image: ftp://ftp.pbone.net/mirror/download.fedora.redhat.com/pub/fedora/linux/development/rawhide/i386/os/Packages/m/mingw32-SDL_image-1.2.12-1.fc17.noarch.rpm
4. Extract the lib and include folders (in ./usr/i686-pc-mingw32/sys-root/mingw/) to /usr/i586-mingw32msvc
5. Link SDL.dll and SDL_image.dll
6. Add a WinMain stub that calls your actual main function.

The same steps should apply when you're setting up MinGW on Windows.
Last edited on
is there any version of MingW32 SDL_image that works on (x)ubuntu? RPM is a fedora format.

EDIT: Nevermind. Figured out that I can open .rpm files with 7zip. Got the files out of it.
Last edited on
Okay, here is my code as of now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
#include <iostream>

// SDL Surfaces
SDL_Surface *surfaces[5] = {0};

// Global Constants
const int scrWidth = 640;
const int scrHeight = 400;
const int scrBitDepth = 32;

// SDL Prequisites
SDL_Event event;

SDL_Surface *loadImage(std::string filename)
{
    SDL_Surface *loadedIMG = 0;
    SDL_Surface *optimizedIMG = 0;
    loadedIMG = IMG_Load(filename.c_str());
    if(loadedIMG)
    {
        optimizedIMG = SDL_DisplayFormatAlpha(loadedIMG);
        SDL_FreeSurface(loadedIMG);
    }
    return(optimizedIMG);
}
void applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination,SDL_Rect *sprShSel = 0)
{
    SDL_Rect offset;
    offset.x = x;
    offset.y = y;
    SDL_BlitSurface(source,sprShSel,destination,&offset);
}
bool init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    surfaces[0] = SDL_SetVideoMode(scrWidth,scrHeight,scrBitDepth,SDL_SWSURFACE);
    surfaces[1] = loadImage("upImg.png");
    surfaces[2] = loadImage("downImg.png");
    surfaces[3] = loadImage("leftImg.png");
    surfaces[4] = loadImage("rightImg.png");
    for (int i=0;i<5;i++) if(!surfaces[i]) return(0);
    return(1);
}
void exit()
{
    for (int i=0;i<5;i++) SDL_FreeSurface(surfaces[i]);
}
int main(int argc,char *argv[])
{
    if(!init()) return(1);
    bool quit = 0;
    while(!quit)
    {
        if(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT) {quit=1;}
            else if(event.type == SDL_KEYDOWN)
            {
                switch(event.key.keysym.sym)
                {
                    case SDLK_UP: applySurface(0,0,surfaces[1],surfaces[0]); break;
                    case SDLK_DOWN: applySurface(0,0,surfaces[2],surfaces[0]); break;
                    case SDLK_LEFT: applySurface(0,0,surfaces[3],surfaces[0]); break;
                    case SDLK_RIGHT: applySurface(0,0,surfaces[4],surfaces[0]); break;
                    default: surfaces[0] = SDL_SetVideoMode(scrWidth,scrHeight,scrBitDepth,SDL_SWSURFACE);
                }
            }
        }
        SDL_Flip(surfaces[0]);
    }
    exit();
    return(0);
}
int WinMain (int argc,char *argv[])
{
    return(main(argc,argv));
}


It only spits out one error now, so I think I'm almost there. The only error is as follows:

c:\program files\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.4.1\..\..\..\libmingw32.a(main.o):main.c|| undefined reference to `WinMain@16'|
||=== Build finished: 1 errors, 0 warnings ===|
Last edited on
WinMain must be declared as follows:

1
2
3
4
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nShowCmd)
{
}


If you don't want to include any Windows headers, you can change it to the following:
1
2
3
4
5
6
extern "C"
{
  int __attribute__((__stdcall__)) WinMain(void*,void*,char*,int)
  {
  }
}
Pages: 12