floooh / sokol-zig

Zig bindings for the sokol headers (https://github.com/floooh/sokol)
zlib License
341 stars 46 forks source link

Can not compile in Windows #44

Closed tuket closed 1 year ago

tuket commented 1 year ago

Hi!

I don't think it's a bug in sokol, most likely it's a bug in the Zig compiler or a user error. But I was wondering if you could help me. Have you been able to compile any sokol app in Windows recenlty? I'm pretty sure that I've been able to compile my sokol app at some point, but it stopped working. There seems to be an error linking WinMain. I have found that it might be a more general problem. But I'm left wondering why I'm experiencing this issue now, and if other people have this issue too.

Thanks for making these awesome libraries!

Manuzor commented 1 year ago

I just tried zig build with zig v0.11.0 on the master branch of this repo and tested all the examples afterwards. Everything seems to work well.

Can you provide the source code and the version of zig you're using?

tuket commented 1 year ago

Thanks for trying it out!

I'm using zig v0.11.0 as well. Interesting!

Here is the project: zig_sokol_test.zip

tuket commented 1 year ago

I tried compiling the library on it's own, and it seem to work, and I can run the samples!

The problem shows up when I try to use sokol as an external library. I have my own build.zig and I import sokol externally. I have also tried with the new package manger approach and I get the same link error.

floooh commented 1 year ago

I can reproduce the problem in your project, but not in sokol-zig or my other projects, not sure what could be causing this.

Can you check if pacman.zig works for you? That should be pretty close to your use case:

https://github.com/floooh/pacman.zig

(building it works, but I just noticed that the colors are off, need to investigate this separately)

PS: the sokol headers won't hijack main() or WinMain because of this define: https://github.com/floooh/sokol-zig/blob/2506dbb4de21c8e04cdc14dc4909fea72edb2d21/src/sokol/c/sokol_defines.h#L2

(the SOKOL_WIN32_FORCE_MAIN below will actually be ignored, because SOKOL_NO_ENTRY overrides that)

So if the C compilation works as expected then the sokol C library should have no main() or WinMain() entry point.

(PS: ignore the pacman.zig color problem, it also happens in the pacman.c version, so it's not Zig related)

PPS: pacman.zig also works when using the package manager branch, e.g.:

git clone --branch sokol-package https://github.com/floooh/pacman.zig
cd pacman.zig
zig build run

PS: ok that wrong-color-problem was a small regression from the image/sampler separation: https://github.com/floooh/pacman.zig/commit/78fbb0dc5c445d0fee99c85ab56a8450d4d1f732

(I probably should have used sokol-shdc to build the shader code, then it wouldn't have happened)

Still no idea about that WinMain problem though.

floooh commented 1 year ago

When I try to build your project, and look at the symbols of sokol.lib in the zig-cache, I can't find any references to main or WinMain (as it should be), e.g. what I did in a "Visual Studio command prompt" => so that Visual Studio's dumpbin tool is in the path, also 'fd' is a file-find tool installed via scoop:

> fd sokol.lib
zig_sokol_test\zig-cache\o\b85f443ef0ac2d82e7cac908be9a8f28\sokol.lib
> dumpbin /SYMBOLS zig_sokol_test\zig-cache\o\b85f443ef0ac2d82e7cac908be9a8f28\sokol.lib >log.txt

...the resulting log has all internal and external symbols in sokol.lib, and if sokol.lib wants to link with main() or WinMain() one of those symbols should be listed, which they are not though.

When you run zig env, what's printed? In may case:

C:\Users\floh\Downloads\zig_sokol_test>zig env
{
 "zig_exe": "C:\\Users\\floh\\scoop\\apps\\zig\\current\\zig.exe",
 "lib_dir": "C:\\Users\\floh\\scoop\\apps\\zig\\current\\lib",
 "std_dir": "C:\\Users\\floh\\scoop\\apps\\zig\\current\\lib\\std",
 "global_cache_dir": "C:\\Users\\floh\\AppData\\Local\\zig",
 "version": "0.11.0",
 "target": "x86_64-windows.win10_fe...win10_fe-gnu"
}
Manuzor commented 1 year ago

It looks to me like root zig module is not specified. I assume it got lost in translation when porting from the old build API to the new one. When I add src/main.zig it compiles and runs for me.

const exe = b.addExecutable(.{
    .name = "zig_sokol_test",
    .target = target,
    .optimize = optimize,
    // This is missing {
    .root_source_file = .{
        .path = "src/main.zig",
    },
    // }
});
floooh commented 1 year ago

Lol yeah, that's it I guess. I just tested to remove all code, and just put an @import("std").debug.print("Hello") into the zig main function, and that also had the linker error.

floooh commented 1 year ago

Yeah confirmed that's it, putting the .root_source_file into build.zig makes it work. A bit strange that Zig doesn't catch that as error. I'll close the ticket, if there's anything else feel free to reopen with new details :)

tuket commented 1 year ago

That was it! thank you very much guys :)

Manuzor commented 1 year ago

Glad it all worked out. 🙂

Yeah confirmed that's it, putting the .root_source_file into build.zig makes it work. A bit strange that Zig doesn't catch that as error. I'll close the ticket, if there's anything else feel free to reopen with new details :)

Not adding any zig files allows you to compile a pure C project with the zig build system without bringing in anything from zig (in terms of generated code). But maybe root_source_file should not be null by default so you need to explicitly choose null to opt out of zig.