Compiling with Winelib on Linux

Just thought I'd share that it's possible to compile and run on Linux with Winelib:

1
winegcc -mwindows code/win32_handmade.cpp


Up until day 10, this worked without any code modifications, but gcc doesn't support the __rdtsc intrinsic [EDIT: This is actually not true if you include x86intrin.h. See below.]. So I added this (which I stole from Stack Overflow) to the top of the file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#ifndef _MSC_VER
#ifdef __i386__
static __inline__ unsigned long long __rdtsc(void)
{
    unsigned long long int x;
    __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A"(x));
    return x;
}
#endif
#ifdef __x86_64__
static __inline__ unsigned long long __rdtsc(void)
{
    unsigned hi, lo;
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#endif
#endif


This might also work on OS X, but I don't run OS X so I don't know.

Edited by Evan Shaw on
That doesn't sound like something you should have to do. I don't use GCC anymore, but on LLVM you should be able to use their RDTSC intrinsic directly. I would assume the same would be true on GCC, but I don't know.

From CLANG's intrin.h:
1
2
unsigned __int64 __rdtsc(void);
unsigned __int64 __rdtscp(unsigned int *);


No inline ASM necessary :)

- Casey
Yes, __rdtsc() is available for gcc. You just need to do #include <x86intrin.h>
Thanks! I searched around but didn't find anything mentioning that intrinsic. I added an edit to the original post.
I tried adding x86intrin.h but I get this error

1
2
3
/usr/bin/ld: cannot find -lwinecrt0
collect2: error: ld returned 1 exit status
winegcc: gcc failed

Any idea on what am I missing? I tried looking in /lib/ and /lib/wine/ but the library is not there and google is not being any useful today :(

I'm using Arch if that helps

Edited by M'aiq on
Have you installed wine?

1
pacman -S wine


I'm also on Arch fwiw.
My bad, I had wine-git from the AUR, apparently it gets rid of some stuff when it's done compiling, thanks
[strike]My bad, I had wine-git from the AUR, it works now thanks[/strike]
Man this forum is confusing

Edited by M'aiq on
Not sure why you use winegcc to compile on Linux.

You should install mingw-w64-gcc package. MinGW is gcc based toolchain to create Windows executables/dll files. It provides whole toolchain (compiler, linker, resource compiler assembler, etc...) that allows you code to compile for 32-bit or 64-bit Windows. Use i686-w64-mingw32-g++ to compile 32-bit executable and x86_64-w64-mingw32-g++ to compile 64-bit executable.

Of course, to run windows executables on Linux you'll still need wine installed.

Edited by Mārtiņš Možeiko on
Mingw would also work, but I used winegcc because it builds a native Linux binary and it's installed with Wine already.
Sure, whatever works for you is good.
I just find it weird - to use Linux to build Windows code to Linux binary :) Imho you can simplify life by removing one step (Linux binary).
Do anybody had any luck making winegcc from the part when we load code dynamically ? (day 21 to 23)

I played with shared libraries and gcc options for quite some time now and I really have hard time with it.
I haven't tried compiling whole Handmade Hero with winegcc, but simple dll/exe files work for me.

Here's dll.c file:
1
2
3
4
5
6
7
#include <stdio.h>

void
fun()
{
    printf("Hello from dll!\n");
}


Here's exe.c file:
 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
#include <stdio.h>
#include <windows.h>

int main()
{
    printf("Hello from exe!\n");

    typedef void fptr();

    HMODULE lib = LoadLibraryA("dll.dll.so");
    if (lib)
    {
        fptr* f = (fptr*)GetProcAddress(lib, "fun");
        if (f)
        {
            f();
        }
        else
        {
            printf("No fun found :(\n");
        }
    }
    else
    {
        printf("No library found\n");
    }
}


Here's dll.spec file (info on spec files):
1
@ cdecl fun()


Here's how I compile and run it:
1
2
3
4
5
$ winegcc -m32 -shared dll.c dll.spec -o dll
$ winegcc -m32 exe.c -o exe
$ ./exe.exe
Hello from exe!
Hello from dll!

I use -m32, because my wine environment is configured as 32-bit one, and my default gcc is 64-bit one. So I need to compile to 32-bit code.

But I'm still recommending to use mingw compiler and avoid linking to wine libraries. Compiled exe will run under the wine just fine.

Edited by Mārtiņš Možeiko on
Wow, Many thanks !

I will study this very soon :)
Yeah ! It works !

Just in case someone find it useful in the future, here is how to compile handmade hero day 25 on linux using winegcc:

Here is my build.sh
1
2
3
4
5
6
7
8
9
#!/bin/bash

mkdir -p ../build
pushd ../build

winegcc  -DHANDMADE_INTERNAL=1 -DHANDMADE_SLOW=1 -DHANDMADE_WIN32=1 -mwindows ../code/handmade.cpp ../code/handmade.spec -o handmadehero -g -Wno-write-strings -std=c++11 -shared -Wl, -fPIC

winegcc  -DHANDMADE_INTERNAL=1 -DHANDMADE_SLOW=1 -DHANDMADE_WIN32=1 -mwindows ../code/win32_handmade.cpp  -o handmadehero -g -Wno-write-strings -std=c++11
popd


Here is the content of handmade.spec:
1
2
@ cdecl GameUpdateAndRender()
@ cdecl GameGetSoundSamples()


I do a search & replace of handmade.dll to handmadehero.dll.so inside win32_handmade.cpp

And at last, I add theses two lines to win32_handmade.cpp
1
2
#include <x86intrin.h> //a ajouter pour compiler
#define _snprintf_s(...) snprintf(__VA_ARGS__)

(given that they start with a # which is a comment in bash, I keep them in my build.sh, ready to be cut and paste on each new handmade.cpp iteration)

Edited by albatros on