diff --git a/lib/std/build.zig b/lib/std/build.zig index 80deb84f37..bf0d06e8f4 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -174,7 +174,7 @@ pub const Builder = struct { .is_release = false, .override_lib_dir = null, .install_path = undefined, - .vcpkg_root = VcpkgRoot{ .Unattempted = {} }, + .vcpkg_root = VcpkgRoot{ .unattempted = {} }, .args = null, }; try self.top_level_steps.append(&self.install_tls); @@ -212,7 +212,7 @@ pub const Builder = struct { } pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { - return addExecutableSource(self, name, convertOptionalPathToFileSource(root_src), false); + return addExecutableSource(self, name, convertOptionalPathToFileSource(root_src), .static); } pub const addExecutableSource = LibExeObjStep.createExecutable; @@ -250,7 +250,7 @@ pub const Builder = struct { } pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { - return addAssembleSource(self, name, FileSource.relative(src)); + return addAssembleSource(self, name, .{ .path = src }); } pub fn addAssembleSource(self: *Builder, name: []const u8, src: FileSource) *LibExeObjStep { @@ -876,7 +876,7 @@ pub const Builder = struct { ///`dest_rel_path` is relative to prefix path pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { - self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Prefix, dest_rel_path).step); + self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .Prefix, dest_rel_path).step); } pub fn installDirectory(self: *Builder, options: InstallDirectoryOptions) void { @@ -885,12 +885,12 @@ pub const Builder = struct { ///`dest_rel_path` is relative to bin path pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { - self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Bin, dest_rel_path).step); + self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .Bin, dest_rel_path).step); } ///`dest_rel_path` is relative to lib path pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { - self.getInstallStep().dependOn(&self.addInstallFileWithDir(FileSource.relative(src_path), .Lib, dest_rel_path).step); + self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .Lib, dest_rel_path).step); } pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void { @@ -1239,7 +1239,7 @@ pub const GeneratedFile = struct { /// A file source is a reference to an existing or future file. /// pub const FileSource = union(enum) { - /// A plain file path, relative to build root. + /// A plain file path, relative to build root or absolute. path: []const u8, /// A file that is generated by an interface. Those files usually are @@ -1270,13 +1270,12 @@ pub const FileSource = union(enum) { } } - /// Should only be called during make(), returns an absolute path to the file. + /// Should only be called during make(), returns a path relative to the build root or absolute. pub fn getPath(self: FileSource, builder: *Builder) []const u8 { const path = switch (self) { .path => |p| builder.pathFromRoot(p), .generated => |gen| gen.getPath(), }; - std.debug.assert(std.fs.path.isAbsolute(path)); return path; } @@ -1307,7 +1306,7 @@ pub const LibExeObjStep = struct { linker_script: ?FileSource = null, version_script: ?[]const u8 = null, out_filename: []const u8, - is_dynamic: bool, + linkage: Linkage, version: ?Version, build_mode: builtin.Mode, kind: Kind, @@ -1442,9 +1441,11 @@ pub const LibExeObjStep = struct { unversioned: void, }; + pub const Linkage = enum { dynamic, static }; + pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, switch (kind) { + self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .dynamic, switch (kind) { .versioned => |ver| ver, .unversioned => null, }); @@ -1453,25 +1454,25 @@ pub const LibExeObjStep = struct { pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, null); + self.* = initExtraArgs(builder, name, root_src, Kind.Lib, .static, null); return self; } pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, null); + self.* = initExtraArgs(builder, name, root_src, Kind.Obj, .static, null); return self; } - pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, is_dynamic: bool) *LibExeObjStep { + pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: Linkage) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, null); + self.* = initExtraArgs(builder, name, root_src, Kind.Exe, linkage, null); return self; } pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { const self = builder.allocator.create(LibExeObjStep) catch unreachable; - self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, null); + self.* = initExtraArgs(builder, name, root_src, Kind.Test, .static, null); return self; } @@ -1480,7 +1481,7 @@ pub const LibExeObjStep = struct { name_raw: []const u8, root_src_raw: ?FileSource, kind: Kind, - is_dynamic: bool, + linkage: Linkage, ver: ?Version, ) LibExeObjStep { const name = builder.dupe(name_raw); @@ -1494,7 +1495,7 @@ pub const LibExeObjStep = struct { .verbose_link = false, .verbose_cc = false, .build_mode = builtin.Mode.Debug, - .is_dynamic = is_dynamic, + .linkage = linkage, .kind = kind, .root_src = root_src, .name = name, @@ -1553,12 +1554,15 @@ pub const LibExeObjStep = struct { .Obj => .Obj, .Exe, .Test => .Exe, }, - .link_mode = if (self.is_dynamic) .Dynamic else .Static, + .link_mode = switch (self.linkage) { + .dynamic => std.builtin.LinkMode.Dynamic, + .static => std.builtin.LinkMode.Static, + }, .version = self.version, }) catch unreachable; if (self.kind == .Lib) { - if (!self.is_dynamic) { + if (self.linkage == .static) { self.out_lib_filename = self.out_filename; } else if (self.version) |version| { if (target.isDarwin()) { @@ -1655,7 +1659,7 @@ pub const LibExeObjStep = struct { } pub fn isDynamicLibrary(self: *LibExeObjStep) bool { - return self.kind == Kind.Lib and self.is_dynamic; + return self.kind == Kind.Lib and self.linkage == .dynamic; } pub fn producesPdbFile(self: *LibExeObjStep) bool { @@ -1920,8 +1924,13 @@ pub const LibExeObjStep = struct { source_duped.addStepDependencies(&self.step); } - pub fn addObjectFile(self: *LibExeObjStep, source: FileSource) void { + pub fn addObjectFile(self: *LibExeObjStep, source_file: []const u8) void { + self.addObjectFileSource(.{ .path = source_file }); + } + + pub fn addObjectFileSource(self: *LibExeObjStep, source: FileSource) void { self.link_objects.append(LinkObject{ .static_path = source.dupe(self.builder) }) catch unreachable; + source.addStepDependencies(&self.step); } pub fn addObject(self: *LibExeObjStep, obj: *LibExeObjStep) void { @@ -2063,15 +2072,24 @@ pub const LibExeObjStep = struct { } pub fn addPackage(self: *LibExeObjStep, package: Pkg) void { - package.path.addStepDependencies(&self.step); self.packages.append(self.builder.dupePkg(package)) catch unreachable; + self.addRecursiveBuildDeps(package); + } + + fn addRecursiveBuildDeps(self: *LibExeObjStep, package: Pkg) void { + package.path.addStepDependencies(&self.step); + if (package.dependencies) |deps| { + for (deps) |dep| { + self.addRecursiveBuildDeps(dep); + } + } } pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void { - self.packages.append(Pkg{ + self.addPackage(Pkg{ .name = self.builder.dupe(name), .path = .{ .path = self.builder.dupe(pkg_index_path) }, - }) catch unreachable; + }); } /// If Vcpkg was found on the system, it will be added to include and lib @@ -2081,20 +2099,20 @@ pub const LibExeObjStep = struct { // after findVcpkgRoot and have only one switch statement, but the compiler // cannot resolve the error set. switch (self.builder.vcpkg_root) { - .Unattempted => { + .unattempted => { self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root| - VcpkgRoot{ .Found = root } + VcpkgRoot{ .found = root } else - .NotFound; + .not_found; }, - .NotFound => return error.VcpkgNotFound, - .Found => {}, + .not_found => return error.VcpkgNotFound, + .found => {}, } switch (self.builder.vcpkg_root) { - .Unattempted => unreachable, - .NotFound => return error.VcpkgNotFound, - .Found => |root| { + .unattempted => unreachable, + .not_found => return error.VcpkgNotFound, + .found => |root| { const allocator = self.builder.allocator; const triplet = try self.target.vcpkgTriplet(allocator, linkage); defer self.builder.allocator.free(triplet); @@ -2207,7 +2225,7 @@ pub const LibExeObjStep = struct { const full_path_lib = other.getOutputLibPath(); try zig_args.append(full_path_lib); - if (other.is_dynamic and !self.target.isWindows()) { + if (other.linkage == .dynamic and !self.target.isWindows()) { if (fs.path.dirname(full_path_lib)) |dirname| { try zig_args.append("-rpath"); try zig_args.append(dirname); @@ -2373,13 +2391,13 @@ pub const LibExeObjStep = struct { zig_args.append("--name") catch unreachable; zig_args.append(self.name) catch unreachable; - if (self.kind == Kind.Lib and self.is_dynamic) { + if (self.kind == Kind.Lib and self.linkage == .dynamic) { if (self.version) |version| { zig_args.append("--version") catch unreachable; zig_args.append(builder.fmt("{}", .{version})) catch unreachable; } } - if (self.is_dynamic) { + if (self.linkage == .dynamic) { try zig_args.append("-dynamic"); } if (self.bundle_compiler_rt) |x| { @@ -2682,7 +2700,7 @@ pub const LibExeObjStep = struct { } } - if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { + if (self.kind == .Lib and self.linkage == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename.?, self.name_only_filename.?); } } @@ -3033,15 +3051,15 @@ fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 { } const VcpkgRoot = union(VcpkgRootStatus) { - Unattempted: void, - NotFound: void, - Found: []const u8, + unattempted: void, + not_found: void, + found: []const u8, }; const VcpkgRootStatus = enum { - Unattempted, - NotFound, - Found, + unattempted, + not_found, + found, }; pub const VcpkgLinkage = std.builtin.LinkMode; diff --git a/lib/std/build/TranslateCStep.zig b/lib/std/build/TranslateCStep.zig index 49a4070276..2f47e2cf82 100644 --- a/lib/std/build/TranslateCStep.zig +++ b/lib/std/build/TranslateCStep.zig @@ -63,7 +63,7 @@ pub fn setTarget(self: *TranslateCStep, target: CrossTarget) void { /// Creates a step to build an executable from the translated source. pub fn addExecutable(self: *TranslateCStep) *LibExeObjStep { - return self.builder.addExecutableSource("translated_c", build.FileSource{ .generated = &self.output_file }, false); + return self.builder.addExecutableSource("translated_c", build.FileSource{ .generated = &self.output_file }, .static); } pub fn addIncludeDir(self: *TranslateCStep, include_dir: []const u8) void { diff --git a/lib/std/build/WriteFileStep.zig b/lib/std/build/WriteFileStep.zig index a33386a4b9..b26113385d 100644 --- a/lib/std/build/WriteFileStep.zig +++ b/lib/std/build/WriteFileStep.zig @@ -48,10 +48,7 @@ pub fn add(self: *WriteFileStep, basename: []const u8, bytes: []const u8) void { self.files.append(node); } -/// Unless setOutputDir was called, this function must be called only in -/// the make step, from a step that has declared a dependency on this one. -/// To run an executable built with zig build, use `run`, or create an install step and invoke it. -//pub const getOutputPath = @compileError("WriteFileStep.getOutputPath is deprecated! Use getFileSource to retrieve a "); + /// Gets a file source for the given basename. If the file does not exist, returns `null`. pub fn getFileSource(step: *WriteFileStep, basename: []const u8) ?build.FileSource { var it = step.files.first; diff --git a/test/src/compare_output.zig b/test/src/compare_output.zig index 1cde470887..a99b3e0d40 100644 --- a/test/src/compare_output.zig +++ b/test/src/compare_output.zig @@ -105,7 +105,7 @@ pub const CompareOutputContext = struct { } const exe = b.addExecutable("test", null); - exe.addAssemblyFileFromWriteFileStep(write_src, case.sources.items[0].filename); + exe.addAssemblyFileSource(write_src.getFileSource(case.sources.items[0].filename).?); const run = exe.run(); run.addArgs(case.cli_args); @@ -126,7 +126,7 @@ pub const CompareOutputContext = struct { } const basename = case.sources.items[0].filename; - const exe = b.addExecutableFromWriteFileStep("test", write_src, basename); + const exe = b.addExecutableSource("test", write_src.getFileSource(basename).?, false); exe.setBuildMode(mode); if (case.link_libc) { exe.linkSystemLibrary("c"); @@ -147,7 +147,7 @@ pub const CompareOutputContext = struct { } const basename = case.sources.items[0].filename; - const exe = b.addExecutableFromWriteFileStep("test", write_src, basename); + const exe = b.addExecutableSource("test", write_src.getFileSource(basename).?, false); if (case.link_libc) { exe.linkSystemLibrary("c"); } diff --git a/test/src/run_translated_c.zig b/test/src/run_translated_c.zig index 1de329112c..4605cea7ae 100644 --- a/test/src/run_translated_c.zig +++ b/test/src/run_translated_c.zig @@ -86,12 +86,8 @@ pub const RunTranslatedCContext = struct { for (case.sources.items) |src_file| { write_src.add(src_file.filename, src_file.source); } - const translate_c = b.addTranslateC(.{ - .write_file = .{ - .step = write_src, - .basename = case.sources.items[0].filename, - }, - }); + const translate_c = b.addTranslateC(write_src.getFileSource(case.sources.items[0].filename).?); + translate_c.step.name = b.fmt("{s} translate-c", .{annotated_case_name}); const exe = translate_c.addExecutable(); exe.setTarget(self.target); diff --git a/test/src/translate_c.zig b/test/src/translate_c.zig index c43f326926..b79becbf8d 100644 --- a/test/src/translate_c.zig +++ b/test/src/translate_c.zig @@ -109,12 +109,8 @@ pub const TranslateCContext = struct { write_src.add(src_file.filename, src_file.source); } - const translate_c = b.addTranslateC(.{ - .write_file = .{ - .step = write_src, - .basename = case.sources.items[0].filename, - }, - }); + const translate_c = b.addTranslateC(write_src.getFileSource(case.sources.items[0].filename).?); + translate_c.step.name = annotated_case_name; translate_c.setTarget(case.target); diff --git a/test/tests.zig b/test/tests.zig index 63b851e90b..8fe31a6127 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -107,6 +107,7 @@ const test_targets = blk: { .link_libc = true, }, + TestTarget{ .target = .{ .cpu_arch = .aarch64, @@ -227,6 +228,7 @@ const test_targets = blk: { .link_libc = true, }, + TestTarget{ .target = .{ .cpu_arch = .riscv64, @@ -654,7 +656,7 @@ pub const StackTracesContext = struct { const b = self.b; const src_basename = "source.zig"; const write_src = b.addWriteFile(src_basename, source); - const exe = b.addExecutableFromWriteFileStep("test", write_src, src_basename); + const exe = b.addExecutableSource("test", write_src.getFileSource(src_basename).?, false); exe.setBuildMode(mode); const run_and_compare = RunAndCompareStep.create( @@ -668,6 +670,7 @@ pub const StackTracesContext = struct { self.step.dependOn(&run_and_compare.step); } + const RunAndCompareStep = struct { step: build.Step, context: *StackTracesContext, @@ -776,6 +779,7 @@ pub const StackTracesContext = struct { var it = mem.split(stderr, "\n"); process_lines: while (it.next()) |line| { if (line.len == 0) continue; + // offset search past `[drive]:` on windows var pos: usize = if (std.Target.current.os.tag == .windows) 2 else 0; // locate delims/anchor @@ -935,7 +939,7 @@ pub const CompileErrorContext = struct { try zig_args.append("build-obj"); } const root_src_basename = self.case.sources.items[0].filename; - try zig_args.append(self.write_src.getOutputPath(root_src_basename)); + try zig_args.append(self.write_src.getFileSource(root_src_basename).?.getPath(b)); zig_args.append("--name") catch unreachable; zig_args.append("test") catch unreachable; @@ -1368,4 +1372,4 @@ fn printInvocation(args: []const []const u8) void { warn("{s} ", .{arg}); } warn("\n", .{}); -} +} \ No newline at end of file