Monday, June 15, 2020

Embedding rc files into Go Win32 executables

When building Go executables in Windows, the Go toolchain recognizes *.syso files and automatically embeds then into the *.exe – this allows the embedding of resources scripts, which can contain icon and manifest, among other resources. Visual C++ resource compiler, however, only generate *.res files.

I’ve seen people using rsrc tool to add manifest files to executables. The problem is that this tool doesn’t really compile a resource file, nor it converts *.res into *.syso.

Turns out resource file compilation can be done with windres tool, from MinGW package. Since I already have the whole Visual C++ stuff, I didn’t want to install all the package, which is rather big, and I already have MinGW terminal from Git. Fortunately, windres works standalone, the only requisite is that gcc is in the same directory. And we can download both.

Portable MinGW tools can be downloaded from here:

From both packages, extract gcc and windres and save them somewhere else. All the rest can be deleted.

Compile the *.rc file into *.res with Visual C++ Developer Power Shell for VS 2019:

rc /r my-resource.rc

Then, on MinGW prompt, convert *.res into *.syso:

windres -i my-resource.res -o my-resource.syso

Now place my-resource.syso in the same directory of your main.go, and that’s it. For some weird reason, when debugging in VSCode, the program icon may appear wrong, but it will show fine in release builds, which are the ones that really matter:

go build -ldflags "-s -w -H=windowsgui"

Ideally windres would be used to compile the *.rc directly into *.syso, but to do so it needs the Win32 headers from MinGW, which are not present – you’ll get an error. Probably there’s a way to point Visual C++ headers directory to windres, but by now I’m satisfied using windres tool just to convert the *.res.

No comments: