From d1204d410472786bfd831a6349437b7784273f42 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 19 May 2026 18:01:40 -0700 Subject: [PATCH] Maker.Step.Run: implement addPathForDynLibs --- lib/compiler/Maker/Step/Compile.zig | 4 +-- lib/compiler/Maker/Step/Run.zig | 54 +++++++++++++++++++---------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/lib/compiler/Maker/Step/Compile.zig b/lib/compiler/Maker/Step/Compile.zig index e8f632ed28f71fc525f39f7e15168838741d3df8..881546f5122b7cd3b4cfec9e555871fa7c6c96d4 100644 --- a/lib/compiler/Maker/Step/Compile.zig +++ b/lib/compiler/Maker/Step/Compile.zig @@ -119,7 +119,7 @@ fn updateGeneratedFile( /// the root module. The root module is guaranteed to be first. const ModuleList = std.AutoArrayHashMapUnmanaged(Configuration.Module.Index, Configuration.String); /// Keyed on the first key in the module list. -const ModuleGraph = std.ArrayHashMapUnmanaged(ModuleList, void, ModuleListContext, false); +pub const ModuleGraph = std.ArrayHashMapUnmanaged(ModuleList, void, ModuleListContext, false); const ModuleListContext = struct { pub fn eql(ctx: @This(), a: ModuleList, b: ModuleList) bool { @@ -1164,7 +1164,7 @@ const CliNamedModules = struct { } }; -fn getCompileDependencies( +pub fn getCompileDependencies( arena: Allocator, module_graph: *ModuleGraph, conf: *const Configuration, diff --git a/lib/compiler/Maker/Step/Run.zig b/lib/compiler/Maker/Step/Run.zig index 2cc2972bcb9a126d9895fcfdfe792dc033ab6543..c927d6d4af90ed114483a0b53504cf3c33a5fd7b 100644 --- a/lib/compiler/Maker/Step/Run.zig +++ b/lib/compiler/Maker/Step/Run.zig @@ -137,16 +137,9 @@ pub fn make( const producer_index = arg.producer.value.?; const producer_step = producer_index.ptr(conf); const producer = producer_step.extended.get(conf.extra).compile; - const root_module = producer.root_module.get(conf); - const root_module_target = root_module.resolved_target.get(conf).?.result.get(conf); - const os_tag = root_module_target.flags.os_tag.unwrap().?; const producer_make_comp_step = maker.stepByIndex(producer_index); const producer_make_comp = &producer_make_comp_step.extended.compile; - if (os_tag == .windows) { - // On Windows we don't have rpaths so we have to add .dll search paths to PATH - addPathForDynLibs(producer_index); - } const file_path = producer_make_comp.installed_path orelse maker.generatedPath(producer.generated_bin.value.?).*; argv_list.appendAssumeCapacity(try mem.concat(arena, u8, &.{ @@ -953,7 +946,7 @@ const FuzzTestRunner = struct { if (i == std.math.maxInt(u32)) return; i += 1; }) { - const name_prefix = "f" ++ Io.Dir.path.sep_str ++ "in"; + const name_prefix = "f" ++ Dir.path.sep_str ++ "in"; in_name = std.fmt.bufPrint(&in_name_buf, name_prefix ++ "{x}", .{i}) catch unreachable; in_f = cache_root.handle.openFile(io, in_name, .{ .lock = .exclusive, @@ -990,7 +983,7 @@ const FuzzTestRunner = struct { defer in_f.close(io); // Save it to a seperate file - const crash_name = "f" ++ Io.Dir.path.sep_str ++ "crash"; + const crash_name = "f" ++ Dir.path.sep_str ++ "crash"; const out = cache_root.handle.createFile(io, crash_name, .{ .lock = .exclusive, // Multiple run steps could have found a crash at the same time }) catch |e| return step.fail(maker, "failed to create file '{f}{s}': {t}", .{ @@ -1922,7 +1915,7 @@ fn runCommand( if (root_target.os.tag == .windows) { // On Windows we don't have rpaths so we have to add .dll search paths to PATH - addPathForDynLibs(producer_index); + try addPathForDynLibs(maker, producer_index, environ_map, argv[0]); } gpa.free(step.result_failed_command.?); @@ -2298,14 +2291,39 @@ fn convertPathArg(run_index: Configuration.Step.Index, maker: *Maker, path: Path return Dir.path.join(arena, &.{ ".", child_cwd_rel }); } -fn addPathForDynLibs(artifact: Configuration.Step.Index) void { - if (true) @panic("TODO addPathForDynLibs"); - for (artifact.getCompileDependencies(true)) |compile| { - if (compile.root_module.resolved_target.?.result.os.tag == .windows and - compile.isDynamicLibrary()) - { - @panic("TODO addPathForDynLibs"); - //addPathDir(run, Dir.path.dirname(compile.getEmittedBin().getPath2(b, step)).?); +fn addPathForDynLibs( + maker: *Maker, + artifact: Configuration.Step.Index, + environ_map: *process.Environ.Map, + argv0: []const u8, +) !void { + const conf = &maker.scanned_config.configuration; + const graph = maker.graph; + const arena = graph.arena; // TODO don't leak into process arena + const use_wine = graph.enable_wine and builtin.os.tag != .windows and std.ascii.endsWithIgnoreCase(argv0, ".exe"); + const path_key = if (use_wine) "WINEPATH" else "PATH"; + const path_delimiter: u8 = if (builtin.os.tag == .windows or use_wine) + Dir.path.delimiter_windows + else + Dir.path.delimiter; + + var module_graph: Step.Compile.ModuleGraph = .empty; + const compile_deps = try Step.Compile.getCompileDependencies(arena, &module_graph, conf, artifact, true); + + for (compile_deps) |dep_index| { + const conf_comp_step = dep_index.ptr(conf); + const conf_comp = conf_comp_step.extended.get(conf.extra).compile; + const root_module = conf_comp.root_module.get(conf); + const target = root_module.resolved_target.get(conf).?.result.get(conf); + if (target.flags.os_tag == .windows and conf_comp.isDynamicLibrary()) { + const dll_path = try maker.generatedPath(conf_comp.generated_bin.value.?).toString(arena); + const search_path = Dir.path.dirname(dll_path).?; + if (environ_map.get(path_key)) |prev_path| { + const new_path = try allocPrint(arena, "{s}{c}{s}", .{ prev_path, path_delimiter, search_path }); + try environ_map.put(path_key, new_path); + } else { + try environ_map.put(path_key, search_path); + } } } } -- 2.54.0