fix running things with zig build on Windows
Windows doesn't have rpaths for DLLs so we instead add search paths to Path environment variable when running an executable that depends on DLLs built with zig build.
This commit is contained in:
parent
85d23e68ee
commit
5046aa9403
@ -1060,6 +1060,7 @@ pub const LibExeObjStep = struct {
|
||||
/// Add command line arguments with `addArg`.
|
||||
pub fn run(exe: *LibExeObjStep) *RunStep {
|
||||
assert(exe.kind == Kind.Exe);
|
||||
assert(exe.target == Target.Native);
|
||||
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
|
||||
run_step.addArtifactArg(exe);
|
||||
return run_step;
|
||||
@ -1276,7 +1277,7 @@ pub const LibExeObjStep = struct {
|
||||
LibExeObjStep.Kind.Lib => {
|
||||
if (other.static or self.target.isWindows()) {
|
||||
try zig_args.append("--object");
|
||||
try zig_args.append(other.getOutputPath());
|
||||
try zig_args.append(other.getOutputLibPath());
|
||||
} else {
|
||||
const full_path_lib = other.getOutputPath();
|
||||
try zig_args.append("--library");
|
||||
@ -1495,7 +1496,7 @@ pub const RunStep = struct {
|
||||
cwd: ?[]const u8,
|
||||
|
||||
/// Override this field to modify the environment, or use setEnvironmentVariable
|
||||
env_map: ?*const BufMap,
|
||||
env_map: ?*BufMap,
|
||||
|
||||
pub const Arg = union(enum) {
|
||||
Artifact: *LibExeObjStep,
|
||||
@ -1529,12 +1530,28 @@ pub const RunStep = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8) void {
|
||||
const env_map = self.env_map orelse blk: {
|
||||
const env_map = os.getEnvMap(allocator) catch unreachable;
|
||||
self.env_map = env_map;
|
||||
break :blk env_map;
|
||||
pub fn addPathDir(self: *RunStep, search_path: []const u8) void {
|
||||
const PATH = if (builtin.os == builtin.Os.windows) "Path" else "PATH";
|
||||
const env_map = self.getEnvMap();
|
||||
const prev_path = env_map.get(PATH) orelse {
|
||||
env_map.set(PATH, search_path) catch unreachable;
|
||||
return;
|
||||
};
|
||||
const new_path = self.builder.fmt("{}" ++ [1]u8{os.path.delimiter} ++ "{}", prev_path, search_path);
|
||||
env_map.set(PATH, new_path) catch unreachable;
|
||||
}
|
||||
|
||||
pub fn getEnvMap(self: *RunStep) *BufMap {
|
||||
return self.env_map orelse {
|
||||
const env_map = self.builder.allocator.create(BufMap) catch unreachable;
|
||||
env_map.* = os.getEnvMap(self.builder.allocator) catch unreachable;
|
||||
self.env_map = env_map;
|
||||
return env_map;
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setEnvironmentVariable(self: *RunStep, key: []const u8, value: []const u8) void {
|
||||
const env_map = self.getEnvMap();
|
||||
env_map.set(key, value) catch unreachable;
|
||||
}
|
||||
|
||||
@ -1547,12 +1564,32 @@ pub const RunStep = struct {
|
||||
for (self.argv.toSlice()) |arg| {
|
||||
switch (arg) {
|
||||
Arg.Bytes => |bytes| try argv.append(bytes),
|
||||
Arg.Artifact => |artifact| try argv.append(artifact.getOutputPath()),
|
||||
Arg.Artifact => |artifact| {
|
||||
if (artifact.target.isWindows()) {
|
||||
// On Windows we don't have rpaths so we have to add .dll search paths to PATH
|
||||
self.addPathForDynLibs(artifact);
|
||||
}
|
||||
try argv.append(artifact.getOutputPath());
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return self.builder.spawnChildEnvMap(cwd, self.env_map orelse self.builder.env_map, argv.toSliceConst());
|
||||
}
|
||||
|
||||
fn addPathForDynLibs(self: *RunStep, artifact: *LibExeObjStep) void {
|
||||
for (artifact.link_objects.toSliceConst()) |link_object| {
|
||||
switch (link_object) {
|
||||
LibExeObjStep.LinkObject.OtherStep => |other| {
|
||||
if (other.target.isWindows() and other.isDynamicLibrary()) {
|
||||
self.addPathDir(os.path.dirname(other.getOutputPath()).?);
|
||||
self.addPathForDynLibs(other);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const InstallArtifactStep = struct {
|
||||
|
@ -167,7 +167,7 @@ pub fn windowsOpen(
|
||||
pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap) ![]u16 {
|
||||
// count bytes needed
|
||||
const max_chars_needed = x: {
|
||||
var max_chars_needed: usize = 1; // 1 for the final null byte
|
||||
var max_chars_needed: usize = 4; // 4 for the final 4 null bytes
|
||||
var it = env_map.iterator();
|
||||
while (it.next()) |pair| {
|
||||
// +1 for '='
|
||||
@ -191,6 +191,12 @@ pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap)
|
||||
}
|
||||
result[i] = 0;
|
||||
i += 1;
|
||||
result[i] = 0;
|
||||
i += 1;
|
||||
result[i] = 0;
|
||||
i += 1;
|
||||
result[i] = 0;
|
||||
i += 1;
|
||||
return allocator.shrink(u16, result, i);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user