Here’s something I wrote about some different use-cases and information on how to use the recently-merged Windows resource compilation powers of the Zig compiler.
Some comments on the article:
- Perhaps you could suggest what to do when you have a non-UTF16
.rc
file – how do you convert it so that it is accepted byzig rc
? - In one of the command-line examples you pass an option as
-rcflags /c65001
. Would-rcflags c65001
be better / nicer? This looks particularly weird inbuild.zig
’s code, such as.flags = &.{"/c65001"}
, where.flags = &.{"c65001"}
seems (to me) more natural. - Maybe you could accept
-
and/
to introduce command-line options everywhere? And perhaps even be clever about what was actually used, so that-path /bin/foo
is not interpreted as two options, but an option name and a path? I have been bitten in the past by/
in the command line…
Anyway, again, wonderful work!
It’s a little bit complicated. If the .rc
file contains only characters within the Windows-1252 range, then converting to Windows-1252 would be the way to go (Windows-1252 is the default code page). If the .rc
file has characters outside of that range, then you’d need to convert to UTF-8 and set the code page to UTF-8 (either via the /c65001
CLI option or via #pragma code_page(65001)
in the .rc
file).
I’ll likely update the article to include some info along these lines.
Note that -rcflags <flags> --
just passes whatever is in <flags>
to the resinator CLI parser, so e.g. -rcflags /c65001 /DUNICODE --
would just pass the flags /c65001 /DUNICODE
to resinator. The -rcflags <flags> --
model is based on the similar -cflags <flags> --
used by Zig for passing C compiler flags for .c
files (you can use Build.Step.Compile.addCSourceFiles
with some flags specified and then zig build --verbose
to see -cflags <flags> --
in action).
The argument parsing matches how rc.exe
works, so because drop-in compatibility is a goal, there’s not much wiggle room here. Note that any of /
, -
, or --
are accepted prefixes for all options/flags, though (--
being an accepted prefix is not true of rc.exe
, but it doesn’t hurt drop-in compatibility). Another thing to note is that options can be combined together in a single argument, and that spaces are optional between an option and its value. For example, these are all equivalent command line options:
rc.exe /vnlnen-us file.rc
rc.exe /v /n /lnen-us file.rc
rc.exe /v /n /ln en-us file.rc
rc.exe -v -n -ln en-us file.rc
(this set of options means ‘enable verbose mode’, ‘append NUL to string table strings’, and ‘set default language to US English’)
As a fun little aside, I’m pretty proud of how resinator
prints error messages for CLI argument errors given how CLI parsing works:
(sadly, these diagnostics will only show up when using zig rc
, they won’t be quite as fancy when you’re compiling via zig build-exe
or zig build
since the Zig error messages are very geared towards source file-based errors)
EDIT: Another thing worth noting: resinator
/zig rc
tries to be helpful if it thinks an argument parsing failure is due to an absolute path being treated as a CLI option:
> resinator /some/absolute/path/option.rc
<cli>: error: the /s option is unsupported
... /some/absolute/path/option.rc
~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<cli>: error: missing input filename
<cli>: note: if this argument was intended to be the input filename, then -- should be specified in front of it to exclude it from option parsing
... /some/absolute/path/option.rc
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Awesome to see this come to fruition! Great work!