aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorRyan Liptak <squeek502@hotmail.com>2023-10-09 04:06:28 -0700
committerRyan Liptak <squeek502@hotmail.com>2023-10-15 13:33:16 -0700
commit5f15acc463d39baedd8de367330286b91c8bafc8 (patch)
tree9b9afbdb5b05090665c1b9b596f874c4fa8dd74c /src/main.zig
parentb0f031f5730be496872591dce3242004cf9a6f22 (diff)
downloadzig-5f15acc463d39baedd8de367330286b91c8bafc8.tar.gz
zig-5f15acc463d39baedd8de367330286b91c8bafc8.zip
Add preliminary support for Windows .manifest files
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 #17406 options
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/main.zig b/src/main.zig
index 14d187796c..5d5223ddb5 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -938,6 +938,7 @@ fn buildOutputType(
var rc_source_files = std.ArrayList(Compilation.RcSourceFile).init(arena);
var rc_includes: Compilation.RcIncludes = .any;
var res_files = std.ArrayList(Compilation.LinkObject).init(arena);
+ var manifest_file: ?[]const u8 = null;
var link_objects = std.ArrayList(Compilation.LinkObject).init(arena);
var framework_dirs = std.ArrayList([]const u8).init(arena);
var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{};
@@ -1627,6 +1628,11 @@ fn buildOutputType(
Compilation.classifyFileExt(arg)) {
.object, .static_library, .shared_library => try link_objects.append(.{ .path = arg }),
.res => try res_files.append(.{ .path = arg }),
+ .manifest => {
+ if (manifest_file) |other| {
+ fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other });
+ } else manifest_file = arg;
+ },
.assembly, .assembly_with_cpp, .c, .cpp, .h, .ll, .bc, .m, .mm, .cu => {
try c_source_files.append(.{
.src_path = arg,
@@ -1734,6 +1740,11 @@ fn buildOutputType(
.path = it.only_arg,
.must_link = must_link,
}),
+ .manifest => {
+ if (manifest_file) |other| {
+ fatal("only one manifest file can be specified, found '{s}' after previously specified manifest '{s}'", .{ it.only_arg, other });
+ } else manifest_file = it.only_arg;
+ },
.def => {
linker_module_definition_file = it.only_arg;
},
@@ -2601,6 +2612,9 @@ fn buildOutputType(
try link_objects.append(res_file);
}
} else {
+ if (manifest_file != null) {
+ fatal("manifest file is not allowed unless the target object format is coff (Windows/UEFI)", .{});
+ }
if (rc_source_files.items.len != 0) {
fatal("rc files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
}
@@ -3418,6 +3432,7 @@ fn buildOutputType(
.symbol_wrap_set = symbol_wrap_set,
.c_source_files = c_source_files.items,
.rc_source_files = rc_source_files.items,
+ .manifest_file = manifest_file,
.rc_includes = rc_includes,
.link_objects = link_objects.items,
.framework_dirs = framework_dirs.items,