build: initial support for using vcpkg libraries
parent
8c8078513e
commit
def5462d05
|
@ -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,
|
||||
|
|
|
@ -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?
|
||||
|
|
Loading…
Reference in New Issue