authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-19 18:01:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-05-25 18:54:36-07:00
logd1204d410472786bfd831a6349437b7784273f42
treedf1a3588e8746da65580127a59a6fa0353b9ff91
parent3a259e2f0f56220ffa3019b009429e9adc4bc6d0

Maker.Step.Run: implement addPathForDynLibs


2 files changed, 38 insertions(+), 20 deletions(-)

lib/compiler/Maker/Step/Compile.zig+2-2
......@@ -119,7 +119,7 @@ fn updateGeneratedFile(
119119/// the root module. The root module is guaranteed to be first.
120120const ModuleList = std.AutoArrayHashMapUnmanaged(Configuration.Module.Index, Configuration.String);
121121/// Keyed on the first key in the module list.
122const ModuleGraph = std.ArrayHashMapUnmanaged(ModuleList, void, ModuleListContext, false);
122pub const ModuleGraph = std.ArrayHashMapUnmanaged(ModuleList, void, ModuleListContext, false);
123123
124124const ModuleListContext = struct {
125125 pub fn eql(ctx: @This(), a: ModuleList, b: ModuleList) bool {
......@@ -1164,7 +1164,7 @@ const CliNamedModules = struct {
11641164 }
11651165};
11661166
1167fn getCompileDependencies(
1167pub fn getCompileDependencies(
11681168 arena: Allocator,
11691169 module_graph: *ModuleGraph,
11701170 conf: *const Configuration,
lib/compiler/Maker/Step/Run.zig+36-18
......@@ -137,16 +137,9 @@ pub fn make(
137137 const producer_index = arg.producer.value.?;
138138 const producer_step = producer_index.ptr(conf);
139139 const producer = producer_step.extended.get(conf.extra).compile;
140 const root_module = producer.root_module.get(conf);
141 const root_module_target = root_module.resolved_target.get(conf).?.result.get(conf);
142 const os_tag = root_module_target.flags.os_tag.unwrap().?;
143140 const producer_make_comp_step = maker.stepByIndex(producer_index);
144141 const producer_make_comp = &producer_make_comp_step.extended.compile;
145142
146 if (os_tag == .windows) {
147 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
148 addPathForDynLibs(producer_index);
149 }
150143 const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*;
151144
152145 argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{
......@@ -953,7 +946,7 @@ const FuzzTestRunner = struct {
953946 if (i == std.math.maxInt(u32)) return;
954947 i += 1;
955948 }) {
956 const name_prefix = "f" ++ Io.Dir.path.sep_str ++ "in";
949 const name_prefix = "f" ++ Dir.path.sep_str ++ "in";
957950 in_name = std.fmt.bufPrint(&in_name_buf, name_prefix ++ "{x}", .{i}) catch unreachable;
958951 in_f = cache_root.handle.openFile(io, in_name, .{
959952 .lock = .exclusive,
......@@ -990,7 +983,7 @@ const FuzzTestRunner = struct {
990983 defer in_f.close(io);
991984
992985 // Save it to a seperate file
993 const crash_name = "f" ++ Io.Dir.path.sep_str ++ "crash";
986 const crash_name = "f" ++ Dir.path.sep_str ++ "crash";
994987 const out = cache_root.handle.createFile(io, crash_name, .{
995988 .lock = .exclusive, // Multiple run steps could have found a crash at the same time
996989 }) catch |e| return step.fail(maker, "failed to create file '{f}{s}': {t}", .{
......@@ -1922,7 +1915,7 @@ fn runCommand(
19221915
19231916 if (root_target.os.tag == .windows) {
19241917 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
1925 addPathForDynLibs(producer_index);
1918 try addPathForDynLibs(maker, producer_index, environ_map, argv[0]);
19261919 }
19271920
19281921 gpa.free(step.result_failed_command.?);
......@@ -2298,14 +2291,39 @@ fn convertPathArg(run_index: Configuration.Step.Index, maker: *Maker, path: Path
22982291 return Dir.path.join(arena, &.{ ".", child_cwd_rel });
22992292}
23002293
2301fn addPathForDynLibs(artifact: Configuration.Step.Index) void {
2302 if (true) @panic("TODO addPathForDynLibs");
2303 for (artifact.getCompileDependencies(true)) |compile| {
2304 if (compile.root_module.resolved_target.?.result.os.tag == .windows and
2305 compile.isDynamicLibrary())
2306 {
2307 @panic("TODO addPathForDynLibs");
2308 //addPathDir(run, Dir.path.dirname(compile.getEmittedBin().getPath2(b, step)).?);
2294fn addPathForDynLibs(
2295 maker: *Maker,
2296 artifact: Configuration.Step.Index,
2297 environ_map: *process.Environ.Map,
2298 argv0: []const u8,
2299) !void {
2300 const conf = &maker.scanned_config.configuration;
2301 const graph = maker.graph;
2302 const arena = graph.arena; // TODO don't leak into process arena
2303 const use_wine = graph.enable_wine and builtin.os.tag != .windows and std.ascii.endsWithIgnoreCase(argv0, ".exe");
2304 const path_key = if (use_wine) "WINEPATH" else "PATH";
2305 const path_delimiter: u8 = if (builtin.os.tag == .windows or use_wine)
2306 Dir.path.delimiter_windows
2307 else
2308 Dir.path.delimiter;
2309
2310 var module_graph: Step.Compile.ModuleGraph = .empty;
2311 const compile_deps = try Step.Compile.getCompileDependencies(arena, &module_graph, conf, artifact, true);
2312
2313 for (compile_deps) |dep_index| {
2314 const conf_comp_step = dep_index.ptr(conf);
2315 const conf_comp = conf_comp_step.extended.get(conf.extra).compile;
2316 const root_module = conf_comp.root_module.get(conf);
2317 const target = root_module.resolved_target.get(conf).?.result.get(conf);
2318 if (target.flags.os_tag == .windows and conf_comp.isDynamicLibrary()) {
2319 const dll_path = try maker.generatedPath(conf_comp.generated_bin.value.?).toString(arena);
2320 const search_path = Dir.path.dirname(dll_path).?;
2321 if (environ_map.get(path_key)) |prev_path| {
2322 const new_path = try allocPrint(arena, "{s}{c}{s}", .{ prev_path, path_delimiter, search_path });
2323 try environ_map.put(path_key, new_path);
2324 } else {
2325 try environ_map.put(path_key, search_path);
2326 }
23092327 }
23102328 }
23112329}