authorgravatar for Sahnvour@users.noreply.github.comSahnvour <Sahnvour@users.noreply.github.com> 2019-11-12 20:16:01+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-11-12 20:16:01+01:00
log956ba8b0e7ada08f2f85cd41ee73af6453db0c16
tree5fc46585794c24875bf8136d6435333c9dbae759
parente32b4829f4f91ee412ead7a3851f6e271d9fb07e
parentdef5462d053d744a9f4c2c6874355a23d3371b3d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #3447 from Sahnvour/vcpkg

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 {...@@ -53,7 +53,7 @@ pub const Builder = struct {
53 release_mode: ?builtin.Mode,53 release_mode: ?builtin.Mode,
54 is_release: bool,54 is_release: bool,
55 override_lib_dir: ?[]const u8,55 override_lib_dir: ?[]const u8,
5656 vcpkg_root: VcpkgRoot,
57 pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,57 pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
5858
59 const PkgConfigError = error{59 const PkgConfigError = error{
...@@ -159,6 +159,7 @@ pub const Builder = struct {...@@ -159,6 +159,7 @@ pub const Builder = struct {
159 .is_release = false,159 .is_release = false,
160 .override_lib_dir = null,160 .override_lib_dir = null,
161 .install_path = undefined,161 .install_path = undefined,
162 .vcpkg_root = VcpkgRoot{ .Unattempted = {} },
162 };163 };
163 try self.top_level_steps.append(&self.install_tls);164 try self.top_level_steps.append(&self.install_tls);
164 try self.top_level_steps.append(&self.uninstall_tls);165 try self.top_level_steps.append(&self.uninstall_tls);
...@@ -1047,6 +1048,7 @@ pub const LibExeObjStep = struct {...@@ -1047,6 +1048,7 @@ pub const LibExeObjStep = struct {
1047 output_dir: ?[]const u8,1048 output_dir: ?[]const u8,
1048 need_system_paths: bool,1049 need_system_paths: bool,
1049 is_linking_libc: bool = false,1050 is_linking_libc: bool = false,
1051 vcpkg_bin_path: ?[]const u8 = null,
10501052
1051 installed_path: ?[]const u8,1053 installed_path: ?[]const u8,
1052 install_step: ?*InstallArtifactStep,1054 install_step: ?*InstallArtifactStep,
...@@ -1265,6 +1267,11 @@ pub const LibExeObjStep = struct {...@@ -1265,6 +1267,11 @@ pub const LibExeObjStep = struct {
1265 // option is supplied.1267 // option is supplied.
1266 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));1268 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
1267 run_step.addArtifactArg(exe);1269 run_step.addArtifactArg(exe);
1270
1271 if (exe.vcpkg_bin_path) |path| {
1272 run_step.addPathDir(path);
1273 }
1274
1268 return run_step;1275 return run_step;
1269 }1276 }
12701277
...@@ -1570,6 +1577,43 @@ pub const LibExeObjStep = struct {...@@ -1570,6 +1577,43 @@ pub const LibExeObjStep = struct {
1570 }) catch unreachable;1577 }) catch unreachable;
1571 }1578 }
15721579
1580 /// If Vcpkg was found on the system, it will be added to include and lib
1581 /// paths for the specified target.
1582 pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void {
1583 // Ideally in the Unattempted case we would call the function recursively
1584 // after findVcpkgRoot and have only one switch statement, but the compiler
1585 // cannot resolve the error set.
1586 switch (self.builder.vcpkg_root) {
1587 .Unattempted => {
1588 self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root|
1589 VcpkgRoot{ .Found = root }
1590 else
1591 .NotFound;
1592 },
1593 .NotFound => return error.VcpkgNotFound,
1594 .Found => {},
1595 }
1596
1597 switch (self.builder.vcpkg_root) {
1598 .Unattempted => unreachable,
1599 .NotFound => return error.VcpkgNotFound,
1600 .Found => |root| {
1601 const allocator = self.builder.allocator;
1602 const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
1603 defer self.builder.allocator.free(triplet);
1604
1605 const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" });
1606 errdefer allocator.free(include_path);
1607 try self.include_dirs.append(IncludeDir{ .RawPath = include_path });
1608
1609 const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" });
1610 try self.lib_paths.append(lib_path);
1611
1612 self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" });
1613 },
1614 }
1615 }
1616
1573 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {1617 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
1574 assert(self.kind == Kind.Test);1618 assert(self.kind == Kind.Test);
1575 self.exec_cmd_args = args;1619 self.exec_cmd_args = args;
...@@ -2342,6 +2386,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj...@@ -2342,6 +2386,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
2342 };2386 };
2343}2387}
23442388
2389/// Returned slice must be freed by the caller.
2390fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {
2391 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
2392 defer allocator.free(appdata_path);
2393
2394 const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" });
2395 defer allocator.free(path_file);
2396
2397 const file = fs.File.openRead(path_file) catch return null;
2398 defer file.close();
2399
2400 const size = @intCast(usize, try file.getEndPos());
2401 const vcpkg_path = try allocator.alloc(u8, size);
2402 const size_read = try file.read(vcpkg_path);
2403 std.debug.assert(size == size_read);
2404
2405 return vcpkg_path;
2406}
2407
2408const VcpkgRoot = union(VcpkgRootStatus) {
2409 Unattempted: void,
2410 NotFound: void,
2411 Found: []const u8,
2412};
2413
2414const VcpkgRootStatus = enum {
2415 Unattempted,
2416 NotFound,
2417 Found,
2418};
2419
2420pub const VcpkgLinkage = enum {
2421 Static,
2422 Dynamic,
2423};
2424
2345pub const InstallDir = enum {2425pub const InstallDir = enum {
2346 Prefix,2426 Prefix,
2347 Lib,2427 Lib,
lib/std/target.zig+34
...@@ -218,6 +218,40 @@ pub const Target = union(enum) {...@@ -218,6 +218,40 @@ pub const Target = union(enum) {
218 );218 );
219 }219 }
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
221 pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {255 pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {
222 // TODO is there anything else worthy of the description that is not256 // TODO is there anything else worthy of the description that is not
223 // already captured in the triple?257 // already captured in the triple?