-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Add preliminary support for Windows .manifest
files
#17448
Conversation
Did some testing and I think this is the right way to go. The downside of this approach is that Zig won't do any validation of manifest files, so it's on the user to ensure that their manifest file is correct ( Here's a real world example from Windows-classic-samples:
Compiled with Zig on Windows via:
Here's proof that the DPI awareness is in effect in the Zig-compiled version: And here's proof that the control styles are affected in the intended way (see the checkbox and button style difference in the version without the manifest): Note that this 'generate an .rc with a RT_MANIFEST resource' strategy happens to be the exact thing that MSVC does for auto-generated manifests. If the "Generate Manifest" option is set to Yes in "Linker > Manifest File" in Visual Studio, then, for example:
|
1fd102d
to
c21ee00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I agree with your reasoning regarding option 3.
c21ee00
to
7835ab3
Compare
An embedded manifest file is really just XML data embedded as a RT_MANIFEST resource (ID = 24). Typically, the Windows-only 'Manifest Tool' (`mt.exe`) is used to embed manifest files, and `mt.exe` also seems to perform some transformation of the manifest data before embedding, but in testing it doesn't seem like the transformations are necessary to get the intended result. So, to handle embedding manifest files, Zig now takes the following approach: - Generate a .rc file with the contents `1 24 "path-to-manifest.manifest"` - Compile that generated .rc file into a .res file - Link the .res file into the final binary This effectively achieves the same thing as `mt.exe` minus the validation/transformations of the XML data that it performs. How this is used: On the command line: ``` zig build-exe main.zig main.manifest ``` (on the command line, specifying a .manifest file when the target object format is not COFF is an error) or in build.zig: ``` const exe = b.addExecutable(.{ .name = "manifest-test", .root_source_file = .{ .path = "main.zig" }, .target = target, .optimize = optimize, .win32_manifest = .{ .path = "main.manifest" }, }); ``` (in build.zig, the manifest file is ignored if the target object format is not COFF) Note: Currently, only one manifest file can be specified per compilation. This is because the ID of the manifest resource is currently always 1. Specifying multiple manifests could be supported if a way for the user to specify an ID for each manifest is added (manifest IDs must be a u16). Closes ziglang#17406 options
…Windows manifest file Example: > zig build-exe test.zig test.xml warning: embedded manifest files must have the extension '.manifest' error: unrecognized file extension of parameter 'test.xml'
7835ab3
to
b511478
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks perfect
This is one option for addressing #17406 (it is option 3 in #17406 (comment)). See that issue for some more details.
An embedded manifest file is really just XML data embedded as a
RT_MANIFEST
resource (ID = 24). Typically, the Windows-only 'Manifest Tool' (mt.exe
) is used to embed manifest files, andmt.exe
also seems to perform some transformation of the manifest data before embedding, but in testing it doesn't seem like the transformations are necessary to get the intended result.So, to handle embedding manifest files, Zig now takes the following approach:
1 24 "path-to-manifest.manifest"
This effectively achieves the same thing as
mt.exe
minus the validation/transformations of the XML data that it performs.How this is used:
On the command line:
(on the command line, specifying a .manifest file when the target object format is not COFF is an error)
or in build.zig:
(in build.zig, the manifest file is ignored if the target object format is not COFF)
Note: Currently, only one manifest file can be specified per compilation. This is because the ID of the manifest resource is currently always 1. Specifying multiple manifests could be supported if a way for the user to specify an ID for each manifest is added (manifest IDs must be a u16). I'm not familiar enough with manifests to know what the use case for multiple manifests is.
Closes #17406
remnants of the original OP
The above works as intended on Windows for the example manifest here at least: https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page#set-a-process-code-page-to-utf-8
This is currently a draft because I need to do some more testing to better determine if it's a viable strategy more generally:
.rc
/.res
files under the hood).manifest
files in Windows-classic-samples and seeing if this method of embedding the manifest has the same effective result as the MSVC compilers method (this is the real kicker, and might be somewhat tough to determine)