Commit def5462d05
Changed files (2)
lib
lib/std/build.zig
@@ -53,7 +53,7 @@ pub const Builder = struct {
release_mode: ?builtin.Mode,
is_release: bool,
override_lib_dir: ?[]const u8,
-
+ vcpkg_root: VcpkgRoot,
pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
const PkgConfigError = error{
@@ -159,6 +159,7 @@ pub const Builder = struct {
.is_release = false,
.override_lib_dir = null,
.install_path = undefined,
+ .vcpkg_root = VcpkgRoot{ .Unattempted = {} },
};
try self.top_level_steps.append(&self.install_tls);
try self.top_level_steps.append(&self.uninstall_tls);
@@ -1046,6 +1047,7 @@ pub const LibExeObjStep = struct {
output_dir: ?[]const u8,
need_system_paths: bool,
is_linking_libc: bool = false,
+ vcpkg_bin_path: ?[]const u8 = null,
installed_path: ?[]const u8,
install_step: ?*InstallArtifactStep,
@@ -1264,6 +1266,11 @@ pub const LibExeObjStep = struct {
// option is supplied.
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
run_step.addArtifactArg(exe);
+
+ if (exe.vcpkg_bin_path) |path| {
+ run_step.addPathDir(path);
+ }
+
return run_step;
}
@@ -1569,6 +1576,43 @@ pub const LibExeObjStep = struct {
}) catch unreachable;
}
+ /// If Vcpkg was found on the system, it will be added to include and lib
+ /// paths for the specified target.
+ pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void {
+ // Ideally in the Unattempted case we would call the function recursively
+ // after findVcpkgRoot and have only one switch statement, but the compiler
+ // cannot resolve the error set.
+ switch (self.builder.vcpkg_root) {
+ .Unattempted => {
+ self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root|
+ VcpkgRoot{ .Found = root }
+ else
+ .NotFound;
+ },
+ .NotFound => return error.VcpkgNotFound,
+ .Found => {},
+ }
+
+ switch (self.builder.vcpkg_root) {
+ .Unattempted => unreachable,
+ .NotFound => return error.VcpkgNotFound,
+ .Found => |root| {
+ const allocator = self.builder.allocator;
+ const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
+ defer self.builder.allocator.free(triplet);
+
+ const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" });
+ errdefer allocator.free(include_path);
+ try self.include_dirs.append(IncludeDir{ .RawPath = include_path });
+
+ const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" });
+ try self.lib_paths.append(lib_path);
+
+ self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" });
+ },
+ }
+ }
+
pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
assert(self.kind == Kind.Test);
self.exec_cmd_args = args;
@@ -2341,6 +2385,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
};
}
+/// Returned slice must be freed by the caller.
+fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {
+ const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
+ defer allocator.free(appdata_path);
+
+ const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" });
+ defer allocator.free(path_file);
+
+ const file = fs.File.openRead(path_file) catch return null;
+ defer file.close();
+
+ const size = @intCast(usize, try file.getEndPos());
+ const vcpkg_path = try allocator.alloc(u8, size);
+ const size_read = try file.read(vcpkg_path);
+ std.debug.assert(size == size_read);
+
+ return vcpkg_path;
+}
+
+const VcpkgRoot = union(VcpkgRootStatus) {
+ Unattempted: void,
+ NotFound: void,
+ Found: []const u8,
+};
+
+const VcpkgRootStatus = enum {
+ Unattempted,
+ NotFound,
+ Found,
+};
+
+pub const VcpkgLinkage = enum {
+ Static,
+ Dynamic,
+};
+
pub const InstallDir = enum {
Prefix,
Lib,
lib/std/target.zig
@@ -218,6 +218,40 @@ pub const Target = union(enum) {
);
}
+ /// Returned slice must be freed by the caller.
+ pub fn vcpkgTriplet(allocator: *mem.Allocator, target: Target, linkage: std.build.VcpkgLinkage) ![]const u8 {
+ const arch = switch (target.getArch()) {
+ .i386 => "x86",
+ .x86_64 => "x64",
+
+ .arm,
+ .armeb,
+ .thumb,
+ .thumbeb,
+ .aarch64_32,
+ => "arm",
+
+ .aarch64,
+ .aarch64_be,
+ => "arm64",
+
+ else => return error.VcpkgNoSuchArchitecture,
+ };
+
+ const os = switch (target.getOs()) {
+ .windows => "windows",
+ .linux => "linux",
+ .macosx => "macos",
+ else => return error.VcpkgNoSuchOs,
+ };
+
+ if (linkage == .Static) {
+ return try mem.join(allocator, "-", [_][]const u8{ arch, os, "static" });
+ } else {
+ return try mem.join(allocator, "-", [_][]const u8{ arch, os });
+ }
+ }
+
pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {
// TODO is there anything else worthy of the description that is not
// already captured in the triple?