diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-09-22 12:18:50 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-22 12:18:50 -0700 |
| commit | 3fc74135749e32ba106572ed85a2e253b89fb0c6 (patch) | |
| tree | fdefb9fa7dc6bda28b9a94ce0c01f711fb06f1ed /src/main.zig | |
| parent | 867e61e10b905cdd1559ed9364ed28decb17d328 (diff) | |
| parent | 572956ce240478ed6bdc5d98237e25fea0bab3e5 (diff) | |
| download | zig-3fc74135749e32ba106572ed85a2e253b89fb0c6.tar.gz zig-3fc74135749e32ba106572ed85a2e253b89fb0c6.zip | |
Merge pull request #17069 from squeek502/resinator
Add a `.rc` -> `.res` compiler to the Zig compiler
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/src/main.zig b/src/main.zig index 6c28503f9b..9eb80f2998 100644 --- a/src/main.zig +++ b/src/main.zig @@ -472,6 +472,12 @@ const usage_build_generic = \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted) \\ --libc [file] Provide a file which specifies libc paths \\ -cflags [flags] -- Set extra flags for the next positional C source files + \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files + \\ -rcincludes=[type] Set the type of includes to use when compiling .rc source files + \\ any (default) Use msvc if available, fall back to gnu + \\ msvc Use msvc include paths (must be present on the system) + \\ gnu Use mingw include paths (distributed with Zig) + \\ none Do not use any autodetected include paths \\ \\Link Options: \\ -l[lib], --library [lib] Link against system library (only if actually used) @@ -919,11 +925,15 @@ fn buildOutputType( var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(arena); var clang_argv = std.ArrayList([]const u8).init(arena); var extra_cflags = std.ArrayList([]const u8).init(arena); + var extra_rcflags = std.ArrayList([]const u8).init(arena); // These are before resolving sysroot. var lib_dir_args = std.ArrayList([]const u8).init(arena); var rpath_list = std.ArrayList([]const u8).init(arena); var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{}; var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena); + 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 link_objects = std.ArrayList(Compilation.LinkObject).init(arena); var framework_dirs = std.ArrayList([]const u8).init(arena); var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{}; @@ -1042,6 +1052,19 @@ fn buildOutputType( if (mem.eql(u8, next_arg, "--")) break; try extra_cflags.append(next_arg); } + } else if (mem.eql(u8, arg, "-rcincludes")) { + rc_includes = parseRcIncludes(args_iter.nextOrFatal()); + } else if (mem.startsWith(u8, arg, "-rcincludes=")) { + rc_includes = parseRcIncludes(arg["-rcincludes=".len..]); + } else if (mem.eql(u8, arg, "-rcflags")) { + extra_rcflags.shrinkRetainingCapacity(0); + while (true) { + const next_arg = args_iter.next() orelse { + fatal("expected -- after -rcflags", .{}); + }; + if (mem.eql(u8, next_arg, "--")) break; + try extra_rcflags.append(next_arg); + } } else if (mem.eql(u8, arg, "--color")) { const next_arg = args_iter.next() orelse { fatal("expected [auto|on|off] after --color", .{}); @@ -1590,7 +1613,8 @@ fn buildOutputType( } } else switch (file_ext orelse Compilation.classifyFileExt(arg)) { - .object, .static_library, .shared_library, .res => try link_objects.append(.{ .path = arg }), + .object, .static_library, .shared_library => try link_objects.append(.{ .path = arg }), + .res => try res_files.append(.{ .path = arg }), .assembly, .assembly_with_cpp, .c, .cpp, .h, .ll, .bc, .m, .mm, .cu => { try c_source_files.append(.{ .src_path = arg, @@ -1599,6 +1623,12 @@ fn buildOutputType( .ext = file_ext, }); }, + .rc => { + try rc_source_files.append(.{ + .src_path = arg, + .extra_flags = try arena.dupe([]const u8, extra_rcflags.items), + }); + }, .zig => { if (root_src_file) |other| { fatal("found another zig file '{s}' after root source file '{s}'", .{ arg, other }); @@ -1684,13 +1714,20 @@ fn buildOutputType( .ext = file_ext, // duped while parsing the args. }); }, - .unknown, .shared_library, .object, .static_library, .res => try link_objects.append(.{ + .unknown, .shared_library, .object, .static_library => try link_objects.append(.{ + .path = it.only_arg, + .must_link = must_link, + }), + .res => try res_files.append(.{ .path = it.only_arg, .must_link = must_link, }), .def => { linker_module_definition_file = it.only_arg; }, + .rc => { + try rc_source_files.append(.{ .src_path = it.only_arg }); + }, .zig => { if (root_src_file) |other| { fatal("found another zig file '{s}' after root source file '{s}'", .{ it.only_arg, other }); @@ -2452,6 +2489,12 @@ fn buildOutputType( } else if (emit_bin == .yes) { const basename = fs.path.basename(emit_bin.yes); break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; + } else if (rc_source_files.items.len >= 1) { + const basename = fs.path.basename(rc_source_files.items[0].src_path); + break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; + } else if (res_files.items.len >= 1) { + const basename = fs.path.basename(res_files.items[0].path); + break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; } else if (show_builtin) { break :blk "builtin"; } else if (arg_mode == .run) { @@ -2530,6 +2573,21 @@ fn buildOutputType( link_libcpp = true; } + if (target_info.target.ofmt == .coff) { + // Now that we know the target supports resources, + // we can add the res files as link objects. + for (res_files.items) |res_file| { + try link_objects.append(res_file); + } + } else { + if (rc_source_files.items.len != 0) { + fatal("rc files are not allowed unless the target object format is coff (Windows/UEFI)", .{}); + } + if (res_files.items.len != 0) { + fatal("res files are not allowed unless the target object format is coff (Windows/UEFI)", .{}); + } + } + if (target_info.target.cpu.arch.isWasm()) blk: { if (single_threaded == null) { single_threaded = true; @@ -2933,6 +2991,7 @@ fn buildOutputType( if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { const total_obj_count = c_source_files.items.len + @intFromBool(root_src_file != null) + + rc_source_files.items.len + link_objects.items.len; if (total_obj_count > 1) { fatal("{s} does not support linking multiple objects into one", .{@tagName(object_format)}); @@ -3319,6 +3378,8 @@ fn buildOutputType( .rpath_list = rpath_list.items, .symbol_wrap_set = symbol_wrap_set, .c_source_files = c_source_files.items, + .rc_source_files = rc_source_files.items, + .rc_includes = rc_includes, .link_objects = link_objects.items, .framework_dirs = framework_dirs.items, .frameworks = resolved_frameworks.items, @@ -6478,3 +6539,8 @@ fn accessFrameworkPath( return false; } + +fn parseRcIncludes(arg: []const u8) Compilation.RcIncludes { + return std.meta.stringToEnum(Compilation.RcIncludes, arg) orelse + fatal("unsupported rc includes type: '{s}'", .{arg}); +} |
