authorgravatar for sahnvour@pm.meSahnvour <sahnvour@pm.me> 2019-10-10 21:58:47+02:00
committergravatar for sahnvour@pm.meSahnvour <sahnvour@pm.me> 2019-11-09 12:37:38+01:00
logdef5462d053d744a9f4c2c6874355a23d3371b3d
tree69fa5e0a56032af6eb989b77f1ede5e8f48925c0
parent8c8078513e60df7e017f91193524384e4e9640ca

build: initial support for using vcpkg libraries


2 files changed, 115 insertions(+), 1 deletions(-)

lib/std/build.zig+81-1
......@@ -53,7 +53,7 @@ pub const Builder = struct {
5353 release_mode: ?builtin.Mode,
5454 is_release: bool,
5555 override_lib_dir: ?[]const u8,
56
56 vcpkg_root: VcpkgRoot,
5757 pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
5858
5959 const PkgConfigError = error{
......@@ -159,6 +159,7 @@ pub const Builder = struct {
159159 .is_release = false,
160160 .override_lib_dir = null,
161161 .install_path = undefined,
162 .vcpkg_root = VcpkgRoot{ .Unattempted = {} },
162163 };
163164 try self.top_level_steps.append(&self.install_tls);
164165 try self.top_level_steps.append(&self.uninstall_tls);
......@@ -1046,6 +1047,7 @@ pub const LibExeObjStep = struct {
10461047 output_dir: ?[]const u8,
10471048 need_system_paths: bool,
10481049 is_linking_libc: bool = false,
1050 vcpkg_bin_path: ?[]const u8 = null,
10491051
10501052 installed_path: ?[]const u8,
10511053 install_step: ?*InstallArtifactStep,
......@@ -1264,6 +1266,11 @@ pub const LibExeObjStep = struct {
12641266 // option is supplied.
12651267 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
12661268 run_step.addArtifactArg(exe);
1269
1270 if (exe.vcpkg_bin_path) |path| {
1271 run_step.addPathDir(path);
1272 }
1273
12671274 return run_step;
12681275 }
12691276
......@@ -1569,6 +1576,43 @@ pub const LibExeObjStep = struct {
15691576 }) catch unreachable;
15701577 }
15711578
1579 /// If Vcpkg was found on the system, it will be added to include and lib
1580 /// paths for the specified target.
1581 pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void {
1582 // Ideally in the Unattempted case we would call the function recursively
1583 // after findVcpkgRoot and have only one switch statement, but the compiler
1584 // cannot resolve the error set.
1585 switch (self.builder.vcpkg_root) {
1586 .Unattempted => {
1587 self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root|
1588 VcpkgRoot{ .Found = root }
1589 else
1590 .NotFound;
1591 },
1592 .NotFound => return error.VcpkgNotFound,
1593 .Found => {},
1594 }
1595
1596 switch (self.builder.vcpkg_root) {
1597 .Unattempted => unreachable,
1598 .NotFound => return error.VcpkgNotFound,
1599 .Found => |root| {
1600 const allocator = self.builder.allocator;
1601 const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
1602 defer self.builder.allocator.free(triplet);
1603
1604 const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" });
1605 errdefer allocator.free(include_path);
1606 try self.include_dirs.append(IncludeDir{ .RawPath = include_path });
1607
1608 const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" });
1609 try self.lib_paths.append(lib_path);
1610
1611 self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" });
1612 },
1613 }
1614 }
1615
15721616 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
15731617 assert(self.kind == Kind.Test);
15741618 self.exec_cmd_args = args;
......@@ -2341,6 +2385,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
23412385 };
23422386}
23432387
2388/// Returned slice must be freed by the caller.
2389fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {
2390 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
2391 defer allocator.free(appdata_path);
2392
2393 const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" });
2394 defer allocator.free(path_file);
2395
2396 const file = fs.File.openRead(path_file) catch return null;
2397 defer file.close();
2398
2399 const size = @intCast(usize, try file.getEndPos());
2400 const vcpkg_path = try allocator.alloc(u8, size);
2401 const size_read = try file.read(vcpkg_path);
2402 std.debug.assert(size == size_read);
2403
2404 return vcpkg_path;
2405}
2406
2407const VcpkgRoot = union(VcpkgRootStatus) {
2408 Unattempted: void,
2409 NotFound: void,
2410 Found: []const u8,
2411};
2412
2413const VcpkgRootStatus = enum {
2414 Unattempted,
2415 NotFound,
2416 Found,
2417};
2418
2419pub const VcpkgLinkage = enum {
2420 Static,
2421 Dynamic,
2422};
2423
23442424pub const InstallDir = enum {
23452425 Prefix,
23462426 Lib,
lib/std/target.zig+34
......@@ -218,6 +218,40 @@ pub const Target = union(enum) {
218218 );
219219 }
220220
221 /// Returned slice must be freed by the caller.
222 pub fn vcpkgTriplet(allocator: *mem.Allocator, target: Target, linkage: std.build.VcpkgLinkage) ![]const u8 {
223 const arch = switch (target.getArch()) {
224 .i386 => "x86",
225 .x86_64 => "x64",
226
227 .arm,
228 .armeb,
229 .thumb,
230 .thumbeb,
231 .aarch64_32,
232 => "arm",
233
234 .aarch64,
235 .aarch64_be,
236 => "arm64",
237
238 else => return error.VcpkgNoSuchArchitecture,
239 };
240
241 const os = switch (target.getOs()) {
242 .windows => "windows",
243 .linux => "linux",
244 .macosx => "macos",
245 else => return error.VcpkgNoSuchOs,
246 };
247
248 if (linkage == .Static) {
249 return try mem.join(allocator, "-", [_][]const u8{ arch, os, "static" });
250 } else {
251 return try mem.join(allocator, "-", [_][]const u8{ arch, os });
252 }
253 }
254
221255 pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {
222256 // TODO is there anything else worthy of the description that is not
223257 // already captured in the triple?