-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
resinator: Sync with upstream #22522
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Note: This mostly matches resinator v0.1.0 rather than the latest master version, since the latest master version focuses on adding support for .res -> .obj conversion which is not necessary for the future planned relationship of zig and resinator (resinator will likely be moved out of the compiler and into the build system, a la translate-c). So, ultimately the changes here consist mostly of bug fixes for obscure edge cases.
alexrp
approved these changes
Jan 21, 2025
Thanks for the nice writeup as well as the sync. |
squeek502
added a commit
to squeek502/zig
that referenced
this pull request
Feb 8, 2025
… case In ziglang#22522 I said: > RC="zig rc" will now work in combination with zig cc and CMake. Here's an example of cross-compiling a simple Windows GUI CMake project > > $ RC="zig rc" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows -G Ninja However, I didn't realize that the time that this only works because of the `-G Ninja` part. When not using Ninja as the build tool, CMake adds a workaround for 'very long lists of object files' where it takes all object files and runs them through `ar` to combine them into one archive: https://github.com/Kitware/CMake/blob/4a11fd8dde745789f66d6500412d7f56607e9218/Modules/Platform/Windows-GNU.cmake#L141-L158 This is a problem for the Windows resource use-case, because `ar` doesn't know how to deal with `.res` files and so this object combining step fails with: unknown file type: foo.rc.res Only the linker knows what to do with .res files (since it has its own `.res` -> `.obj` ('cvtres') conversion mechanism). So, when using Ninja, this object file combining step is skipped and the .res file gets passed to the linker and everyone is happy. Note: When CMake thinks that its using `windres` as the Windows resource compiler, it will pass `-O coff` to windres which causes it to output a COFF object file instead of a `.res` file, which means that the `ar` step can succeed because it's only working on actual object files. --- This commit gives `zig rc` the ability to output COFF object files directly when `/:output-format coff` is provided as an argument. This effectively matches what happens when CMake uses `windres` for resource compilation, but requires the argument to be provided explicitly. So, after this change, the following CMake cross-compilation use case will work, even when not using Ninja as the generator: RC="zig rc /:output-format coff" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows
squeek502
added a commit
to squeek502/zig
that referenced
this pull request
Feb 9, 2025
Fixup for some of the changes in ziglang#22522
squeek502
added a commit
that referenced
this pull request
Feb 10, 2025
Fixup for some of the changes in #22522
squeek502
added a commit
to squeek502/zig
that referenced
this pull request
Feb 10, 2025
… case In ziglang#22522 I said: > RC="zig rc" will now work in combination with zig cc and CMake. Here's an example of cross-compiling a simple Windows GUI CMake project > > $ RC="zig rc" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows -G Ninja However, I didn't realize that the time that this only works because of the `-G Ninja` part. When not using Ninja as the build tool, CMake adds a workaround for 'very long lists of object files' where it takes all object files and runs them through `ar` to combine them into one archive: https://github.com/Kitware/CMake/blob/4a11fd8dde745789f66d6500412d7f56607e9218/Modules/Platform/Windows-GNU.cmake#L141-L158 This is a problem for the Windows resource use-case, because `ar` doesn't know how to deal with `.res` files and so this object combining step fails with: unknown file type: foo.rc.res Only the linker knows what to do with .res files (since it has its own `.res` -> `.obj` ('cvtres') conversion mechanism). So, when using Ninja, this object file combining step is skipped and the .res file gets passed to the linker and everyone is happy. Note: When CMake thinks that its using `windres` as the Windows resource compiler, it will pass `-O coff` to windres which causes it to output a COFF object file instead of a `.res` file, which means that the `ar` step can succeed because it's only working on actual object files. --- This commit gives `zig rc` the ability to output COFF object files directly when `/:output-format coff` is provided as an argument. This effectively matches what happens when CMake uses `windres` for resource compilation, but requires the argument to be provided explicitly. So, after this change, the following CMake cross-compilation use case will work, even when not using Ninja as the generator: RC="zig rc /:output-format coff" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows
andrewrk
pushed a commit
that referenced
this pull request
Feb 23, 2025
… case In #22522 I said: > RC="zig rc" will now work in combination with zig cc and CMake. Here's an example of cross-compiling a simple Windows GUI CMake project > > $ RC="zig rc" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows -G Ninja However, I didn't realize that the time that this only works because of the `-G Ninja` part. When not using Ninja as the build tool, CMake adds a workaround for 'very long lists of object files' where it takes all object files and runs them through `ar` to combine them into one archive: https://github.com/Kitware/CMake/blob/4a11fd8dde745789f66d6500412d7f56607e9218/Modules/Platform/Windows-GNU.cmake#L141-L158 This is a problem for the Windows resource use-case, because `ar` doesn't know how to deal with `.res` files and so this object combining step fails with: unknown file type: foo.rc.res Only the linker knows what to do with .res files (since it has its own `.res` -> `.obj` ('cvtres') conversion mechanism). So, when using Ninja, this object file combining step is skipped and the .res file gets passed to the linker and everyone is happy. Note: When CMake thinks that its using `windres` as the Windows resource compiler, it will pass `-O coff` to windres which causes it to output a COFF object file instead of a `.res` file, which means that the `ar` step can succeed because it's only working on actual object files. --- This commit gives `zig rc` the ability to output COFF object files directly when `/:output-format coff` is provided as an argument. This effectively matches what happens when CMake uses `windres` for resource compilation, but requires the argument to be provided explicitly. So, after this change, the following CMake cross-compilation use case will work, even when not using Ninja as the generator: RC="zig rc /:output-format coff" CC="zig cc --target=x86_64-windows-gnu" cmake .. -DCMAKE_SYSTEM_NAME=Windows
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The end result of this PR is somewhat boring--it's just some bug fixes, mostly for obscure edge cases--but the journey was not straightforward.
This PR has had 3 distinct versions:
The tightly integrated version
The original plan was to implement what's detailed here: make resinator compile directly to COFF object files, and then send those to the linker instead of
.res
files.However, the plan (as I understand it) is now for resinator to become a build system thing rather than part of the compiler, following the lead of translate-c (relevant issue), so tight integration with the compiler would be wasted effort.
The drop-in
windres
versionThe master version of
resinator
has support for outputting COFF object files, and one other potential use case that opens up is providing awindres
-compatible CLI interface (since windres can also output COFF object files).So, the second plan was to add a
zig windres
command (see #9564 (comment)). This could be useful, because CMake can use windres when cross-compiling, so being able to do something likeRC="zig windres" CC="zig cc --target=x86_64-windows-gnu" cmake ...
would be quite nice.From my testing, however, CMake only recognizes the RC compiler as windres if "windres" is in the 'main' program name (i.e.
zigwindres
would work and CMake would give it windres-style arguments, butzig windres
still getsrc.exe
-style arguments). So, having azig windres
command wouldn't actually help that much to enable this use case without a wrapper script.The bug fix version
So, ultimately, the windres subcommand and all COFF object file stuff was excluded from this update for the sake of simplicity. Instead, it's mostly just bug fixes.
However, the CMake cross-compiling use case is still addressed, because it turns out the only thing really blocking it before was CMake giving the RC compiler absolute paths, which
resinator
tried to interpret as flags, e.g./home/foo/bar.rc
would be interpreted as the flag/h
which prints the help screen and exits. Note that this behavior is 'correct' in terms ofrc.exe
, since it is Windows-only and uses/
as an option prefix.To support the CMake use-case, resinator's CLI parser has been updated to infer when an argument might actually be an absolute filepath (see the
looksLikeFilepath
function inresinator/cli.zig
).So,
RC="zig rc"
will now work in combination withzig cc
and CMake. Here's an example of cross-compiling a simple Windows GUI CMake project:Running the result with wine (the dialog, the button, and the label come from the
.rc
file):Re-closes #9564 (cc @alexrp)