From 142471fcc46070326526e3976f0150fe734df0b6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 2 Dec 2023 21:51:34 -0700 Subject: [PATCH] zig build system: change target, compilation, and module APIs Introduce the concept of "target query" and "resolved target". A target query is what the user specifies, with some things left to default. A resolved target has the default things discovered and populated. In the future, std.zig.CrossTarget will be rename to std.Target.Query. Introduces `std.Build.resolveTargetQuery` to get from one to the other. The concept of `main_mod_path` is gone, no longer supported. You have to put the root source file at the module root now. * remove deprecated API * update build.zig for the breaking API changes in this branch * move std.Build.Step.Compile.BuildId to std.zig.BuildId * add more options to std.Build.ExecutableOptions, std.Build.ObjectOptions, std.Build.SharedLibraryOptions, std.Build.StaticLibraryOptions, and std.Build.TestOptions. * remove `std.Build.constructCMacro`. There is no use for this API. * deprecate `std.Build.Step.Compile.defineCMacro`. Instead, `std.Build.Module.addCMacro` is provided. - remove `std.Build.Step.Compile.defineCMacroRaw`. * deprecate `std.Build.Step.Compile.linkFrameworkNeeded` - use `std.Build.Module.linkFramework` * deprecate `std.Build.Step.Compile.linkFrameworkWeak` - use `std.Build.Module.linkFramework` * move more logic into `std.Build.Module` * allow `target` and `optimize` to be `null` when creating a Module. Along with other fields, those unspecified options will be inherited from parent `Module` when inserted into an import table. * the `target` field of `addExecutable` is now required. pass `b.host` to get the host target. --- build.zig | 92 +- deps/aro/build/GenerateDef.zig | 4 +- lib/build_runner.zig | 7 +- lib/std/Build.zig | 177 ++- lib/std/Build/Cache.zig | 2 +- lib/std/Build/Module.zig | 347 ++++-- lib/std/Build/Step/CheckObject.zig | 48 +- lib/std/Build/Step/Compile.zig | 284 ++--- lib/std/Build/Step/ConfigHeader.zig | 6 - lib/std/Build/Step/InstallArtifact.zig | 2 +- lib/std/Build/Step/Options.zig | 6 +- lib/std/Build/Step/Run.zig | 27 +- lib/std/Build/Step/TranslateC.zig | 11 +- lib/std/Build/Step/WriteFile.zig | 7 - lib/std/std.zig | 3 - lib/std/zig.zig | 77 ++ lib/std/zig/CrossTarget.zig | 4 - lib/std/zig/system/NativeTargetInfo.zig | 4 +- src/Compilation.zig | 3 +- src/link.zig | 3 +- src/main.zig | 7 +- test/behavior/eval.zig | 20 +- test/cases.zig | 10 +- test/cbe.zig | 46 +- test/compile_errors.zig | 22 +- test/link/bss/build.zig | 1 + test/link/common_symbols/build.zig | 2 +- test/link/common_symbols_alignment/build.zig | 2 +- test/link/elf.zig | 1093 ++++++++++------- test/link/glibc_compat/build.zig | 4 +- .../interdependent_static_c_libs/build.zig | 4 +- test/link/link.zig | 175 ++- test/link/macho.zig | 59 +- test/link/macho/bugs/13056/build.zig | 6 +- test/link/macho/bugs/13457/build.zig | 2 +- test/link/macho/bugs/16308/build.zig | 2 +- test/link/macho/bugs/16628/build.zig | 2 +- test/link/macho/dead_strip/build.zig | 4 +- test/link/macho/dead_strip_dylibs/build.zig | 1 + test/link/macho/dylib/build.zig | 4 +- test/link/macho/empty/build.zig | 2 +- test/link/macho/entry/build.zig | 2 +- test/link/macho/entry_in_archive/build.zig | 4 +- test/link/macho/entry_in_dylib/build.zig | 4 +- test/link/macho/headerpad/build.zig | 1 + test/link/macho/linksection/build.zig | 2 +- test/link/macho/needed_framework/build.zig | 1 + test/link/macho/needed_library/build.zig | 4 +- test/link/macho/objc/build.zig | 1 + test/link/macho/objcpp/build.zig | 1 + test/link/macho/pagezero/build.zig | 2 +- test/link/macho/reexports/build.zig | 2 +- test/link/macho/search_strategy/build.zig | 6 +- test/link/macho/stack_size/build.zig | 2 +- test/link/macho/strict_validation/build.zig | 2 +- test/link/macho/tbdv3/build.zig | 2 +- test/link/macho/tls/build.zig | 2 +- test/link/macho/unwind_info/build.zig | 6 +- test/link/macho/weak_framework/build.zig | 1 + test/link/macho/weak_library/build.zig | 4 +- .../static_libs_from_object_files/build.zig | 14 +- test/link/wasm/archive/build.zig | 2 +- test/link/wasm/basic-features/build.zig | 4 +- test/link/wasm/bss/build.zig | 8 +- test/link/wasm/export-data/build.zig | 2 +- test/link/wasm/export/build.zig | 8 +- test/link/wasm/extern-mangle/build.zig | 2 +- test/link/wasm/extern/build.zig | 2 +- test/link/wasm/function-table/build.zig | 6 +- test/link/wasm/infer-features/build.zig | 8 +- test/link/wasm/producers/build.zig | 4 +- test/link/wasm/segments/build.zig | 4 +- test/link/wasm/shared-memory/build.zig | 6 +- test/link/wasm/stack_pointer/build.zig | 4 +- test/link/wasm/type/build.zig | 4 +- test/llvm_targets.zig | 12 +- test/nvptx.zig | 27 +- test/src/Cases.zig | 109 +- test/src/CompareOutput.zig | 6 +- test/src/StackTrace.zig | 2 +- test/src/run_translated_c.zig | 4 +- test/src/translate_c.zig | 4 +- test/standalone.zig | 4 - test/standalone/c_compiler/build.zig | 4 +- test/standalone/child_process/build.zig | 2 +- test/standalone/compiler_rt_panic/build.zig | 8 +- test/standalone/dep_diamond/build.zig | 15 +- .../dep_mutually_recursive/build.zig | 11 +- test/standalone/dep_recursive/build.zig | 7 +- test/standalone/dep_shared_builtin/build.zig | 5 +- test/standalone/dep_triangle/build.zig | 11 +- .../standalone/embed_generated_file/build.zig | 8 +- test/standalone/empty_env/build.zig | 1 + test/standalone/extern/build.zig | 2 +- test/standalone/global_linkage/build.zig | 2 +- test/standalone/install_raw_hex/build.zig | 4 +- test/standalone/ios/build.zig | 8 +- test/standalone/issue_11595/build.zig | 2 +- test/standalone/issue_12588/build.zig | 3 +- test/standalone/issue_12706/build.zig | 3 +- test/standalone/issue_339/build.zig | 2 +- test/standalone/issue_8550/build.zig | 4 +- .../standalone/load_dynamic_library/build.zig | 2 +- test/standalone/main_pkg_path/a/test.zig | 5 - test/standalone/main_pkg_path/b.zig | 1 - test/standalone/main_pkg_path/build.zig | 13 - test/standalone/mix_c_files/build.zig | 1 + test/standalone/mix_o_files/build.zig | 2 +- test/standalone/options/build.zig | 2 +- test/standalone/pie/build.zig | 4 +- test/standalone/pkg_import/build.zig | 3 +- test/standalone/self_exe_symlink/build.zig | 4 +- test/standalone/shared_library/build.zig | 2 +- test/standalone/stack_iterator/build.zig | 19 +- test/standalone/static_c_lib/build.zig | 2 +- test/standalone/strip_empty_loop/build.zig | 4 +- test/standalone/strip_struct_init/build.zig | 2 +- .../test_runner_module_imports/build.zig | 8 +- test/standalone/windows_resources/build.zig | 16 +- test/standalone/windows_spawn/build.zig | 2 +- test/standalone/zerolength_check/build.zig | 4 +- test/tests.zig | 69 +- 122 files changed, 1809 insertions(+), 1335 deletions(-) delete mode 100644 test/standalone/main_pkg_path/a/test.zig delete mode 100644 test/standalone/main_pkg_path/b.zig delete mode 100644 test/standalone/main_pkg_path/build.zig diff --git a/build.zig b/build.zig index 11b3006039..bc4c32035c 100644 --- a/build.zig +++ b/build.zig @@ -39,10 +39,10 @@ pub fn build(b: *std.Build) !void { const docgen_exe = b.addExecutable(.{ .name = "docgen", .root_source_file = .{ .path = "tools/docgen.zig" }, - .target = .{}, + .target = b.host, .optimize = .Debug, + .single_threaded = single_threaded, }); - docgen_exe.single_threaded = single_threaded; const docgen_cmd = b.addRunArtifact(docgen_exe); docgen_cmd.addArgs(&.{ "--zig", b.zig_exe }); @@ -89,11 +89,11 @@ pub fn build(b: *std.Build) !void { const check_case_exe = b.addExecutable(.{ .name = "check-case", .root_source_file = .{ .path = "test/src/Cases.zig" }, + .target = b.host, .optimize = optimize, - .main_mod_path = .{ .path = "." }, + .single_threaded = single_threaded, }); check_case_exe.stack_size = stack_size; - check_case_exe.single_threaded = single_threaded; const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false; const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false; @@ -194,14 +194,18 @@ pub fn build(b: *std.Build) !void { break :blk 4; }; - const exe = addCompilerStep(b, optimize, target); - exe.strip = strip; + const exe = addCompilerStep(b, .{ + .optimize = optimize, + .target = target, + .strip = strip, + .sanitize_thread = sanitize_thread, + .single_threaded = single_threaded, + }); exe.pie = pie; - exe.sanitize_thread = sanitize_thread; exe.entitlements = entitlements; exe.build_id = b.option( - std.Build.Step.Compile.BuildId, + std.zig.BuildId, "build-id", "Request creation of '.note.gnu.build-id' section", ); @@ -217,9 +221,7 @@ pub fn build(b: *std.Build) !void { test_step.dependOn(&exe.step); - exe.single_threaded = single_threaded; - - if (target.isWindows() and target.getAbi() == .gnu) { + if (target.target.os.tag == .windows and target.target.abi == .gnu) { // LTO is currently broken on mingw, this can be removed when it's fixed. exe.want_lto = false; check_case_exe.want_lto = false; @@ -230,7 +232,7 @@ pub fn build(b: *std.Build) !void { exe.use_lld = use_llvm; const exe_options = b.addOptions(); - exe.addOptions("build_options", exe_options); + exe.root_module.addOptions("build_options", exe_options); exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames); exe_options.addOption(bool, "skip_non_native", skip_non_native); @@ -345,7 +347,7 @@ pub fn build(b: *std.Build) !void { try addStaticLlvmOptionsToExe(exe); try addStaticLlvmOptionsToExe(check_case_exe); } - if (target.isWindows()) { + if (target.target.os.tag == .windows) { inline for (.{ exe, check_case_exe }) |artifact| { artifact.linkSystemLibrary("version"); artifact.linkSystemLibrary("uuid"); @@ -369,7 +371,7 @@ pub fn build(b: *std.Build) !void { ); // On mingw, we need to opt into windows 7+ to get some features required by tracy. - const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu) + const tracy_c_flags: []const []const u8 = if (target.target.os.tag == .windows and target.target.abi == .gnu) &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" } else &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" }; @@ -377,11 +379,11 @@ pub fn build(b: *std.Build) !void { exe.addIncludePath(.{ .cwd_relative = tracy_path }); exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); if (!enable_llvm) { - exe.linkSystemLibraryName("c++"); + exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no }); } exe.linkLibC(); - if (target.isWindows()) { + if (target.target.os.tag == .windows) { exe.linkSystemLibrary("dbghelp"); exe.linkSystemLibrary("ws2_32"); } @@ -390,7 +392,7 @@ pub fn build(b: *std.Build) !void { const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); const test_cases_options = b.addOptions(); - check_case_exe.addOptions("build_options", test_cases_options); + check_case_exe.root_module.addOptions("build_options", test_cases_options); test_cases_options.addOption(bool, "enable_tracy", false); test_cases_options.addOption(bool, "enable_logging", enable_logging); @@ -540,16 +542,19 @@ pub fn build(b: *std.Build) !void { fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { const semver = try std.SemanticVersion.parse(version); - var target: std.zig.CrossTarget = .{ + var target_query: std.zig.CrossTarget = .{ .cpu_arch = .wasm32, .os_tag = .wasi, }; - target.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory)); + target_query.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory)); - const exe = addCompilerStep(b, .ReleaseSmall, target); + const exe = addCompilerStep(b, .{ + .optimize = .ReleaseSmall, + .target = b.resolveTargetQuery(target_query), + }); const exe_options = b.addOptions(); - exe.addOptions("build_options", exe_options); + exe.root_module.addOptions("build_options", exe_options); exe_options.addOption(u32, "mem_leak_frames", 0); exe_options.addOption(bool, "have_llvm", false); @@ -584,17 +589,24 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void { update_zig1_step.dependOn(©_zig_h.step); } -fn addCompilerStep( - b: *std.Build, +const AddCompilerStepOptions = struct { optimize: std.builtin.OptimizeMode, - target: std.zig.CrossTarget, -) *std.Build.Step.Compile { + target: std.Build.ResolvedTarget, + strip: ?bool = null, + sanitize_thread: ?bool = null, + single_threaded: ?bool = null, +}; + +fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile { const exe = b.addExecutable(.{ .name = "zig", .root_source_file = .{ .path = "src/main.zig" }, - .target = target, - .optimize = optimize, + .target = options.target, + .optimize = options.optimize, .max_rss = 7_000_000_000, + .strip = options.strip, + .sanitize_thread = options.sanitize_thread, + .single_threaded = options.single_threaded, }); exe.stack_size = stack_size; @@ -602,15 +614,15 @@ fn addCompilerStep( aro_options.addOption([]const u8, "version_str", "aro-zig"); const aro_options_module = aro_options.createModule(); const aro_backend = b.createModule(.{ - .source_file = .{ .path = "deps/aro/backend.zig" }, - .dependencies = &.{.{ + .root_source_file = .{ .path = "deps/aro/backend.zig" }, + .imports = &.{.{ .name = "build_options", .module = aro_options_module, }}, }); const aro_module = b.createModule(.{ - .source_file = .{ .path = "deps/aro/aro.zig" }, - .dependencies = &.{ + .root_source_file = .{ .path = "deps/aro/aro.zig" }, + .imports = &.{ .{ .name = "build_options", .module = aro_options_module, @@ -625,7 +637,7 @@ fn addCompilerStep( }, }); - exe.addModule("aro", aro_module); + exe.root_module.addImport("aro", aro_module); return exe; } @@ -649,7 +661,7 @@ fn addCmakeCfgOptionsToExe( exe: *std.Build.Step.Compile, use_zig_libcxx: bool, ) !void { - if (exe.target.isDarwin()) { + if (exe.rootModuleTarget().isDarwin()) { // useful for package maintainers exe.headerpad_max_install_names = true; } @@ -677,8 +689,8 @@ fn addCmakeCfgOptionsToExe( // against system-provided LLVM, Clang, LLD. const need_cpp_includes = true; const static = cfg.llvm_linkage == .static; - const lib_suffix = if (static) exe.target.staticLibSuffix()[1..] else exe.target.dynamicLibSuffix()[1..]; - switch (exe.target.getOsTag()) { + const lib_suffix = if (static) exe.rootModuleTarget().staticLibSuffix()[1..] else exe.rootModuleTarget().dynamicLibSuffix()[1..]; + switch (exe.rootModuleTarget().os.tag) { .linux => { // First we try to link against the detected libcxx name. If that doesn't work, we fall // back to -lc++ and cross our fingers. @@ -694,7 +706,7 @@ fn addCmakeCfgOptionsToExe( exe.linkLibCpp(); }, .windows => { - if (exe.target.getAbi() != .msvc) exe.linkLibCpp(); + if (exe.rootModuleTarget().abi != .msvc) exe.linkLibCpp(); }, .freebsd => { if (static) { @@ -756,12 +768,12 @@ fn addStaticLlvmOptionsToExe(exe: *std.Build.Step.Compile) !void { exe.linkSystemLibrary("z"); exe.linkSystemLibrary("zstd"); - if (exe.target.getOs().tag != .windows or exe.target.getAbi() != .msvc) { + if (exe.rootModuleTarget().os.tag != .windows or exe.rootModuleTarget().abi != .msvc) { // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries. exe.linkSystemLibrary("c++"); } - if (exe.target.getOs().tag == .windows) { + if (exe.rootModuleTarget().os.tag == .windows) { exe.linkSystemLibrary("version"); exe.linkSystemLibrary("uuid"); exe.linkSystemLibrary("ole32"); @@ -810,7 +822,9 @@ fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void { while (it.next()) |lib| { if (mem.startsWith(u8, lib, "-l")) { exe.linkSystemLibrary(lib["-l".len..]); - } else if (exe.target.isWindows() and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) { + } else if (exe.rootModuleTarget().os.tag == .windows and + mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) + { exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]); } else { exe.addObjectFile(.{ .cwd_relative = lib }); diff --git a/deps/aro/build/GenerateDef.zig b/deps/aro/build/GenerateDef.zig index 129d65ebdf..5c0f8d4b18 100644 --- a/deps/aro/build/GenerateDef.zig +++ b/deps/aro/build/GenerateDef.zig @@ -21,7 +21,7 @@ pub const Options = struct { pub const Kind = enum { dafsa, named }; }; -pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency { +pub fn create(owner: *std.Build, options: Options) std.Build.Module.Import { const self = owner.allocator.create(GenerateDef) catch @panic("OOM"); const path = owner.pathJoin(&.{ options.src_prefix, options.name }); @@ -39,7 +39,7 @@ pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency { .generated_file = .{ .step = &self.step }, }; const module = self.step.owner.createModule(.{ - .source_file = .{ .generated = &self.generated_file }, + .root_source_file = .{ .generated = &self.generated_file }, }); return .{ .module = module, diff --git a/lib/build_runner.zig b/lib/build_runner.zig index a5e537c43c..fba1c90d71 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -46,7 +46,12 @@ pub fn main() !void { return error.InvalidArgs; }; - const host = try std.zig.system.NativeTargetInfo.detect(.{}); + const detected = try std.zig.system.NativeTargetInfo.detect(.{}); + const host: std.Build.ResolvedTarget = .{ + .query = .{}, + .target = detected.target, + .dynamic_linker = detected.dynamic_linker, + }; const build_root_directory: std.Build.Cache.Directory = .{ .path = build_root, diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 8726feb7c1..666a1ec15b 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -14,20 +14,11 @@ const process = std.process; const EnvMap = std.process.EnvMap; const fmt_lib = std.fmt; const File = std.fs.File; -const CrossTarget = std.zig.CrossTarget; -const NativeTargetInfo = std.zig.system.NativeTargetInfo; +const TargetQuery = std.zig.CrossTarget; const Sha256 = std.crypto.hash.sha2.Sha256; const Build = @This(); pub const Cache = @import("Build/Cache.zig"); - -/// deprecated: use `Step.Compile`. -pub const LibExeObjStep = Step.Compile; -/// deprecated: use `Build`. -pub const Builder = Build; -/// deprecated: use `Step.InstallDir.Options` -pub const InstallDirectoryOptions = Step.InstallDir.Options; - pub const Step = @import("Build/Step.zig"); pub const Module = @import("Build/Module.zig"); @@ -94,7 +85,7 @@ enable_wine: bool = false, glibc_runtimes_dir: ?[]const u8 = null, /// Information about the native target. Computed before build() is invoked. -host: NativeTargetInfo, +host: ResolvedTarget, dep_prefix: []const u8 = "", @@ -220,7 +211,7 @@ pub fn create( build_root: Cache.Directory, cache_root: Cache.Directory, global_cache_root: Cache.Directory, - host: NativeTargetInfo, + host: ResolvedTarget, cache: *Cache, available_deps: AvailableDeps, ) !*Build { @@ -384,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption const v = @field(args, field.name); const T = @TypeOf(v); switch (T) { - CrossTarget => { + TargetQuery => { user_input_options.put(field.name, .{ .name = field.name, .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") }, @@ -593,14 +584,22 @@ pub fn addOptions(self: *Build) *Step.Options { pub const ExecutableOptions = struct { name: []const u8, + /// If you want the executable to run on the same computer as the one + /// building the package, pass the `host` field of the package's `Build` + /// instance. + target: ResolvedTarget, root_source_file: ?LazyPath = null, version: ?std.SemanticVersion = null, - target: CrossTarget = .{}, optimize: std.builtin.OptimizeMode = .Debug, linkage: ?Step.Compile.Linkage = null, max_rss: usize = 0, link_libc: ?bool = null, single_threaded: ?bool = null, + pic: ?bool = null, + strip: ?bool = null, + unwind_tables: ?bool = null, + omit_frame_pointer: ?bool = null, + sanitize_thread: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -621,6 +620,11 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { .optimize = options.optimize, .link_libc = options.link_libc, .single_threaded = options.single_threaded, + .pic = options.pic, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .omit_frame_pointer = options.omit_frame_pointer, + .sanitize_thread = options.sanitize_thread, }, .version = options.version, .kind = .exe, @@ -636,11 +640,18 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { pub const ObjectOptions = struct { name: []const u8, root_source_file: ?LazyPath = null, - target: CrossTarget, + /// To choose the same computer as the one building the package, pass the + /// `host` field of the package's `Build` instance. + target: ResolvedTarget, optimize: std.builtin.OptimizeMode, max_rss: usize = 0, link_libc: ?bool = null, single_threaded: ?bool = null, + pic: ?bool = null, + strip: ?bool = null, + unwind_tables: ?bool = null, + omit_frame_pointer: ?bool = null, + sanitize_thread: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -655,6 +666,11 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile { .optimize = options.optimize, .link_libc = options.link_libc, .single_threaded = options.single_threaded, + .pic = options.pic, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .omit_frame_pointer = options.omit_frame_pointer, + .sanitize_thread = options.sanitize_thread, }, .kind = .obj, .max_rss = options.max_rss, @@ -666,13 +682,20 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile { pub const SharedLibraryOptions = struct { name: []const u8, + /// To choose the same computer as the one building the package, pass the + /// `host` field of the package's `Build` instance. + target: ResolvedTarget, + optimize: std.builtin.OptimizeMode, root_source_file: ?LazyPath = null, version: ?std.SemanticVersion = null, - target: CrossTarget, - optimize: std.builtin.OptimizeMode, max_rss: usize = 0, link_libc: ?bool = null, single_threaded: ?bool = null, + pic: ?bool = null, + strip: ?bool = null, + unwind_tables: ?bool = null, + omit_frame_pointer: ?bool = null, + sanitize_thread: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -693,6 +716,11 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile .root_source_file = options.root_source_file, .link_libc = options.link_libc, .single_threaded = options.single_threaded, + .pic = options.pic, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .omit_frame_pointer = options.omit_frame_pointer, + .sanitize_thread = options.sanitize_thread, }, .kind = .lib, .linkage = .dynamic, @@ -708,12 +736,19 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile pub const StaticLibraryOptions = struct { name: []const u8, root_source_file: ?LazyPath = null, - target: CrossTarget, + /// To choose the same computer as the one building the package, pass the + /// `host` field of the package's `Build` instance. + target: ResolvedTarget, optimize: std.builtin.OptimizeMode, version: ?std.SemanticVersion = null, max_rss: usize = 0, link_libc: ?bool = null, single_threaded: ?bool = null, + pic: ?bool = null, + strip: ?bool = null, + unwind_tables: ?bool = null, + omit_frame_pointer: ?bool = null, + sanitize_thread: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -728,6 +763,11 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile .root_source_file = options.root_source_file, .link_libc = options.link_libc, .single_threaded = options.single_threaded, + .pic = options.pic, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .omit_frame_pointer = options.omit_frame_pointer, + .sanitize_thread = options.sanitize_thread, }, .kind = .lib, .linkage = .static, @@ -742,7 +782,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile pub const TestOptions = struct { name: []const u8 = "test", root_source_file: LazyPath, - target: CrossTarget = .{}, + target: ?ResolvedTarget = null, optimize: std.builtin.OptimizeMode = .Debug, version: ?std.SemanticVersion = null, max_rss: usize = 0, @@ -750,6 +790,11 @@ pub const TestOptions = struct { test_runner: ?[]const u8 = null, link_libc: ?bool = null, single_threaded: ?bool = null, + pic: ?bool = null, + strip: ?bool = null, + unwind_tables: ?bool = null, + omit_frame_pointer: ?bool = null, + sanitize_thread: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -761,10 +806,15 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { .kind = .@"test", .root_module = .{ .root_source_file = options.root_source_file, - .target = options.target, + .target = options.target orelse b.host, .optimize = options.optimize, .link_libc = options.link_libc, .single_threaded = options.single_threaded, + .pic = options.pic, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .omit_frame_pointer = options.omit_frame_pointer, + .sanitize_thread = options.sanitize_thread, }, .max_rss = options.max_rss, .filter = options.filter, @@ -778,7 +828,9 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { pub const AssemblyOptions = struct { name: []const u8, source_file: LazyPath, - target: CrossTarget, + /// To choose the same computer as the one building the package, pass the + /// `host` field of the package's `Build` instance. + target: ResolvedTarget, optimize: std.builtin.OptimizeMode, max_rss: usize = 0, zig_lib_dir: ?LazyPath = null, @@ -1061,7 +1113,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_ return null; }, .scalar => |s| { - if (Step.Compile.BuildId.parse(s)) |build_id| { + if (std.zig.BuildId.parse(s)) |build_id| { return build_id; } else |err| { log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) }); @@ -1126,13 +1178,20 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio } pub const StandardTargetOptionsArgs = struct { - whitelist: ?[]const CrossTarget = null, + whitelist: ?[]const TargetQuery = null, - default_target: CrossTarget = CrossTarget{}, + default_target: TargetQuery = .{}, }; +/// Exposes standard `zig build` options for choosing a target and additionally +/// resolves the target query. +pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) ResolvedTarget { + const query = b.standardTargetOptionsQueryOnly(args); + return b.resolveTargetQuery(query); +} + /// Exposes standard `zig build` options for choosing a target. -pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) CrossTarget { +pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) TargetQuery { const maybe_triple = self.option( []const u8, "target", @@ -1146,8 +1205,8 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros const triple = maybe_triple orelse "native"; - var diags: CrossTarget.ParseOptions.Diagnostics = .{}; - const selected_target = CrossTarget.parse(.{ + var diags: TargetQuery.ParseOptions.Diagnostics = .{}; + const selected_target = TargetQuery.parse(.{ .arch_os_abi = triple, .cpu_features = mcpu, .diagnostics = &diags, @@ -1203,7 +1262,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros // Make sure it's a match of one of the list. var mismatch_triple = true; var mismatch_cpu_features = true; - var whitelist_item = CrossTarget{}; + var whitelist_item: TargetQuery = .{}; for (list) |t| { mismatch_cpu_features = true; mismatch_triple = true; @@ -1340,7 +1399,7 @@ pub fn addUserInputFlag(self: *Build, name_raw: []const u8) !bool { fn typeToEnum(comptime T: type) TypeId { return switch (T) { - Step.Compile.BuildId => .build_id, + std.zig.BuildId => .build_id, else => return switch (@typeInfo(T)) { .Int => .int, .Float => .float, @@ -1408,7 +1467,7 @@ pub fn installFile(self: *Build, src_path: []const u8, dest_rel_path: []const u8 self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .prefix, dest_rel_path).step); } -pub fn installDirectory(self: *Build, options: InstallDirectoryOptions) void { +pub fn installDirectory(self: *Build, options: Step.InstallDir.Options) void { self.getInstallStep().dependOn(&self.addInstallDirectory(options).step); } @@ -1454,7 +1513,7 @@ pub fn addInstallFileWithDir( return Step.InstallFile.create(self, source.dupe(self), install_dir, dest_rel_path); } -pub fn addInstallDirectory(self: *Build, options: InstallDirectoryOptions) *Step.InstallDir { +pub fn addInstallDirectory(self: *Build, options: Step.InstallDir.Options) *Step.InstallDir { return Step.InstallDir.create(self, options); } @@ -1511,7 +1570,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 { pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 { // TODO report error for ambiguous situations - const exe_extension = @as(CrossTarget, .{}).exeFileExt(); + const exe_extension = @as(TargetQuery, .{}).exeFileExt(); for (self.search_prefixes.items) |search_prefix| { for (names) |name| { if (fs.path.isAbsolute(name)) { @@ -1957,22 +2016,6 @@ pub fn dumpBadGetPathHelp( tty_config.setColor(w, .reset) catch {}; } -/// Allocates a new string for assigning a value to a named macro. -/// If the value is omitted, it is set to 1. -/// `name` and `value` need not live longer than the function call. -pub fn constructCMacro(allocator: Allocator, name: []const u8, value: ?[]const u8) []const u8 { - var macro = allocator.alloc( - u8, - name.len + if (value) |value_slice| value_slice.len + 1 else 0, - ) catch |err| if (err == error.OutOfMemory) @panic("Out of memory") else unreachable; - @memcpy(macro[0..name.len], name); - if (value) |value_slice| { - macro[name.len] = '='; - @memcpy(macro[name.len + 1 ..][0..value_slice.len], value_slice); - } - return macro; -} - pub const InstallDir = union(enum) { prefix: void, lib: void, @@ -2062,6 +2105,44 @@ pub fn hex64(x: u64) [16]u8 { return result; } +/// A pair of target query and fully resolved target. +/// This type is generally required by build system API that need to be given a +/// target. The query is kept because the Zig toolchain needs to know which parts +/// of the target are "native". This can apply to the CPU, the OS, or even the ABI. +pub const ResolvedTarget = struct { + query: TargetQuery, + target: std.Target, + dynamic_linker: std.Target.DynamicLinker, + + pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo { + return .{ + .target = self.target, + .dynamic_linker = self.dynamic_linker, + }; + } +}; + +/// Converts a target query into a fully resolved target that can be passed to +/// various parts of the API. +pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget { + // This context will likely be required in the future when the target is + // resolved via a WASI API or via the build protocol. + _ = b; + + const result = std.zig.system.NativeTargetInfo.detect(query) catch + @panic("unable to resolve target query"); + + return .{ + .query = query, + .target = result.target, + .dynamic_linker = result.dynamic_linker, + }; +} + +pub fn wantSharedLibSymLinks(target: std.Target) bool { + return target.os.tag != .windows; +} + test { _ = Cache; _ = Step; diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 283a3d1f5f..b7865e730b 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -270,7 +270,7 @@ pub const HashHelper = struct { .none => {}, } }, - std.Build.Step.Compile.BuildId => switch (x) { + std.zig.BuildId => switch (x) { .none, .fast, .uuid, .sha1, .md5 => hh.add(std.meta.activeTag(x)), .hexstring => |hex_string| hh.addBytes(hex_string.toSlice()), }, diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig index 31db0ad689..c672ae6c2e 100644 --- a/lib/std/Build/Module.zig +++ b/lib/std/Build/Module.zig @@ -3,27 +3,24 @@ owner: *std.Build, /// Tracks the set of steps that depend on this `Module`. This ensures that /// when making this `Module` depend on other `Module` objects and `Step` /// objects, respective `Step` dependencies can be added. -depending_steps: std.AutoArrayHashMapUnmanaged(*std.Build.Step.Compile, void), -/// This could either be a generated file, in which case the module -/// contains exactly one file, or it could be a path to the root source -/// file of directory of files which constitute the module. -/// If `null`, it means this module is made up of only `link_objects`. +depending_steps: std.AutoArrayHashMapUnmanaged(*Step.Compile, void), root_source_file: ?LazyPath, /// The modules that are mapped into this module's import table. -import_table: std.StringArrayHashMap(*Module), +/// Use `addImport` rather than modifying this field directly in order to +/// maintain step dependency edges. +import_table: std.StringArrayHashMapUnmanaged(*Module), -target: std.zig.CrossTarget, -target_info: NativeTargetInfo, -optimize: std.builtin.OptimizeMode, +target: ?std.Build.ResolvedTarget = null, +optimize: ?std.builtin.OptimizeMode = null, dwarf_format: ?std.dwarf.Format, -c_macros: std.ArrayList([]const u8), -include_dirs: std.ArrayList(IncludeDir), -lib_paths: std.ArrayList(LazyPath), -rpaths: std.ArrayList(LazyPath), -frameworks: std.StringArrayHashMapUnmanaged(FrameworkLinkInfo), +c_macros: std.ArrayListUnmanaged([]const u8), +include_dirs: std.ArrayListUnmanaged(IncludeDir), +lib_paths: std.ArrayListUnmanaged(LazyPath), +rpaths: std.ArrayListUnmanaged(RPath), +frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions), c_std: std.Build.CStd, -link_objects: std.ArrayList(LinkObject), +link_objects: std.ArrayListUnmanaged(LinkObject), strip: ?bool, unwind_tables: ?bool, @@ -53,9 +50,14 @@ link_libcpp: ?bool, /// Symbols to be exported when compiling to WebAssembly. export_symbol_names: []const []const u8 = &.{}, +pub const RPath = union(enum) { + lazy_path: LazyPath, + special: []const u8, +}; + pub const LinkObject = union(enum) { static_path: LazyPath, - other_step: *std.Build.Step.Compile, + other_step: *Step.Compile, system_lib: SystemLib, assembly_file: LazyPath, c_source_file: *CSourceFile, @@ -133,21 +135,32 @@ pub const IncludeDir = union(enum) { path_after: LazyPath, framework_path: LazyPath, framework_path_system: LazyPath, - other_step: *std.Build.Step.Compile, - config_header_step: *std.Build.Step.ConfigHeader, + other_step: *Step.Compile, + config_header_step: *Step.ConfigHeader, }; -pub const FrameworkLinkInfo = struct { +pub const LinkFrameworkOptions = struct { needed: bool = false, weak: bool = false, }; +/// Unspecified options here will be inherited from parent `Module` when +/// inserted into an import table. pub const CreateOptions = struct { - target: std.zig.CrossTarget, - target_info: ?NativeTargetInfo = null, - optimize: std.builtin.OptimizeMode, + /// This could either be a generated file, in which case the module + /// contains exactly one file, or it could be a path to the root source + /// file of directory of files which constitute the module. + /// If `null`, it means this module is made up of only `link_objects`. root_source_file: ?LazyPath = null, - import_table: []const Import = &.{}, + + /// The table of other modules that this module can access via `@import`. + /// Imports are allowed to be cyclical, so this table can be added to after + /// the `Module` is created via `addImport`. + imports: []const Import = &.{}, + + target: ?std.Build.ResolvedTarget = null, + optimize: ?std.builtin.OptimizeMode = null, + link_libc: ?bool = null, link_libcpp: ?bool = null, single_threaded: ?bool = null, @@ -173,26 +186,26 @@ pub const Import = struct { module: *Module, }; -pub fn init(owner: *std.Build, options: CreateOptions, compile: ?*std.Build.Step.Compile) Module { - var m: Module = .{ +pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*Step.Compile) void { + const allocator = owner.allocator; + + m.* = .{ .owner = owner, .depending_steps = .{}, .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null, - .import_table = std.StringArrayHashMap(*Module).init(owner.allocator), + .import_table = .{}, .target = options.target, - .target_info = options.target_info orelse - NativeTargetInfo.detect(options.target) catch @panic("unhandled error"), .optimize = options.optimize, .link_libc = options.link_libc, .link_libcpp = options.link_libcpp, .dwarf_format = options.dwarf_format, - .c_macros = std.ArrayList([]const u8).init(owner.allocator), - .include_dirs = std.ArrayList(IncludeDir).init(owner.allocator), - .lib_paths = std.ArrayList(LazyPath).init(owner.allocator), - .rpaths = std.ArrayList(LazyPath).init(owner.allocator), + .c_macros = .{}, + .include_dirs = .{}, + .lib_paths = .{}, + .rpaths = .{}, .frameworks = .{}, .c_std = options.c_std, - .link_objects = std.ArrayList(LinkObject).init(owner.allocator), + .link_objects = .{}, .strip = options.strip, .unwind_tables = options.unwind_tables, .single_threaded = options.single_threaded, @@ -208,31 +221,30 @@ pub fn init(owner: *std.Build, options: CreateOptions, compile: ?*std.Build.Step .export_symbol_names = &.{}, }; - if (compile) |c| { - m.depending_steps.put(owner.allocator, c, {}) catch @panic("OOM"); - } - - m.import_table.ensureUnusedCapacity(options.import_table.len) catch @panic("OOM"); - for (options.import_table) |dep| { + m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM"); + for (options.imports) |dep| { m.import_table.putAssumeCapacity(dep.name, dep.module); } - var it = m.iterateDependencies(null); - while (it.next()) |item| addShallowDependencies(&m, item.module); + if (compile) |c| { + m.depending_steps.put(allocator, c, {}) catch @panic("OOM"); + } - return m; + // This logic accesses `depending_steps` which was just modified above. + var it = m.iterateDependencies(null); + while (it.next()) |item| addShallowDependencies(m, item.module); } pub fn create(owner: *std.Build, options: CreateOptions) *Module { const m = owner.allocator.create(Module) catch @panic("OOM"); - m.* = init(owner, options, null); + m.init(owner, options, null); return m; } /// Adds an existing module to be used with `@import`. pub fn addImport(m: *Module, name: []const u8, module: *Module) void { const b = m.owner; - m.import_table.put(b.dupe(name), module) catch @panic("OOM"); + m.import_table.put(b.allocator, b.dupe(name), module) catch @panic("OOM"); var it = module.iterateDependencies(null); while (it.next()) |item| addShallowDependencies(m, item.module); @@ -244,7 +256,10 @@ pub fn addImport(m: *Module, name: []const u8, module: *Module) void { fn addShallowDependencies(m: *Module, dependee: *Module) void { if (dependee.root_source_file) |lazy_path| addLazyPathDependencies(m, dependee, lazy_path); for (dependee.lib_paths.items) |lib_path| addLazyPathDependencies(m, dependee, lib_path); - for (dependee.rpaths.items) |rpath| addLazyPathDependencies(m, dependee, rpath); + for (dependee.rpaths.items) |rpath| switch (rpath) { + .lazy_path => |lp| addLazyPathDependencies(m, dependee, lp), + .special => {}, + }; for (dependee.link_objects.items) |link_object| switch (link_object) { .other_step => |compile| addStepDependencies(m, dependee, &compile.step), @@ -277,7 +292,7 @@ fn addLazyPathDependenciesOnly(m: *Module, lazy_path: LazyPath) void { } } -fn addStepDependencies(m: *Module, module: *Module, dependee: *std.Build.Step) void { +fn addStepDependencies(m: *Module, module: *Module, dependee: *Step) void { addStepDependenciesOnly(m, dependee); if (m != module) { for (m.depending_steps.keys()) |compile| { @@ -286,20 +301,19 @@ fn addStepDependencies(m: *Module, module: *Module, dependee: *std.Build.Step) v } } -fn addStepDependenciesOnly(m: *Module, dependee: *std.Build.Step) void { +fn addStepDependenciesOnly(m: *Module, dependee: *Step) void { for (m.depending_steps.keys()) |compile| { compile.step.dependOn(dependee); } } /// Creates a new module and adds it to be used with `@import`. -pub fn addAnonymousImport(m: *Module, name: []const u8, options: std.Build.CreateModuleOptions) void { - const b = m.step.owner; - const module = b.createModule(options); +pub fn addAnonymousImport(m: *Module, name: []const u8, options: CreateOptions) void { + const module = create(m.owner, options); return addImport(m, name, module); } -pub fn addOptions(m: *Module, module_name: []const u8, options: *std.Build.Step.Options) void { +pub fn addOptions(m: *Module, module_name: []const u8, options: *Step.Options) void { addImport(m, module_name, options.createModule()); } @@ -311,14 +325,14 @@ pub const DependencyIterator = struct { pub const Key = struct { /// The compilation that contains the `Module`. Note that a `Module` might be /// used by more than one compilation. - compile: ?*std.Build.Step.Compile, + compile: ?*Step.Compile, module: *Module, }; pub const Item = struct { /// The compilation that contains the `Module`. Note that a `Module` might be /// used by more than one compilation. - compile: ?*std.Build.Step.Compile, + compile: ?*Step.Compile, module: *Module, name: []const u8, }; @@ -368,7 +382,7 @@ pub const DependencyIterator = struct { pub fn iterateDependencies( m: *Module, - chase_steps: ?*std.Build.Step.Compile, + chase_steps: ?*Step.Compile, ) DependencyIterator { var it: DependencyIterator = .{ .allocator = m.owner.allocator, @@ -397,16 +411,18 @@ pub fn linkSystemLibrary( options: LinkSystemLibraryOptions, ) void { const b = m.owner; - if (m.target_info.target.is_libc_lib_name(name)) { + + const target = m.requireKnownTarget(); + if (target.is_libc_lib_name(name)) { m.link_libc = true; return; } - if (m.target_info.target.is_libcpp_lib_name(name)) { + if (target.is_libcpp_lib_name(name)) { m.link_libcpp = true; return; } - m.link_objects.append(.{ + m.link_objects.append(b.allocator, .{ .system_lib = .{ .name = b.dupe(name), .needed = options.needed, @@ -418,6 +434,11 @@ pub fn linkSystemLibrary( }) catch @panic("OOM"); } +pub fn linkFramework(m: *Module, name: []const u8, options: LinkFrameworkOptions) void { + const b = m.owner; + m.frameworks.put(b.allocator, b.dupe(name), options) catch @panic("OOM"); +} + pub const AddCSourceFilesOptions = struct { /// When provided, `files` are relative to `dependency` rather than the /// package that owns the `Compile` step. @@ -428,19 +449,23 @@ pub const AddCSourceFilesOptions = struct { /// Handy when you have many C/C++ source files and want them all to have the same flags. pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void { - const c_source_files = m.owner.allocator.create(CSourceFiles) catch @panic("OOM"); + const b = m.owner; + const allocator = b.allocator; + const c_source_files = allocator.create(CSourceFiles) catch @panic("OOM"); c_source_files.* = .{ .dependency = options.dependency, - .files = m.owner.dupeStrings(options.files), - .flags = m.owner.dupeStrings(options.flags), + .files = b.dupeStrings(options.files), + .flags = b.dupeStrings(options.flags), }; - m.link_objects.append(.{ .c_source_files = c_source_files }) catch @panic("OOM"); + m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM"); } pub fn addCSourceFile(m: *Module, source: CSourceFile) void { - const c_source_file = m.owner.allocator.create(CSourceFile) catch @panic("OOM"); - c_source_file.* = source.dupe(m.owner); - m.link_objects.append(.{ .c_source_file = c_source_file }) catch @panic("OOM"); + const b = m.owner; + const allocator = b.allocator; + const c_source_file = allocator.create(CSourceFile) catch @panic("OOM"); + c_source_file.* = source.dupe(b); + m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM"); addLazyPathDependenciesOnly(m, source.file); } @@ -448,30 +473,122 @@ pub fn addCSourceFile(m: *Module, source: CSourceFile) void { /// Can be called regardless of target. The .rc file will be ignored /// if the target object format does not support embedded resources. pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void { + const b = m.owner; + const allocator = b.allocator; + const target = m.requireKnownTarget(); // Only the PE/COFF format has a Resource Table, so for any other target // the resource file is ignored. - if (m.target_info.target.ofmt != .coff) return; + if (target.ofmt != .coff) return; - const rc_source_file = m.owner.allocator.create(RcSourceFile) catch @panic("OOM"); - rc_source_file.* = source.dupe(m.owner); - m.link_objects.append(.{ .win32_resource_file = rc_source_file }) catch @panic("OOM"); + const rc_source_file = allocator.create(RcSourceFile) catch @panic("OOM"); + rc_source_file.* = source.dupe(b); + m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM"); addLazyPathDependenciesOnly(m, source.file); } pub fn addAssemblyFile(m: *Module, source: LazyPath) void { - m.link_objects.append(.{ .assembly_file = source.dupe(m.owner) }) catch @panic("OOM"); + const b = m.owner; + m.link_objects.append(b.allocator, .{ .assembly_file = source.dupe(b) }) catch @panic("OOM"); addLazyPathDependenciesOnly(m, source); } -pub fn addObjectFile(m: *Module, source: LazyPath) void { - m.link_objects.append(.{ .static_path = source.dupe(m.owner) }) catch @panic("OOM"); - addLazyPathDependencies(m, source); +pub fn addObjectFile(m: *Module, object: LazyPath) void { + const b = m.owner; + m.link_objects.append(b.allocator, .{ .static_path = object.dupe(b) }) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, object); +} + +pub fn addObject(m: *Module, object: *Step.Compile) void { + assert(object.kind == .obj); + m.linkLibraryOrObject(object); +} + +pub fn linkLibrary(m: *Module, library: *Step.Compile) void { + assert(library.kind == .lib); + m.linkLibraryOrObject(library); +} + +pub fn addAfterIncludePath(m: *Module, lazy_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .path_after = lazy_path.dupe(b) }) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, lazy_path); +} + +pub fn addSystemIncludePath(m: *Module, lazy_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .path_system = lazy_path.dupe(b) }) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, lazy_path); +} + +pub fn addIncludePath(m: *Module, lazy_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .path = lazy_path.dupe(b) }) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, lazy_path); +} + +pub fn addConfigHeader(m: *Module, config_header: *Step.ConfigHeader) void { + const allocator = m.owner.allocator; + m.include_dirs.append(allocator, .{ .config_header_step = config_header }) catch @panic("OOM"); + addStepDependenciesOnly(m, &config_header.step); +} + +pub fn addSystemFrameworkPath(m: *Module, directory_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .framework_path_system = directory_path.dupe(b) }) catch + @panic("OOM"); + addLazyPathDependenciesOnly(m, directory_path); +} + +pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void { + const b = m.owner; + m.include_dirs.append(b.allocator, .{ .framework_path = directory_path.dupe(b) }) catch + @panic("OOM"); + addLazyPathDependenciesOnly(m, directory_path); +} + +pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void { + const b = m.owner; + m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, directory_path); +} + +pub fn addRPath(m: *Module, directory_path: LazyPath) void { + const b = m.owner; + switch (directory_path) { + .path, .cwd_relative => |path| { + // TODO: remove this check after people upgrade and stop expecting it to work + if (std.mem.startsWith(u8, path, "@executable_path") or + std.mem.startsWith(u8, path, "@loader_path")) + { + @panic("this function is for adding directory paths. It does not support special rpaths. use addRPathSpecial for that."); + } + }, + else => {}, + } + m.rpaths.append(b.allocator, .{ .lazy_path = directory_path.dupe(b) }) catch @panic("OOM"); + addLazyPathDependenciesOnly(m, directory_path); +} + +pub fn addRPathSpecial(m: *Module, bytes: []const u8) void { + const b = m.owner; + m.rpaths.append(b.allocator, .{ .special = b.dupe(bytes) }) catch @panic("OOM"); +} + +/// Equvialent to the following C code, applied to all C source files owned by +/// this `Module`: +/// ```c +/// #define name value +/// ``` +/// `name` and `value` need not live longer than the function call. +pub fn addCMacro(m: *Module, name: []const u8, value: []const u8) void { + const b = m.owner; + m.c_macros.append(b.allocator, b.fmt("-D{s}={s}", .{ name, value })) catch @panic("OOM"); } pub fn appendZigProcessFlags( m: *Module, zig_args: *std.ArrayList([]const u8), - asking_step: ?*std.Build.Step, + asking_step: ?*Step, ) !void { const b = m.owner; @@ -495,27 +612,30 @@ pub fn appendZigProcessFlags( } try zig_args.ensureUnusedCapacity(1); - switch (m.optimize) { - .Debug => {}, // Skip since it's the default. + if (m.optimize) |optimize| switch (optimize) { + .Debug => zig_args.appendAssumeCapacity("-ODebug"), .ReleaseSmall => zig_args.appendAssumeCapacity("-OReleaseSmall"), .ReleaseFast => zig_args.appendAssumeCapacity("-OReleaseFast"), .ReleaseSafe => zig_args.appendAssumeCapacity("-OReleaseSafe"), - } + }; if (m.code_model != .default) { try zig_args.append("-mcmodel"); try zig_args.append(@tagName(m.code_model)); } - if (!m.target.isNative()) { - try zig_args.appendSlice(&.{ - "-target", try m.target.zigTriple(b.allocator), - "-mcpu", try std.Build.serializeCpu(b.allocator, m.target.getCpu()), - }); + if (m.target) |target| { + // Communicate the query via CLI since it's more compact. + if (!target.query.isNative()) { + try zig_args.appendSlice(&.{ + "-target", try target.query.zigTriple(b.allocator), + "-mcpu", try std.Build.serializeCpu(b.allocator, target.query.getCpu()), + }); - if (m.target.dynamic_linker.get()) |dynamic_linker| { - try zig_args.append("--dynamic-linker"); - try zig_args.append(dynamic_linker); + if (target.query.dynamic_linker.get()) |dynamic_linker| { + try zig_args.append("--dynamic-linker"); + try zig_args.append(dynamic_linker); + } } } @@ -565,10 +685,7 @@ pub fn appendZigProcessFlags( } } - for (m.c_macros.items) |c_macro| { - try zig_args.append("-D"); - try zig_args.append(c_macro); - } + try zig_args.appendSlice(m.c_macros.items); try zig_args.ensureUnusedCapacity(2 * m.lib_paths.items.len); for (m.lib_paths.items) |lib_path| { @@ -577,26 +694,16 @@ pub fn appendZigProcessFlags( } try zig_args.ensureUnusedCapacity(2 * m.rpaths.items.len); - for (m.rpaths.items) |rpath| { - zig_args.appendAssumeCapacity("-rpath"); - - if (m.target_info.target.isDarwin()) switch (rpath) { - .path, .cwd_relative => |path| { - // On Darwin, we should not try to expand special runtime paths such as - // * @executable_path - // * @loader_path - if (std.mem.startsWith(u8, path, "@executable_path") or - std.mem.startsWith(u8, path, "@loader_path")) - { - zig_args.appendAssumeCapacity(path); - continue; - } - }, - .generated, .dependency => {}, - }; - - zig_args.appendAssumeCapacity(rpath.getPath2(b, asking_step)); - } + for (m.rpaths.items) |rpath| switch (rpath) { + .lazy_path => |lp| { + zig_args.appendAssumeCapacity("-rpath"); + zig_args.appendAssumeCapacity(lp.getPath2(b, asking_step)); + }, + .special => |bytes| { + zig_args.appendAssumeCapacity("-rpath"); + zig_args.appendAssumeCapacity(bytes); + }, + }; } fn addFlag( @@ -609,8 +716,32 @@ fn addFlag( return args.append(if (cond) then_name else else_name); } +fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void { + const allocator = m.owner.allocator; + _ = other.getEmittedBin(); // Indicate there is a dependency on the outputted binary. + addStepDependenciesOnly(m, &other.step); + + if (other.rootModuleTarget().os.tag == .windows and other.isDynamicLibrary()) { + _ = other.getEmittedImplib(); // Indicate dependency on the outputted implib. + } + + m.link_objects.append(allocator, .{ .other_step = other }) catch @panic("OOM"); + m.include_dirs.append(allocator, .{ .other_step = other }) catch @panic("OOM"); + + for (other.installed_headers.items) |install_step| { + addStepDependenciesOnly(m, install_step); + } +} + +fn requireKnownTarget(m: *Module) std.Target { + const resolved_target = m.target orelse + @panic("this API requires the Module to be created with a known 'target' field"); + return resolved_target.target; +} + const Module = @This(); const std = @import("std"); const assert = std.debug.assert; const LazyPath = std.Build.LazyPath; const NativeTargetInfo = std.zig.system.NativeTargetInfo; +const Step = std.Build.Step; diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index 3be9cdc83c..c5eb1f776b 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -44,11 +44,11 @@ pub fn create( const SearchPhrase = struct { string: []const u8, - file_source: ?std.Build.LazyPath = null, + lazy_path: ?std.Build.LazyPath = null, fn resolve(phrase: SearchPhrase, b: *std.Build, step: *Step) []const u8 { - const file_source = phrase.file_source orelse return phrase.string; - return b.fmt("{s} {s}", .{ phrase.string, file_source.getPath2(b, step) }); + const lazy_path = phrase.lazy_path orelse return phrase.string; + return b.fmt("{s} {s}", .{ phrase.string, lazy_path.getPath2(b, step) }); } }; @@ -321,14 +321,14 @@ pub fn checkExact(self: *CheckObject, phrase: []const u8) void { /// Like `checkExact()` but takes an additional argument `LazyPath` which will be /// resolved to a full search query in `make()`. -pub fn checkExactPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void { - self.checkExactInner(phrase, file_source); +pub fn checkExactPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { + self.checkExactInner(phrase, lazy_path); } -fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.LazyPath) void { +fn checkExactInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source }); + last.exact(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path }); } /// Adds a fuzzy match phrase to the latest created Check. @@ -336,16 +336,20 @@ pub fn checkContains(self: *CheckObject, phrase: []const u8) void { self.checkContainsInner(phrase, null); } -/// Like `checkContains()` but takes an additional argument `FileSource` which will be +/// Like `checkContains()` but takes an additional argument `lazy_path` which will be /// resolved to a full search query in `make()`. -pub fn checkContainsPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void { - self.checkContainsInner(phrase, file_source); +pub fn checkContainsPath( + self: *CheckObject, + phrase: []const u8, + lazy_path: std.Build.LazyPath, +) void { + self.checkContainsInner(phrase, lazy_path); } -fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { +fn checkContainsInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.contains(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source }); + last.contains(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path }); } /// Adds an exact match phrase with variable extractor to the latest created Check. @@ -353,16 +357,16 @@ pub fn checkExtract(self: *CheckObject, phrase: []const u8) void { self.checkExtractInner(phrase, null); } -/// Like `checkExtract()` but takes an additional argument `FileSource` which will be +/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be /// resolved to a full search query in `make()`. -pub fn checkExtractFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void { - self.checkExtractInner(phrase, file_source); +pub fn checkExtractLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { + self.checkExtractInner(phrase, lazy_path); } -fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { +fn checkExtractInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.extract(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source }); + last.extract(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path }); } /// Adds another searched phrase to the latest created Check @@ -371,16 +375,16 @@ pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void { self.checkNotPresentInner(phrase, null); } -/// Like `checkExtract()` but takes an additional argument `FileSource` which will be +/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be /// resolved to a full search query in `make()`. -pub fn checkNotPresentFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void { - self.checkNotPresentInner(phrase, file_source); +pub fn checkNotPresentLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void { + self.checkNotPresentInner(phrase, lazy_path); } -fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void { +fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void { assert(self.checks.items.len > 0); const last = &self.checks.items[self.checks.items.len - 1]; - last.notPresent(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source }); + last.notPresent(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path }); } /// Creates a new check checking in the file headers (section, program headers, etc.). diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 4cd8868752..52c9703db0 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -88,7 +88,7 @@ each_lib_rpath: ?bool = null, /// As an example, the bloaty project refuses to work unless its inputs have /// build ids, in order to prevent accidental mismatches. /// The default is to not include this section because it slows down linking. -build_id: ?BuildId = null, +build_id: ?std.zig.BuildId = null, /// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF /// file. @@ -200,7 +200,7 @@ pub const ExpectedCompileErrors = union(enum) { exact: []const []const u8, }; -const Entry = union(enum) { +pub const Entry = union(enum) { /// Let the compiler decide whether to make an entry point and what to name /// it. default, @@ -232,82 +232,6 @@ pub const Options = struct { win32_manifest: ?LazyPath = null, }; -pub const BuildId = union(enum) { - none, - fast, - uuid, - sha1, - md5, - hexstring: HexString, - - pub fn eql(a: BuildId, b: BuildId) bool { - const a_tag = std.meta.activeTag(a); - const b_tag = std.meta.activeTag(b); - if (a_tag != b_tag) return false; - return switch (a) { - .none, .fast, .uuid, .sha1, .md5 => true, - .hexstring => |a_hexstring| mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()), - }; - } - - pub const HexString = struct { - bytes: [32]u8, - len: u8, - - /// Result is byte values, *not* hex-encoded. - pub fn toSlice(hs: *const HexString) []const u8 { - return hs.bytes[0..hs.len]; - } - }; - - /// Input is byte values, *not* hex-encoded. - /// Asserts `bytes` fits inside `HexString` - pub fn initHexString(bytes: []const u8) BuildId { - var result: BuildId = .{ .hexstring = .{ - .bytes = undefined, - .len = @as(u8, @intCast(bytes.len)), - } }; - @memcpy(result.hexstring.bytes[0..bytes.len], bytes); - return result; - } - - /// Converts UTF-8 text to a `BuildId`. - pub fn parse(text: []const u8) !BuildId { - if (mem.eql(u8, text, "none")) { - return .none; - } else if (mem.eql(u8, text, "fast")) { - return .fast; - } else if (mem.eql(u8, text, "uuid")) { - return .uuid; - } else if (mem.eql(u8, text, "sha1") or mem.eql(u8, text, "tree")) { - return .sha1; - } else if (mem.eql(u8, text, "md5")) { - return .md5; - } else if (mem.startsWith(u8, text, "0x")) { - var result: BuildId = .{ .hexstring = undefined }; - const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]); - result.hexstring.len = @as(u8, @intCast(slice.len)); - return result; - } - return error.InvalidBuildIdStyle; - } - - test parse { - try std.testing.expectEqual(BuildId.md5, try parse("md5")); - try std.testing.expectEqual(BuildId.none, try parse("none")); - try std.testing.expectEqual(BuildId.fast, try parse("fast")); - try std.testing.expectEqual(BuildId.uuid, try parse("uuid")); - try std.testing.expectEqual(BuildId.sha1, try parse("sha1")); - try std.testing.expectEqual(BuildId.sha1, try parse("tree")); - - try std.testing.expect(BuildId.initHexString("").eql(try parse("0x"))); - try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456"))); - try std.testing.expectError(error.InvalidLength, parse("0x12-34")); - try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb")); - try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx")); - } -}; - pub const Kind = enum { exe, lib, @@ -329,6 +253,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile { else owner.fmt("{s} ", .{name}); + const target = options.root_module.target.?.target; + const step_name = owner.fmt("{s} {s}{s} {s}", .{ switch (options.kind) { .exe => "zig build-exe", @@ -337,16 +263,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .@"test" => "zig test", }, name_adjusted, - @tagName(options.root_module.optimize), - options.root_module.target.zigTriple(owner.allocator) catch @panic("OOM"), + @tagName(options.root_module.optimize orelse .Debug), + target.zigTriple(owner.allocator) catch @panic("OOM"), }); - const target_info = NativeTargetInfo.detect(options.root_module.target) catch - @panic("unhandled error"); - const out_filename = std.zig.binNameAlloc(owner.allocator, .{ .root_name = name, - .target = target_info.target, + .target = target, .output_mode = switch (options.kind) { .lib => .Lib, .obj => .Obj, @@ -361,7 +284,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { const self = owner.allocator.create(Compile) catch @panic("OOM"); self.* = .{ - .root_module = Module.init(owner, options.root_module, self), + .root_module = undefined, .verbose_link = false, .verbose_cc = false, .linkage = options.linkage, @@ -403,6 +326,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .use_lld = options.use_lld, }; + self.root_module.init(owner, options.root_module, self); + if (options.zig_lib_dir) |lp| { self.zig_lib_dir = lp.dupe(self.step.owner); lp.addStepDependencies(&self.step); @@ -410,7 +335,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { // Only the PE/COFF format has a Resource Table which is where the manifest // gets embedded, so for any other target the manifest file is just ignored. - if (target_info.target.ofmt == .coff) { + if (target.ofmt == .coff) { if (options.win32_manifest) |lp| { self.win32_manifest = lp.dupe(self.step.owner); lp.addStepDependencies(&self.step); @@ -421,14 +346,14 @@ pub fn create(owner: *std.Build, options: Options) *Compile { if (self.linkage != null and self.linkage.? == .static) { self.out_lib_filename = self.out_filename; } else if (self.version) |version| { - if (target_info.target.isDarwin()) { + if (target.isDarwin()) { self.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{ self.name, version.major, }); self.name_only_filename = owner.fmt("lib{s}.dylib", .{self.name}); self.out_lib_filename = self.out_filename; - } else if (target_info.target.os.tag == .windows) { + } else if (target.os.tag == .windows) { self.out_lib_filename = owner.fmt("{s}.lib", .{self.name}); } else { self.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ self.name, version.major }); @@ -436,9 +361,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile { self.out_lib_filename = self.out_filename; } } else { - if (target_info.target.isDarwin()) { + if (target.isDarwin()) { self.out_lib_filename = self.out_filename; - } else if (target_info.target.os.tag == .windows) { + } else if (target.os.tag == .windows) { self.out_lib_filename = owner.fmt("{s}.lib", .{self.name}); } else { self.out_lib_filename = self.out_filename; @@ -545,7 +470,7 @@ pub const run = @compileError("deprecated; use std.Build.addRunArtifact"); pub const install = @compileError("deprecated; use std.Build.installArtifact"); pub fn checkObject(self: *Compile) *Step.CheckObject { - return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.target_info.target.ofmt); + return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.rootModuleTarget().ofmt); } /// deprecated: use `setLinkerScript` @@ -562,25 +487,6 @@ pub fn forceUndefinedSymbol(self: *Compile, symbol_name: []const u8) void { self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM"); } -pub fn linkFramework(self: *Compile, framework_name: []const u8) void { - const b = self.step.owner; - self.frameworks.put(b.dupe(framework_name), .{}) catch @panic("OOM"); -} - -pub fn linkFrameworkNeeded(self: *Compile, framework_name: []const u8) void { - const b = self.step.owner; - self.frameworks.put(b.dupe(framework_name), .{ - .needed = true, - }) catch @panic("OOM"); -} - -pub fn linkFrameworkWeak(self: *Compile, framework_name: []const u8) void { - const b = self.step.owner; - self.frameworks.put(b.dupe(framework_name), .{ - .weak = true, - }) catch @panic("OOM"); -} - /// Returns whether the library, executable, or object depends on a particular system library. pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool { var is_linking_libc = false; @@ -598,22 +504,17 @@ pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool { is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true; } - if (self.root_module.target_info.target.is_libc_lib_name(name)) { + if (self.rootModuleTarget().is_libc_lib_name(name)) { return is_linking_libc; } - if (self.root_module.target_info.target.is_libcpp_lib_name(name)) { + if (self.rootModuleTarget().is_libcpp_lib_name(name)) { return is_linking_libcpp; } return false; } -pub fn linkLibrary(self: *Compile, lib: *Compile) void { - assert(lib.kind == .lib); - self.linkLibraryOrObject(lib); -} - pub fn isDynamicLibrary(self: *const Compile) bool { return self.kind == .lib and self.linkage == Linkage.dynamic; } @@ -623,16 +524,24 @@ pub fn isStaticLibrary(self: *const Compile) bool { } pub fn producesPdbFile(self: *Compile) bool { + const target = self.rootModuleTarget(); // TODO: Is this right? Isn't PDB for *any* PE/COFF file? // TODO: just share this logic with the compiler, silly! - if (!self.target.isWindows() and !self.target.isUefi()) return false; - if (self.target.getObjectFormat() == .c) return false; - if (self.strip == true or (self.strip == null and self.optimize == .ReleaseSmall)) return false; + switch (target.os.tag) { + .windows, .uefi => {}, + else => return false, + } + if (target.ofmt == .c) return false; + if (self.root_module.strip == true or + (self.root_module.strip == null and self.root_module.optimize == .ReleaseSmall)) + { + return false; + } return self.isDynamicLibrary() or self.kind == .exe or self.kind == .@"test"; } pub fn producesImplib(self: *Compile) bool { - return self.isDynamicLibrary() and self.root_module.target_info.target.os.tag == .windows; + return self.isDynamicLibrary() and self.rootModuleTarget().os.tag == .windows; } pub fn linkLibC(self: *Compile) void { @@ -643,18 +552,9 @@ pub fn linkLibCpp(self: *Compile) void { self.root_module.link_libcpp = true; } -/// If the value is omitted, it is set to 1. -/// `name` and `value` need not live longer than the function call. -pub fn defineCMacro(self: *Compile, name: []const u8, value: ?[]const u8) void { - const b = self.step.owner; - const macro = std.Build.constructCMacro(b.allocator, name, value); - self.c_macros.append(macro) catch @panic("OOM"); -} - -/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1. -pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void { - const b = self.step.owner; - self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM"); +/// Deprecated. Use `c.root_module.addCMacro`. +pub fn defineCMacro(c: *Compile, name: []const u8, value: ?[]const u8) void { + c.root_module.addCMacro(name, value orelse "1"); } /// Run pkg-config for the given library name and parse the output, returning the arguments @@ -765,6 +665,20 @@ pub fn linkSystemLibrary2( return self.root_module.linkSystemLibrary(name, options); } +pub fn linkFramework(c: *Compile, name: []const u8) void { + c.root_module.linkFramework(name, .{}); +} + +/// Deprecated. Use `c.root_module.linkFramework`. +pub fn linkFrameworkNeeded(c: *Compile, name: []const u8) void { + c.root_module.linkFramework(name, .{ .needed = true }); +} + +/// Deprecated. Use `c.root_module.linkFramework`. +pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void { + c.root_module.linkFramework(name, .{ .weak = true }); +} + /// Handy when you have many C/C++ source files and want them all to have the same flags. pub fn addCSourceFiles(self: *Compile, options: Module.AddCSourceFilesOptions) void { self.root_module.addCSourceFiles(options); @@ -805,27 +719,18 @@ fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath return .{ .generated = generated_file }; } -/// deprecated: use `getEmittedBinDirectory` -pub const getOutputDirectorySource = getEmittedBinDirectory; - /// Returns the path to the directory that contains the emitted binary file. pub fn getEmittedBinDirectory(self: *Compile) LazyPath { _ = self.getEmittedBin(); return self.getEmittedFileGeneric(&self.emit_directory); } -/// deprecated: use `getEmittedBin` -pub const getOutputSource = getEmittedBin; - /// Returns the path to the generated executable, library or object file. /// To run an executable built with zig build, use `run`, or create an install step and invoke it. pub fn getEmittedBin(self: *Compile) LazyPath { return self.getEmittedFileGeneric(&self.generated_bin); } -/// deprecated: use `getEmittedImplib` -pub const getOutputLibSource = getEmittedImplib; - /// Returns the path to the generated import library. /// This function can only be called for libraries. pub fn getEmittedImplib(self: *Compile) LazyPath { @@ -833,9 +738,6 @@ pub fn getEmittedImplib(self: *Compile) LazyPath { return self.getEmittedFileGeneric(&self.generated_implib); } -/// deprecated: use `getEmittedH` -pub const getOutputHSource = getEmittedH; - /// Returns the path to the generated header file. /// This function can only be called for libraries or objects. pub fn getEmittedH(self: *Compile) LazyPath { @@ -843,9 +745,6 @@ pub fn getEmittedH(self: *Compile) LazyPath { return self.getEmittedFileGeneric(&self.generated_h); } -/// deprecated: use `getEmittedPdb`. -pub const getOutputPdbSource = getEmittedPdb; - /// Returns the generated PDB file. /// If the compilation does not produce a PDB file, this causes a FileNotFound error /// at build time. @@ -882,56 +781,44 @@ pub fn addObjectFile(self: *Compile, source: LazyPath) void { self.root_module.addObjectFile(source); } -pub fn addObject(self: *Compile, obj: *Compile) void { - assert(obj.kind == .obj); - self.linkLibraryOrObject(obj); +pub fn addObject(self: *Compile, object: *Compile) void { + self.root_module.addObject(object); } -pub fn addAfterIncludePath(self: *Compile, path: LazyPath) void { - const b = self.step.owner; - self.include_dirs.append(.{ .path_after = path.dupe(b) }) catch @panic("OOM"); - path.addStepDependencies(&self.step); +pub fn linkLibrary(self: *Compile, library: *Compile) void { + self.root_module.linkLibrary(library); } -pub fn addSystemIncludePath(self: *Compile, path: LazyPath) void { - const b = self.step.owner; - self.include_dirs.append(.{ .path_system = path.dupe(b) }) catch @panic("OOM"); - path.addStepDependencies(&self.step); +pub fn addAfterIncludePath(self: *Compile, lazy_path: LazyPath) void { + self.root_module.addAfterIncludePath(lazy_path); } -pub fn addIncludePath(self: *Compile, path: LazyPath) void { - const b = self.step.owner; - self.include_dirs.append(.{ .path = path.dupe(b) }) catch @panic("OOM"); - path.addStepDependencies(&self.step); +pub fn addSystemIncludePath(self: *Compile, lazy_path: LazyPath) void { + self.root_module.addSystemIncludePath(lazy_path); +} + +pub fn addIncludePath(self: *Compile, lazy_path: LazyPath) void { + self.root_module.addIncludePath(lazy_path); } pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void { - self.step.dependOn(&config_header.step); - self.include_dirs.append(.{ .config_header_step = config_header }) catch @panic("OOM"); + self.root_module.addConfigHeader(config_header); } -pub fn addLibraryPath(self: *Compile, directory_source: LazyPath) void { - const b = self.step.owner; - self.lib_paths.append(directory_source.dupe(b)) catch @panic("OOM"); - directory_source.addStepDependencies(&self.step); +pub fn addLibraryPath(self: *Compile, directory_path: LazyPath) void { + self.root_module.addLibraryPath(directory_path); } -pub fn addRPath(self: *Compile, directory_source: LazyPath) void { - const b = self.step.owner; - self.rpaths.append(directory_source.dupe(b)) catch @panic("OOM"); - directory_source.addStepDependencies(&self.step); +pub fn addRPath(self: *Compile, directory_path: LazyPath) void { + self.root_module.addRPath(directory_path); } -pub fn addSystemFrameworkPath(self: *Compile, directory_source: LazyPath) void { - const b = self.step.owner; - self.include_dirs.append(.{ .framework_path_system = directory_source.dupe(b) }) catch @panic("OOM"); - directory_source.addStepDependencies(&self.step); +pub fn addSystemFrameworkPath(self: *Compile, directory_path: LazyPath) void { + self.root_module.addSystemFrameworkPath(directory_path); } -pub fn addFrameworkPath(self: *Compile, directory_source: LazyPath) void { - const b = self.step.owner; - self.include_dirs.append(.{ .framework_path = directory_source.dupe(b) }) catch @panic("OOM"); - directory_source.addStepDependencies(&self.step); +pub fn addFrameworkPath(self: *Compile, directory_path: LazyPath) void { + self.root_module.addFrameworkPath(directory_path); } pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { @@ -944,20 +831,6 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void { self.exec_cmd_args = duped_args; } -fn linkLibraryOrObject(self: *Compile, other: *Compile) void { - other.getEmittedBin().addStepDependencies(&self.step); - if (other.target.isWindows() and other.isDynamicLibrary()) { - other.getEmittedImplib().addStepDependencies(&self.step); - } - - self.link_objects.append(.{ .other_step = other }) catch @panic("OOM"); - self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM"); - - for (other.installed_headers.items) |install_step| { - self.step.dependOn(install_step); - } -} - fn appendModuleArgs(cs: *Compile, zig_args: *ArrayList([]const u8)) !void { const b = cs.step.owner; // First, traverse the whole dependency graph and give every module a @@ -1014,7 +887,7 @@ fn appendModuleArgs(cs: *Compile, zig_args: *ArrayList([]const u8)) !void { fn constructDepString( allocator: std.mem.Allocator, mod_names: std.AutoArrayHashMapUnmanaged(*Module, []const u8), - deps: std.StringArrayHashMap(*Module), + deps: std.StringArrayHashMapUnmanaged(*Module), ) ![]const u8 { var deps_str = std.ArrayList(u8).init(allocator); var it = deps.iterator(); @@ -1082,7 +955,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try addFlag(&zig_args, "llvm", self.use_llvm); try addFlag(&zig_args, "lld", self.use_lld); - if (self.root_module.target.ofmt) |ofmt| { + if (self.root_module.target.?.query.ofmt) |ofmt| { try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)})); } @@ -1110,7 +983,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { { var seen_system_libs: std.StringHashMapUnmanaged(void) = .{}; - var frameworks: std.StringArrayHashMapUnmanaged(Module.FrameworkLinkInfo) = .{}; + var frameworks: std.StringArrayHashMapUnmanaged(Module.LinkFrameworkOptions) = .{}; var prev_has_cflags = false; var prev_has_rcflags = false; @@ -1240,7 +1113,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try zig_args.append(full_path_lib); if (other.linkage == Linkage.dynamic and - self.root_module.target_info.target.os.tag != .windows) + self.rootModuleTarget().os.tag != .windows) { if (fs.path.dirname(full_path_lib)) |dirname| { try zig_args.append("-rpath"); @@ -1471,11 +1344,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try zig_args.append(b.fmt("{}", .{version})); } - if (self.root_module.target_info.target.isDarwin()) { + if (self.rootModuleTarget().isDarwin()) { const install_name = self.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{ - self.root_module.target_info.target.libPrefix(), + self.rootModuleTarget().libPrefix(), self.name, - self.root_module.target_info.target.dynamicLibSuffix(), + self.rootModuleTarget().dynamicLibSuffix(), }); try zig_args.append("-install_name"); try zig_args.append(install_name); @@ -1763,7 +1636,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { } if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and - self.version != null and self.root_module.target.wantSharedLibSymLinks()) + self.version != null and std.Build.wantSharedLibSymLinks(self.rootModuleTarget())) { try doAtomicSymLinks( step, @@ -1932,3 +1805,8 @@ fn matchCompileError(actual: []const u8, expected: []const u8) bool { } return false; } + +pub fn rootModuleTarget(c: *Compile) std.Target { + // The root module is always given a target, so we know this to be non-null. + return c.root_module.target.?.target; +} diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 9f040349c6..c352b2460c 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -15,9 +15,6 @@ pub const Style = union(enum) { /// Start with nothing, like blank, and output a nasm .asm file. nasm, - /// deprecated: use `getPath` - pub const getFileSource = getPath; - pub fn getPath(style: Style) ?std.Build.LazyPath { switch (style) { .autoconf, .cmake => |s| return s, @@ -107,9 +104,6 @@ pub fn addValues(self: *ConfigHeader, values: anytype) void { return addValuesInner(self, values) catch @panic("OOM"); } -/// deprecated: use `getOutput` -pub const getFileSource = getOutput; - pub fn getOutput(self: *ConfigHeader) std.Build.LazyPath { return .{ .generated = &self.output_file }; } diff --git a/lib/std/Build/Step/InstallArtifact.zig b/lib/std/Build/Step/InstallArtifact.zig index f3c9ca3bef..b9c3acfbc9 100644 --- a/lib/std/Build/Step/InstallArtifact.zig +++ b/lib/std/Build/Step/InstallArtifact.zig @@ -94,7 +94,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins .dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and artifact.isDynamicLibrary() and artifact.version != null and - artifact.target.wantSharedLibSymLinks())) .{ + std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{ .major_only_filename = artifact.major_only_filename.?, .name_only_filename = artifact.name_only_filename.?, } else null, diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 8255be5cf4..362e030e5a 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -165,9 +165,6 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void { } } -/// deprecated: use `addOptionPath` -pub const addOptionFileSource = addOptionPath; - /// The value is the path in the cache dir. /// Adds a dependency automatically. pub fn addOptionPath( @@ -189,8 +186,7 @@ pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compi pub fn createModule(self: *Options) *std.Build.Module { return self.step.owner.createModule(.{ - .source_file = self.getOutput(), - .dependencies = &.{}, + .root_source_file = self.getOutput(), }); } diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 855eabeae9..40b72c7bca 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -197,16 +197,10 @@ pub fn addPrefixedOutputFileArg( return .{ .generated = &output.generated_file }; } -/// deprecated: use `addFileArg` -pub const addFileSourceArg = addFileArg; - pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void { self.addPrefixedFileArg("", lp); } -// deprecated: use `addPrefixedFileArg` -pub const addPrefixedFileSourceArg = addPrefixedFileArg; - pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, lp: std.Build.LazyPath) void { const b = self.step.owner; @@ -488,7 +482,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { man.hash.addBytes(file_path); }, .artifact => |artifact| { - if (artifact.root_module.target_info.target.os.tag == .windows) { + if (artifact.rootModuleTarget().os.tag == .windows) { // On Windows we don't have rpaths so we have to add .dll search paths to PATH self.addPathForDynLibs(artifact); } @@ -682,9 +676,10 @@ fn runCommand( else => break :interpret, } - const need_cross_glibc = exe.root_module.target_info.target.isGnuLibC() and + const need_cross_glibc = exe.rootModuleTarget().isGnuLibC() and exe.is_linking_libc; - switch (b.host.getExternalExecutor(&exe.root_module.target_info, .{ + const other_target_info = exe.root_module.target.?.toNativeTargetInfo(); + switch (b.host.toNativeTargetInfo().getExternalExecutor(&other_target_info, .{ .qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null, .link_libc = exe.is_linking_libc, })) { @@ -715,9 +710,9 @@ fn runCommand( // needs the directory to be called "i686" rather than // "x86" which is why we do it manually here. const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}"; - const cpu_arch = exe.root_module.target_info.target.cpu.arch; - const os_tag = exe.root_module.target_info.target.os.tag; - const abi = exe.root_module.target_info.target.abi; + const cpu_arch = exe.rootModuleTarget().cpu.arch; + const os_tag = exe.rootModuleTarget().os.tag; + const abi = exe.rootModuleTarget().abi; const cpu_arch_name: []const u8 = if (cpu_arch == .x86) "i686" else @@ -770,7 +765,7 @@ fn runCommand( if (allow_skip) return error.MakeSkipped; const host_name = try b.host.target.zigTriple(b.allocator); - const foreign_name = try exe.root_module.target_info.target.zigTriple(b.allocator); + const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator); return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{ host_name, foreign_name, @@ -778,7 +773,7 @@ fn runCommand( }, } - if (exe.root_module.target_info.target.os.tag == .windows) { + if (exe.rootModuleTarget().os.tag == .windows) { // On Windows we don't have rpaths so we have to add .dll search paths to PATH self.addPathForDynLibs(exe); } @@ -1300,7 +1295,7 @@ fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void { while (it.next()) |item| { const other = item.compile.?; if (item.module == &other.root_module) { - if (item.module.target_info.target.os.tag == .windows and other.isDynamicLibrary()) { + if (item.module.target.?.target.os.tag == .windows and other.isDynamicLibrary()) { addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?); addPathForDynLibs(self, other); } @@ -1321,7 +1316,7 @@ fn failForeign( const b = self.step.owner; const host_name = try b.host.target.zigTriple(b.allocator); - const foreign_name = try exe.root_module.target_info.target.zigTriple(b.allocator); + const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator); return self.step.fail( \\unable to spawn foreign binary '{s}' ({s}) on host system ({s}) diff --git a/lib/std/Build/Step/TranslateC.zig b/lib/std/Build/Step/TranslateC.zig index 26e59dad90..31919ba11a 100644 --- a/lib/std/Build/Step/TranslateC.zig +++ b/lib/std/Build/Step/TranslateC.zig @@ -2,7 +2,6 @@ const std = @import("std"); const Step = std.Build.Step; const fs = std.fs; const mem = std.mem; -const CrossTarget = std.zig.CrossTarget; const TranslateC = @This(); @@ -13,7 +12,7 @@ source: std.Build.LazyPath, include_dirs: std.ArrayList([]const u8), c_macros: std.ArrayList([]const u8), out_basename: []const u8, -target: CrossTarget, +target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, output_file: std.Build.GeneratedFile, link_libc: bool, @@ -21,7 +20,7 @@ use_clang: bool, pub const Options = struct { source_file: std.Build.LazyPath, - target: CrossTarget, + target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, link_libc: bool = true, use_clang: bool = true, @@ -54,7 +53,7 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC { pub const AddExecutableOptions = struct { name: ?[]const u8 = null, version: ?std.SemanticVersion = null, - target: ?CrossTarget = null, + target: ?std.Build.ResolvedTarget = null, optimize: ?std.builtin.OptimizeMode = null, linkage: ?Step.Compile.Linkage = null, }; @@ -139,9 +138,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { try argv_list.append("--listen=-"); - if (!self.target.isNative()) { + if (!self.target.query.isNative()) { try argv_list.append("-target"); - try argv_list.append(try self.target.zigTriple(b.allocator)); + try argv_list.append(try self.target.query.zigTriple(b.allocator)); } switch (self.optimize) { diff --git a/lib/std/Build/Step/WriteFile.zig b/lib/std/Build/Step/WriteFile.zig index 01019274fd..7fcf06249f 100644 --- a/lib/std/Build/Step/WriteFile.zig +++ b/lib/std/Build/Step/WriteFile.zig @@ -28,9 +28,6 @@ pub const File = struct { sub_path: []const u8, contents: Contents, - /// deprecated: use `getPath` - pub const getFileSource = getPath; - pub fn getPath(self: *File) std.Build.LazyPath { return .{ .generated = &self.generated_file }; } @@ -126,10 +123,6 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8) }) catch @panic("OOM"); } -pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getPath()"); - -pub const getDirectorySource = getDirectory; - /// Returns a `LazyPath` representing the base directory that contains all the /// files from this `WriteFile`. pub fn getDirectory(wf: *WriteFile) std.Build.LazyPath { diff --git a/lib/std/std.zig b/lib/std/std.zig index 7342cadbef..8db22c3c6c 100644 --- a/lib/std/std.zig +++ b/lib/std/std.zig @@ -194,9 +194,6 @@ pub const zig = @import("zig.zig"); pub const start = @import("start.zig"); -/// deprecated: use `Build`. -pub const build = Build; - const root = @import("root"); const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {}; diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 2d2aaf17ba..89e014190c 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -203,6 +203,83 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error } } +pub const BuildId = union(enum) { + none, + fast, + uuid, + sha1, + md5, + hexstring: HexString, + + pub fn eql(a: BuildId, b: BuildId) bool { + const Tag = @TypeOf(BuildId).Union.tag_type.?; + const a_tag: Tag = a; + const b_tag: Tag = b; + if (a_tag != b_tag) return false; + return switch (a) { + .none, .fast, .uuid, .sha1, .md5 => true, + .hexstring => |a_hexstring| std.mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()), + }; + } + + pub const HexString = struct { + bytes: [32]u8, + len: u8, + + /// Result is byte values, *not* hex-encoded. + pub fn toSlice(hs: *const HexString) []const u8 { + return hs.bytes[0..hs.len]; + } + }; + + /// Input is byte values, *not* hex-encoded. + /// Asserts `bytes` fits inside `HexString` + pub fn initHexString(bytes: []const u8) BuildId { + var result: BuildId = .{ .hexstring = .{ + .bytes = undefined, + .len = @intCast(bytes.len), + } }; + @memcpy(result.hexstring.bytes[0..bytes.len], bytes); + return result; + } + + /// Converts UTF-8 text to a `BuildId`. + pub fn parse(text: []const u8) !BuildId { + if (std.mem.eql(u8, text, "none")) { + return .none; + } else if (std.mem.eql(u8, text, "fast")) { + return .fast; + } else if (std.mem.eql(u8, text, "uuid")) { + return .uuid; + } else if (std.mem.eql(u8, text, "sha1") or std.mem.eql(u8, text, "tree")) { + return .sha1; + } else if (std.mem.eql(u8, text, "md5")) { + return .md5; + } else if (std.mem.startsWith(u8, text, "0x")) { + var result: BuildId = .{ .hexstring = undefined }; + const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]); + result.hexstring.len = @as(u8, @intCast(slice.len)); + return result; + } + return error.InvalidBuildIdStyle; + } + + test parse { + try std.testing.expectEqual(BuildId.md5, try parse("md5")); + try std.testing.expectEqual(BuildId.none, try parse("none")); + try std.testing.expectEqual(BuildId.fast, try parse("fast")); + try std.testing.expectEqual(BuildId.uuid, try parse("uuid")); + try std.testing.expectEqual(BuildId.sha1, try parse("sha1")); + try std.testing.expectEqual(BuildId.sha1, try parse("tree")); + + try std.testing.expect(BuildId.initHexString("").eql(try parse("0x"))); + try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456"))); + try std.testing.expectError(error.InvalidLength, parse("0x12-34")); + try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb")); + try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx")); + } +}; + test { @import("std").testing.refAllDecls(@This()); } diff --git a/lib/std/zig/CrossTarget.zig b/lib/std/zig/CrossTarget.zig index c65269e4d3..dc6de46af5 100644 --- a/lib/std/zig/CrossTarget.zig +++ b/lib/std/zig/CrossTarget.zig @@ -632,10 +632,6 @@ pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 { return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); } -pub fn wantSharedLibSymLinks(self: CrossTarget) bool { - return self.getOsTag() != .windows; -} - pub fn isGnuLibC(self: CrossTarget) bool { return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); } diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig index 080f18bf0a..d44e396fb5 100644 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ b/lib/std/zig/system/NativeTargetInfo.zig @@ -1008,8 +1008,8 @@ pub const GetExternalExecutorOptions = struct { link_libc: bool = false, }; -/// Return whether or not the given host target is capable of executing natively executables -/// of the other target. +/// Return whether or not the given host is capable of running executables of +/// the other target. pub fn getExternalExecutor( host: NativeTargetInfo, candidate: *const NativeTargetInfo, diff --git a/src/Compilation.zig b/src/Compilation.zig index 296b300f8d..7831a58840 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -30,7 +30,6 @@ const fatal = @import("main.zig").fatal; const clangMain = @import("main.zig").clangMain; const Module = @import("Module.zig"); const InternPool = @import("InternPool.zig"); -const BuildId = std.Build.CompileStep.BuildId; const Cache = std.Build.Cache; const c_codegen = @import("codegen/c.zig"); const libtsan = @import("libtsan.zig"); @@ -910,7 +909,7 @@ pub const InitOptions = struct { linker_print_map: bool = false, linker_opt_bisect_limit: i32 = -1, each_lib_rpath: ?bool = null, - build_id: ?BuildId = null, + build_id: ?std.zig.BuildId = null, disable_c_depfile: bool = false, linker_z_nodelete: bool = false, linker_z_notext: bool = false, diff --git a/src/link.zig b/src/link.zig index 12b9c58d9b..09669f4dbe 100644 --- a/src/link.zig +++ b/src/link.zig @@ -10,7 +10,6 @@ const wasi_libc = @import("wasi_libc.zig"); const Air = @import("Air.zig"); const Allocator = std.mem.Allocator; -const BuildId = std.Build.CompileStep.BuildId; const Cache = std.Build.Cache; const Compilation = @import("Compilation.zig"); const LibCInstallation = @import("libc_installation.zig").LibCInstallation; @@ -185,7 +184,7 @@ pub const Options = struct { error_return_tracing: bool, skip_linker_dependencies: bool, each_lib_rpath: bool, - build_id: BuildId, + build_id: std.zig.BuildId, disable_lld_caching: bool, is_test: bool, hash_style: HashStyle, diff --git a/src/main.zig b/src/main.zig index 73316c6e65..0e6ce947aa 100644 --- a/src/main.zig +++ b/src/main.zig @@ -21,7 +21,6 @@ const introspect = @import("introspect.zig"); const EnvVar = introspect.EnvVar; const LibCInstallation = @import("libc_installation.zig").LibCInstallation; const wasi_libc = @import("wasi_libc.zig"); -const BuildId = std.Build.CompileStep.BuildId; const Cache = std.Build.Cache; const target_util = @import("target.zig"); const crash_report = @import("crash_report.zig"); @@ -882,7 +881,7 @@ fn buildOutputType( var link_eh_frame_hdr = false; var link_emit_relocs = false; var each_lib_rpath: ?bool = null; - var build_id: ?BuildId = null; + var build_id: ?std.zig.BuildId = null; var sysroot: ?[]const u8 = null; var libc_paths_file: ?[]const u8 = try EnvVar.ZIG_LIBC.get(arena); var machine_code_model: std.builtin.CodeModel = .default; @@ -1551,7 +1550,7 @@ fn buildOutputType( build_id = .fast; } else if (mem.startsWith(u8, arg, "--build-id=")) { const style = arg["--build-id=".len..]; - build_id = BuildId.parse(style) catch |err| { + build_id = std.zig.BuildId.parse(style) catch |err| { fatal("unable to parse --build-id style '{s}': {s}", .{ style, @errorName(err), }); @@ -1847,7 +1846,7 @@ fn buildOutputType( const key = linker_arg[0..equals_pos]; const value = linker_arg[equals_pos + 1 ..]; if (mem.eql(u8, key, "--build-id")) { - build_id = BuildId.parse(value) catch |err| { + build_id = std.zig.BuildId.parse(value) catch |err| { fatal("unable to parse --build-id style '{s}': {s}", .{ value, @errorName(err), }); diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index ac09066552..e99925f228 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -876,27 +876,27 @@ test "two comptime calls with array default initialized to undefined" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO const S = struct { - const CrossTarget = struct { - dynamic_linker: DynamicLinker = DynamicLinker{}, + const A = struct { + c: B = B{}, - pub fn parse() void { - var result: CrossTarget = .{}; - result.getCpuArch(); + pub fn d() void { + var f: A = .{}; + f.e(); } - pub fn getCpuArch(self: CrossTarget) void { - _ = self; + pub fn e(g: A) void { + _ = g; } }; - const DynamicLinker = struct { + const B = struct { buffer: [255]u8 = undefined, }; }; comptime { - S.CrossTarget.parse(); - S.CrossTarget.parse(); + S.A.d(); + S.A.d(); } } diff --git a/test/cases.zig b/test/cases.zig index 2f39041332..9bbdde4777 100644 --- a/test/cases.zig +++ b/test/cases.zig @@ -9,9 +9,9 @@ pub const BuildOptions = struct { llvm_has_xtensa: bool, }; -pub fn addCases(cases: *Cases, build_options: BuildOptions) !void { - try @import("compile_errors.zig").addCases(cases); - try @import("cbe.zig").addCases(cases); - try @import("llvm_targets.zig").addCases(cases, build_options); - try @import("nvptx.zig").addCases(cases); +pub fn addCases(cases: *Cases, build_options: BuildOptions, b: *std.Build) !void { + try @import("compile_errors.zig").addCases(cases, b); + try @import("cbe.zig").addCases(cases, b); + try @import("llvm_targets.zig").addCases(cases, build_options, b); + try @import("nvptx.zig").addCases(cases, b); } diff --git a/test/cbe.zig b/test/cbe.zig index bee7138438..b45a4e5f72 100644 --- a/test/cbe.zig +++ b/test/cbe.zig @@ -2,16 +2,16 @@ const std = @import("std"); const Cases = @import("src/Cases.zig"); const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; -// These tests should work with all platforms, but we're using linux_x64 for -// now for consistency. Will be expanded eventually. -const linux_x64 = std.zig.CrossTarget{ - .cpu_arch = .x86_64, - .os_tag = .linux, -}; +pub fn addCases(ctx: *Cases, b: *std.Build) !void { + // These tests should work with all platforms, but we're using linux_x64 for + // now for consistency. Will be expanded eventually. + const linux_x64: std.zig.CrossTarget = .{ + .cpu_arch = .x86_64, + .os_tag = .linux, + }; -pub fn addCases(ctx: *Cases) !void { { - var case = ctx.exeFromCompiledC("hello world with updates", .{}); + var case = ctx.exeFromCompiledC("hello world with updates", .{}, b); // Regular old hello world case.addCompareOutput( @@ -59,7 +59,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("var args", .{}); + var case = ctx.exeFromCompiledC("var args", .{}, b); case.addCompareOutput( \\extern fn printf(format: [*:0]const u8, ...) c_int; @@ -72,7 +72,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("errorFromInt", .{}); + var case = ctx.exeFromCompiledC("errorFromInt", .{}, b); case.addCompareOutput( \\pub export fn main() c_int { @@ -108,7 +108,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64); + var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64, b); // Exit with 0 case.addCompareOutput( @@ -202,7 +202,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("alloc and retptr", .{}); + var case = ctx.exeFromCompiledC("alloc and retptr", .{}, b); case.addCompareOutput( \\fn add(a: i32, b: i32) i32 { @@ -220,7 +220,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("inferred local const and var", .{}); + var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b); case.addCompareOutput( \\fn add(a: i32, b: i32) i32 { @@ -236,7 +236,7 @@ pub fn addCases(ctx: *Cases) !void { , ""); } { - var case = ctx.exeFromCompiledC("control flow", .{}); + var case = ctx.exeFromCompiledC("control flow", .{}, b); // Simple while loop case.addCompareOutput( @@ -423,7 +423,7 @@ pub fn addCases(ctx: *Cases) !void { }); } //{ - // var case = ctx.exeFromCompiledC("optionals", .{}); + // var case = ctx.exeFromCompiledC("optionals", .{}, b); // // Simple while loop // case.addCompareOutput( @@ -451,7 +451,7 @@ pub fn addCases(ctx: *Cases) !void { //} { - var case = ctx.exeFromCompiledC("errors", .{}); + var case = ctx.exeFromCompiledC("errors", .{}, b); case.addCompareOutput( \\pub export fn main() c_int { \\ var e1 = error.Foo; @@ -495,7 +495,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("structs", .{}); + var case = ctx.exeFromCompiledC("structs", .{}, b); case.addError( \\const Point = struct { x: i32, y: i32 }; \\pub export fn main() c_int { @@ -562,7 +562,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("unions", .{}); + var case = ctx.exeFromCompiledC("unions", .{}, b); case.addError( \\const U = union { @@ -596,7 +596,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("enums", .{}); + var case = ctx.exeFromCompiledC("enums", .{}, b); case.addError( \\const E1 = packed enum { a, b, c }; @@ -838,7 +838,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("shift right and left", .{}); + var case = ctx.exeFromCompiledC("shift right and left", .{}, b); case.addCompareOutput( \\pub export fn main() c_int { \\ var i: u32 = 16; @@ -863,7 +863,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("inferred error sets", .{}); + var case = ctx.exeFromCompiledC("inferred error sets", .{}, b); case.addCompareOutput( \\pub export fn main() c_int { @@ -884,7 +884,7 @@ pub fn addCases(ctx: *Cases) !void { { // TODO: add u64 tests, ran into issues with the literal generated for std.math.maxInt(u64) - var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{}); + var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{}, b); case.addCompareOutput( \\pub export fn main() c_int { \\ // Addition @@ -933,7 +933,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = ctx.exeFromCompiledC("rem", linux_x64); + var case = ctx.exeFromCompiledC("rem", linux_x64, b); case.addCompareOutput( \\fn assert(ok: bool) void { \\ if (!ok) unreachable; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index a3bdf5b8f1..ec3726e94d 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,9 +2,9 @@ const std = @import("std"); const builtin = @import("builtin"); const Cases = @import("src/Cases.zig"); -pub fn addCases(ctx: *Cases) !void { +pub fn addCases(ctx: *Cases, b: *std.Build) !void { { - const case = ctx.obj("multiline error messages", .{}); + const case = ctx.obj("multiline error messages", b.host); case.addError( \\comptime { @@ -39,7 +39,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("isolated carriage return in multiline string literal", .{}); + const case = ctx.obj("isolated carriage return in multiline string literal", b.host); case.addError("const foo = \\\\\test\r\r rogue carriage return\n;", &[_][]const u8{ ":1:19: error: expected ';' after declaration", @@ -48,7 +48,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("missing semicolon at EOF", .{}); + const case = ctx.obj("missing semicolon at EOF", b.host); case.addError( \\const foo = 1 , &[_][]const u8{ @@ -57,7 +57,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("argument causes error", .{}); + const case = ctx.obj("argument causes error", b.host); case.addError( \\pub export fn entry() void { @@ -80,7 +80,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("astgen failure in file struct", .{}); + const case = ctx.obj("astgen failure in file struct", b.host); case.addError( \\pub export fn entry() void { @@ -95,7 +95,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("invalid store to comptime field", .{}); + const case = ctx.obj("invalid store to comptime field", b.host); case.addError( \\const a = @import("a.zig"); @@ -119,7 +119,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("file in multiple modules", .{}); + const case = ctx.obj("file in multiple modules", b.host); case.addDepModule("foo", "foo.zig"); case.addError( @@ -138,7 +138,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("wrong same named struct", .{}); + const case = ctx.obj("wrong same named struct", b.host); case.addError( \\const a = @import("a.zig"); @@ -172,7 +172,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("non-printable invalid character", .{}); + const case = ctx.obj("non-printable invalid character", b.host); case.addError("\xff\xfe" ++ \\export fn foo() bool { @@ -185,7 +185,7 @@ pub fn addCases(ctx: *Cases) !void { } { - const case = ctx.obj("imported generic method call with invalid param", .{}); + const case = ctx.obj("imported generic method call with invalid param", b.host); case.addError( \\pub const import = @import("import.zig"); diff --git a/test/link/bss/build.zig b/test/link/bss/build.zig index 3c7964fae1..865af0a488 100644 --- a/test/link/bss/build.zig +++ b/test/link/bss/build.zig @@ -7,6 +7,7 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "bss", .root_source_file = .{ .path = "main.zig" }, + .target = b.host, .optimize = .Debug, }); diff --git a/test/link/common_symbols/build.zig b/test/link/common_symbols/build.zig index bb44073e38..9b5c9da662 100644 --- a/test/link/common_symbols/build.zig +++ b/test/link/common_symbols/build.zig @@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib_a = b.addStaticLibrary(.{ .name = "a", .optimize = optimize, - .target = .{}, + .target = b.host, }); lib_a.addCSourceFiles(.{ .files = &.{ "c.c", "a.c", "b.c" }, diff --git a/test/link/common_symbols_alignment/build.zig b/test/link/common_symbols_alignment/build.zig index 049a8f5a8f..63aff339a9 100644 --- a/test/link/common_symbols_alignment/build.zig +++ b/test/link/common_symbols_alignment/build.zig @@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib_a = b.addStaticLibrary(.{ .name = "a", .optimize = optimize, - .target = .{}, + .target = b.host, }); lib_a.addCSourceFiles(.{ .files = &.{"a.c"}, diff --git a/test/link/elf.zig b/test/link/elf.zig index 4055ec9219..d395344edd 100644 --- a/test/link/elf.zig +++ b/test/link/elf.zig @@ -5,20 +5,20 @@ pub fn testAll(b: *Build) *Step { const elf_step = b.step("test-elf", "Run ELF tests"); - const default_target = CrossTarget{ + const default_target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, // TODO relax this once ELF linker is able to handle other archs .os_tag = .linux, - }; - const musl_target = CrossTarget{ + }); + const musl_target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl, - }; - const glibc_target = CrossTarget{ + }); + const glibc_target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .gnu, - }; + }); // Exercise linker in -r mode elf_step.dependOn(testEmitRelocatable(b, .{ .use_llvm = false, .target = musl_target })); @@ -132,14 +132,18 @@ pub fn testAll(b: *Build) *Step { fn testAbsSymbols(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "abs-symbols", opts); - const obj = addObject(b, "obj", opts); - addAsmSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .asm_source_bytes = \\.globl foo \\foo = 0x800008 - ); + \\ + , + }); - const exe = addExecutable(b, "test", opts); - addCSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test", + .c_source_bytes = \\#include \\#include \\#include @@ -159,7 +163,8 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step { \\ foo = 5; \\ return 0; \\} - , &.{}); + , + }); exe.addObject(obj); exe.linkLibC(); @@ -173,31 +178,36 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step { fn testAsNeeded(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "as-needed", opts); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\int baz(); \\int main() { \\ printf("%d\n", baz()); \\ return 0; \\} - , &.{}); + \\ + , + }); main_o.linkLibC(); - const libfoo = addSharedLibrary(b, "foo", opts); + const libfoo = addSharedLibrary(b, opts, .{ .name = "foo" }); addCSourceBytes(libfoo, "int foo() { return 42; }", &.{}); - const libbar = addSharedLibrary(b, "bar", opts); + const libbar = addSharedLibrary(b, opts, .{ .name = "bar" }); addCSourceBytes(libbar, "int bar() { return 42; }", &.{}); - const libbaz = addSharedLibrary(b, "baz", opts); + const libbaz = addSharedLibrary(b, opts, .{ .name = "baz" }); addCSourceBytes(libbaz, \\int foo(); \\int baz() { return foo(); } , &.{}); { - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ + .name = "test", + }); exe.addObject(main_o); exe.linkSystemLibrary2("foo", .{ .needed = true }); exe.addLibraryPath(libfoo.getEmittedBinDirectory()); @@ -225,7 +235,9 @@ fn testAsNeeded(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ + .name = "test", + }); exe.addObject(main_o); exe.linkSystemLibrary2("foo", .{ .needed = false }); exe.addLibraryPath(libfoo.getEmittedBinDirectory()); @@ -259,7 +271,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step { fn testCanonicalPlt(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "canonical-plt", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\void *foo() { \\ return foo; @@ -269,17 +281,21 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { \\} , &.{}); - const b_o = addObject(b, "obj", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\void *bar(); \\void *baz() { \\ return bar; \\} - , &.{}); - b_o.force_pic = true; + \\ + , + .pic = true, + }); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\void *foo(); \\void *bar(); @@ -290,11 +306,15 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { \\ assert(bar == baz()); \\ return 0; \\} - , &.{}); + \\ + , + .pic = false, + }); main_o.linkLibC(); - main_o.force_pic = false; - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ + .name = "main", + }); exe.addObject(main_o); exe.addObject(b_o); exe.linkLibrary(dso); @@ -311,7 +331,9 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step { fn testCommonSymbols(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "common-symbols", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ + .name = "test", + }); addCSourceBytes(exe, \\int foo; \\int bar; @@ -338,8 +360,9 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step { fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "common-symbols-in-archive", opts); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\#include \\int foo; \\int bar; @@ -348,28 +371,43 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { \\int main() { \\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1); \\} - , &.{"-fcommon"}); + \\ + , + .c_source_flags = &.{"-fcommon"}, + }); a_o.linkLibC(); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"}); + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = "int foo = 5;", + .c_source_flags = &.{"-fcommon"}, + }); { - const c_o = addObject(b, "c", opts); - addCSourceBytes(c_o, + const c_o = addObject(b, opts, .{ + .name = "c", + .c_source_bytes = \\int bar; \\int two() { return 2; } - , &.{"-fcommon"}); + \\ + , + .c_source_flags = &.{"-fcommon"}, + }); - const d_o = addObject(b, "d", opts); - addCSourceBytes(d_o, "int baz;", &.{"-fcommon"}); + const d_o = addObject(b, opts, .{ + .name = "d", + .c_source_bytes = "int baz;", + .c_source_flags = &.{"-fcommon"}, + }); - const lib = addStaticLibrary(b, "lib", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); lib.addObject(b_o); lib.addObject(c_o); lib.addObject(d_o); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ + .name = "test", + }); exe.addObject(a_o); exe.linkLibrary(lib); exe.linkLibC(); @@ -380,18 +418,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { } { - const e_o = addObject(b, "e", opts); - addCSourceBytes(e_o, + const e_o = addObject(b, opts, .{ + .name = "e", + .c_source_bytes = \\int bar = 0; \\int baz = 7; \\int two() { return 2; } - , &.{"-fcommon"}); + , + .c_source_flags = &.{"-fcommon"}, + }); - const lib = addStaticLibrary(b, "lib", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); lib.addObject(b_o); lib.addObject(e_o); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ + .name = "test", + }); exe.addObject(a_o); exe.linkLibrary(lib); exe.linkLibC(); @@ -407,21 +450,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step { fn testCopyrel(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "copyrel", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\int foo = 3; \\int bar = 5; , &.{}); - const exe = addExecutable(b, "main", opts); - addCSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\extern int foo, bar; \\int main() { \\ printf("%d %d\n", foo, bar); \\ return 0; \\} - , &.{}); + , + }); exe.linkLibrary(dso); exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 @@ -437,7 +482,7 @@ fn testCopyrel(b: *Build, opts: Options) *Step { fn testCopyrelAlias(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "copyrel-alias", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\int bruh = 31; \\int foo = 42; @@ -445,7 +490,10 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { \\extern int baz __attribute__((alias("foo"))); , &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ + .name = "main", + .pic = false, + }); addCSourceBytes(exe, \\#include \\extern int foo; @@ -461,7 +509,6 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { , &.{}); exe.linkLibrary(dso); exe.linkLibC(); - exe.force_pic = false; exe.pie = false; const run = addRunArtifact(exe); @@ -474,28 +521,31 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step { fn testCopyrelAlignment(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "copyrel-alignment", opts); - const a_so = addSharedLibrary(b, "a", opts); + const a_so = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(a_so, "__attribute__((aligned(32))) int foo = 5;", &.{}); - const b_so = addSharedLibrary(b, "b", opts); + const b_so = addSharedLibrary(b, opts, .{ .name = "b" }); addCSourceBytes(b_so, "__attribute__((aligned(8))) int foo = 5;", &.{}); - const c_so = addSharedLibrary(b, "c", opts); + const c_so = addSharedLibrary(b, opts, .{ .name = "c" }); addCSourceBytes(c_so, "__attribute__((aligned(256))) int foo = 5;", &.{}); - const obj = addObject(b, "main", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\extern int foo; \\int main() { printf("%d\n", foo); } - , &.{}); + \\ + , + .pic = false, + }); obj.linkLibC(); - obj.force_pic = false; const exp_stdout = "5\n"; { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(obj); exe.linkLibrary(a_so); exe.linkLibC(); @@ -514,7 +564,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(obj); exe.linkLibrary(b_so); exe.linkLibC(); @@ -533,7 +583,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(obj); exe.linkLibrary(c_so); exe.linkLibC(); @@ -557,7 +607,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step { fn testDsoPlt(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "dso-plt", opts); - const dso = addSharedLibrary(b, "dso", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); addCSourceBytes(dso, \\#include \\void world() { @@ -573,7 +623,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, \\#include \\void world() { @@ -599,7 +649,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step { fn testDsoUndef(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "dso-undef", opts); - const dso = addSharedLibrary(b, "dso", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); addCSourceBytes(dso, \\extern int foo; \\int bar = 5; @@ -607,13 +657,15 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, "int foo = 3;", &.{}); + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = "int foo = 3;", + }); - const lib = addStaticLibrary(b, "lib", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); lib.addObject(obj); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); exe.linkLibrary(dso); exe.linkLibrary(lib); addCSourceBytes(exe, @@ -641,8 +693,9 @@ fn testDsoUndef(b: *Build, opts: Options) *Step { fn testEmitRelocatable(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "emit-relocatable", opts); - const obj1 = addObject(b, "obj1", opts); - addZigSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .zig_source_bytes = \\const std = @import("std"); \\extern var bar: i32; \\export fn foo() i32 { @@ -651,18 +704,20 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { \\export fn printFoo() void { \\ std.debug.print("foo={d}\n", .{foo()}); \\} - ); - addCSourceBytes(obj1, + , + .c_source_bytes = \\#include \\int bar = 42; \\void printBar() { \\ fprintf(stderr, "bar=%d\n", bar); \\} - , &.{}); + , + }); obj1.linkLibC(); - const exe = addExecutable(b, "test", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test", + .zig_source_bytes = \\const std = @import("std"); \\extern fn printFoo() void; \\extern fn printBar() void; @@ -670,7 +725,8 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { \\ printFoo(); \\ printBar(); \\} - ); + , + }); exe.addObject(obj1); exe.linkLibC(); @@ -688,20 +744,26 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step { fn testEmitStaticLib(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "emit-static-lib", opts); - const obj1 = addObject(b, "obj1", opts); - addCSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .c_source_bytes = \\int foo = 0; \\int bar = 2; \\int fooBar() { \\ return foo + bar; \\} - , &.{}); + , + }); - const obj2 = addObject(b, "obj2", opts); - addCSourceBytes(obj2, "int tentative;", &.{"-fcommon"}); + const obj2 = addObject(b, opts, .{ + .name = "obj2", + .c_source_bytes = "int tentative;", + .c_source_flags = &.{"-fcommon"}, + }); - const obj3 = addObject(b, "a_very_long_file_name_so_that_it_ends_up_in_strtab", opts); - addZigSourceBytes(obj3, + const obj3 = addObject(b, opts, .{ + .name = "a_very_long_file_name_so_that_it_ends_up_in_strtab", + .zig_source_bytes = \\fn weakFoo() callconv(.C) usize { \\ return 42; \\} @@ -710,9 +772,10 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step { \\ @export(weakFoo, .{ .name = "weakFoo", .linkage = .Weak }); \\ @export(strongBar, .{ .name = "strongBarAlias", .linkage = .Strong }); \\} - ); + , + }); - const lib = addStaticLibrary(b, "lib", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); lib.addObject(obj1); lib.addObject(obj2); lib.addObject(obj3); @@ -747,30 +810,36 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step { fn testEmitStaticLibZig(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "emit-static-lib-zig", opts); - const obj1 = addObject(b, "obj1", opts); - addZigSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .zig_source_bytes = \\export var foo: i32 = 42; \\export var bar: i32 = 2; - ); + , + }); - const lib = addStaticLibrary(b, "lib", opts); - addZigSourceBytes(lib, + const lib = addStaticLibrary(b, opts, .{ + .name = "lib", + .zig_source_bytes = \\extern var foo: i32; \\extern var bar: i32; \\export fn fooBar() i32 { \\ return foo + bar; \\} - ); + , + }); lib.addObject(obj1); - const exe = addExecutable(b, "test", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test", + .zig_source_bytes = \\const std = @import("std"); \\extern fn fooBar() i32; \\pub fn main() void { \\ std.debug.print("{d}", .{fooBar()}); \\} - ); + , + }); exe.linkLibrary(lib); const run = addRunArtifact(exe); @@ -783,7 +852,7 @@ fn testEmitStaticLibZig(b: *Build, opts: Options) *Step { fn testEmptyObject(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "empty-object", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, "int main() { return 0; }", &.{}); addCSourceBytes(exe, "", &.{}); exe.linkLibC(); @@ -798,18 +867,23 @@ fn testEmptyObject(b: *Build, opts: Options) *Step { fn testEntryPoint(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "entry-point", opts); - const a_o = addObject(b, "a", opts); - addAsmSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .asm_source_bytes = \\.globl foo, bar \\foo = 0x1000 \\bar = 0x2000 - ); + \\ + , + }); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, "int main() { return 0; }", &.{}); + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = "int main() { return 0; }", + }); { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(a_o); exe.addObject(b_o); exe.entry = .{ .symbol_name = "foo" }; @@ -825,7 +899,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step { // TODO looks like not assigning a unique name to this executable will // cause an artifact collision taking the cached executable from the above // step instead of generating a new one. - const exe = addExecutable(b, "other", opts); + const exe = addExecutable(b, opts, .{ .name = "other" }); exe.addObject(a_o); exe.addObject(b_o); exe.entry = .{ .symbol_name = "bar" }; @@ -843,8 +917,9 @@ fn testEntryPoint(b: *Build, opts: Options) *Step { fn testExportDynamic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "export-dynamic", opts); - const obj = addObject(b, "obj", opts); - addAsmSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .asm_source_bytes = \\.text \\ .globl foo \\ .hidden foo @@ -856,12 +931,14 @@ fn testExportDynamic(b: *Build, opts: Options) *Step { \\ .globl _start \\_start: \\ nop - ); + \\ + , + }); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, "int baz = 10;", &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\extern int baz; \\int callBaz() { @@ -885,7 +962,7 @@ fn testExportDynamic(b: *Build, opts: Options) *Step { fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "export-symbols-from-exe", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\void expfn1(); \\void expfn2() {} @@ -895,7 +972,7 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { \\} , &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\void expfn1() {} \\void expfn2() {} @@ -923,10 +1000,10 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step { fn testFuncAddress(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "func-address", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, "void fn() {}", &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\typedef void Func(); @@ -937,7 +1014,7 @@ fn testFuncAddress(b: *Build, opts: Options) *Step { \\} , &.{}); exe.linkLibrary(dso); - exe.force_pic = false; + exe.root_module.pic = false; exe.pie = false; const run = addRunArtifact(exe); @@ -950,8 +1027,9 @@ fn testFuncAddress(b: *Build, opts: Options) *Step { fn testGcSections(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "gc-sections", opts); - const obj = addObject(b, "obj", opts); - addCppSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .cpp_source_bytes = \\#include \\int two() { return 2; } \\int live_var1 = 1; @@ -966,14 +1044,15 @@ fn testGcSections(b: *Build, opts: Options) *Step { \\ printf("%d %d\n", live_var1, live_var2); \\ live_fn2(); \\} - , &.{}); + , + }); obj.link_function_sections = true; obj.link_data_sections = true; obj.linkLibC(); obj.linkLibCpp(); { - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); exe.addObject(obj); exe.link_gc_sections = false; exe.linkLibC(); @@ -1004,7 +1083,7 @@ fn testGcSections(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); exe.addObject(obj); exe.link_gc_sections = true; exe.linkLibC(); @@ -1040,11 +1119,12 @@ fn testGcSections(b: *Build, opts: Options) *Step { fn testGcSectionsZig(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "gc-sections-zig", opts); - const obj = addObject(b, "obj", .{ + const obj = addObject(b, .{ .target = opts.target, .use_llvm = true, - }); - addCSourceBytes(obj, + }, .{ + .name = "obj", + .c_source_bytes = \\int live_var1 = 1; \\int live_var2 = 2; \\int dead_var1 = 3; @@ -1053,13 +1133,15 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { \\void live_fn2() { live_fn1(); } \\void dead_fn1() {} \\void dead_fn2() { dead_fn1(); } - , &.{}); + , + }); obj.link_function_sections = true; obj.link_data_sections = true; { - const exe = addExecutable(b, "test1", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test1", + .zig_source_bytes = \\const std = @import("std"); \\extern var live_var1: i32; \\extern var live_var2: i32; @@ -1069,7 +1151,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; \\ live_fn2(); \\} - ); + , + }); exe.addObject(obj); exe.link_gc_sections = false; @@ -1098,8 +1181,9 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "test2", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test2", + .zig_source_bytes = \\const std = @import("std"); \\extern var live_var1: i32; \\extern var live_var2: i32; @@ -1109,7 +1193,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable; \\ live_fn2(); \\} - ); + , + }); exe.addObject(obj); exe.link_gc_sections = true; @@ -1143,7 +1228,7 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step { fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "hidden-weak-undef", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\__attribute__((weak, visibility("hidden"))) void foo(); \\void bar() { foo(); } @@ -1162,7 +1247,7 @@ fn testHiddenWeakUndef(b: *Build, opts: Options) *Step { fn testIFuncAlias(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-alias", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\void foo() {} @@ -1173,7 +1258,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step { \\ assert(bar == bar2); \\} , &.{}); - exe.force_pic = true; + exe.root_module.pic = true; exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -1188,7 +1273,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step { fn testIFuncDlopen(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-dlopen", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\__attribute__((ifunc("resolve_foo"))) \\void foo(void); @@ -1200,7 +1285,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { \\} , &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\#include @@ -1219,7 +1304,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { exe.linkLibrary(dso); exe.linkLibC(); exe.linkSystemLibrary2("dl", .{}); - exe.force_pic = false; + exe.root_module.pic = false; exe.pie = false; const run = addRunArtifact(exe); @@ -1232,7 +1317,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step { fn testIFuncDso(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-dso", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\#include \\__attribute__((ifunc("resolve_foobar"))) @@ -1247,7 +1332,7 @@ fn testIFuncDso(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\void foobar(void); \\int main() { @@ -1283,7 +1368,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { ; { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, main_c, &.{}); exe.linkLibC(); exe.link_z_lazy = true; @@ -1295,7 +1380,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { test_step.dependOn(&run.step); } { - const exe = addExecutable(b, "other", opts); + const exe = addExecutable(b, opts, .{ .name = "other" }); addCSourceBytes(exe, main_c, &.{}); exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 @@ -1312,7 +1397,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step { fn testIFuncExport(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-export", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\#include \\__attribute__((ifunc("resolve_foobar"))) @@ -1338,7 +1423,7 @@ fn testIFuncExport(b: *Build, opts: Options) *Step { fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-func-ptr", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\typedef int Fn(); \\int foo() __attribute__((ifunc("resolve_foo"))); @@ -1361,7 +1446,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { \\ printf("%d\n", f()); \\} , &.{}); - exe.force_pic = true; + exe.root_module.pic = true; exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -1376,7 +1461,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step { fn testIFuncNoPlt(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-noplt", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\__attribute__((ifunc("resolve_foo"))) @@ -1392,7 +1477,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step { \\ foo(); \\} , &.{"-fno-plt"}); - exe.force_pic = true; + exe.root_module.pic = true; exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -1407,7 +1492,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step { fn testIFuncStatic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-static", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\void foo() __attribute__((ifunc("resolve_foo"))); @@ -1435,7 +1520,7 @@ fn testIFuncStatic(b: *Build, opts: Options) *Step { fn testIFuncStaticPie(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ifunc-static-pie", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\void foo() __attribute__((ifunc("resolve_foo"))); @@ -1451,7 +1536,7 @@ fn testIFuncStaticPie(b: *Build, opts: Options) *Step { \\} , &.{}); exe.linkage = .static; - exe.force_pic = true; + exe.root_module.pic = true; exe.pie = true; exe.linkLibC(); @@ -1478,7 +1563,7 @@ fn testImageBase(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "image-base", opts); { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); addCSourceBytes(exe, \\#include \\int main() { @@ -1502,7 +1587,7 @@ fn testImageBase(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); addCSourceBytes(exe, "void _start() {}", &.{}); exe.image_base = 0xffffffff8000000; @@ -1520,22 +1605,26 @@ fn testImageBase(b: *Build, opts: Options) *Step { fn testImportingDataDynamic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "importing-data-dynamic", opts); - const dso = addSharedLibrary(b, "a", .{ + const dso = addSharedLibrary(b, .{ .target = opts.target, .optimize = opts.optimize, .use_llvm = true, + }, .{ + .name = "a", + .c_source_bytes = "int foo = 42;", }); - addCSourceBytes(dso, "int foo = 42;", &.{}); - const main = addExecutable(b, "main", opts); - addZigSourceBytes(main, + const main = addExecutable(b, opts, .{ + .name = "main", + .zig_source_bytes = \\extern var foo: i32; \\pub fn main() void { \\ @import("std").debug.print("{d}\n", .{foo}); \\} - ); + , + .strip = true, // TODO temp hack + }); main.pie = true; - main.strip = true; // TODO temp hack main.linkLibrary(dso); main.linkLibC(); @@ -1549,28 +1638,34 @@ fn testImportingDataDynamic(b: *Build, opts: Options) *Step { fn testImportingDataStatic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "importing-data-static", opts); - const obj = addObject(b, "a", .{ + const obj = addObject(b, .{ .target = opts.target, .optimize = opts.optimize, .use_llvm = true, + }, .{ + .name = "a", + .c_source_bytes = "int foo = 42;", }); - addCSourceBytes(obj, "int foo = 42;", &.{}); - const lib = addStaticLibrary(b, "a", .{ + const lib = addStaticLibrary(b, .{ .target = opts.target, .optimize = opts.optimize, .use_llvm = true, + }, .{ + .name = "a", }); lib.addObject(obj); - const main = addExecutable(b, "main", opts); - addZigSourceBytes(main, + const main = addExecutable(b, opts, .{ + .name = "main", + .zig_source_bytes = \\extern var foo: i32; \\pub fn main() void { \\ @import("std").debug.print("{d}\n", .{foo}); \\} - ); - main.strip = true; // TODO temp hack + , + .strip = true, // TODO temp hack + }); main.linkLibrary(lib); main.linkLibC(); @@ -1584,63 +1679,76 @@ fn testImportingDataStatic(b: *Build, opts: Options) *Step { fn testInitArrayOrder(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "init-array-order", opts); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\#include \\__attribute__((constructor(10000))) void init4() { printf("1"); } - , &.{}); + , + }); a_o.linkLibC(); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\#include \\__attribute__((constructor(1000))) void init3() { printf("2"); } - , &.{}); + , + }); b_o.linkLibC(); - const c_o = addObject(b, "c", opts); - addCSourceBytes(c_o, + const c_o = addObject(b, opts, .{ + .name = "c", + .c_source_bytes = \\#include \\__attribute__((constructor)) void init1() { printf("3"); } - , &.{}); + , + }); c_o.linkLibC(); - const d_o = addObject(b, "d", opts); - addCSourceBytes(d_o, + const d_o = addObject(b, opts, .{ + .name = "d", + .c_source_bytes = \\#include \\__attribute__((constructor)) void init2() { printf("4"); } - , &.{}); + , + }); d_o.linkLibC(); - const e_o = addObject(b, "e", opts); - addCSourceBytes(e_o, + const e_o = addObject(b, opts, .{ + .name = "e", + .c_source_bytes = \\#include \\__attribute__((destructor(10000))) void fini4() { printf("5"); } - , &.{}); + , + }); e_o.linkLibC(); - const f_o = addObject(b, "f", opts); - addCSourceBytes(f_o, + const f_o = addObject(b, opts, .{ + .name = "f", + .c_source_bytes = \\#include \\__attribute__((destructor(1000))) void fini3() { printf("6"); } - , &.{}); + , + }); f_o.linkLibC(); - const g_o = addObject(b, "g", opts); - addCSourceBytes(g_o, + const g_o = addObject(b, opts, .{ + .name = "g", + .c_source_bytes = \\#include \\__attribute__((destructor)) void fini1() { printf("7"); } - , &.{}); + , + }); g_o.linkLibC(); - const h_o = addObject(b, "h", opts); - addCSourceBytes(h_o, - \\#include - \\__attribute__((destructor)) void fini2() { printf("8"); } - , &.{}); + const h_o = addObject(b, opts, .{ .name = "h", .c_source_bytes = + \\#include + \\__attribute__((destructor)) void fini2() { printf("8"); } + }); h_o.linkLibC(); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, "int main() { return 0; }", &.{}); exe.addObject(a_o); exe.addObject(b_o); @@ -1651,7 +1759,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step { exe.addObject(g_o); exe.addObject(h_o); - if (opts.target.isGnuLibC()) { + if (opts.target.target.isGnuLibC()) { // TODO I think we need to clarify our use of `-fPIC -fPIE` flags for different targets exe.pie = true; } @@ -1666,7 +1774,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step { fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "large-alignment-dso", opts); - const dso = addSharedLibrary(b, "dso", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "dso" }); addCSourceBytes(dso, \\#include \\#include @@ -1695,7 +1803,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } }); test_step.dependOn(&check.step); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, \\void greet(); \\int main() { greet(); } @@ -1715,7 +1823,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step { fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "large-alignment-exe", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, \\#include \\#include @@ -1760,7 +1868,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step { fn testLargeBss(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "large-bss", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\char arr[0x100000000]; \\int main() { @@ -1781,27 +1889,31 @@ fn testLargeBss(b: *Build, opts: Options) *Step { fn testLinkOrder(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "link-order", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, "void foo() {}", &.{}); - obj.force_pic = true; + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = "void foo() {}", + .pic = true, + }); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(obj); - const lib = addStaticLibrary(b, "b", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "b" }); lib.addObject(obj); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\void foo(); \\int main() { \\ foo(); \\} - , &.{}); + , + }); // https://github.com/ziglang/zig/issues/17450 // { - // const exe = addExecutable(b, "main1", opts); + // const exe = addExecutable(b, opts, .{ .name = "main1"}); // exe.addObject(main_o); // exe.linkSystemLibrary2("a", .{}); // exe.addLibraryPath(dso.getEmittedBinDirectory()); @@ -1818,7 +1930,7 @@ fn testLinkOrder(b: *Build, opts: Options) *Step { // } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(main_o); exe.linkSystemLibrary2("b", .{}); exe.addLibraryPath(lib.getEmittedBinDirectory()); @@ -1840,14 +1952,14 @@ fn testLinkOrder(b: *Build, opts: Options) *Step { fn testLdScript(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "ld-script", opts); - const dso = addSharedLibrary(b, "bar", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "bar" }); addCSourceBytes(dso, "int foo() { return 42; }", &.{}); const scripts = WriteFile.create(b); _ = scripts.add("liba.so", "INPUT(libfoo.so)"); _ = scripts.add("libfoo.so", "GROUP(AS_NEEDED(-lbar))"); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\int foo(); \\int main() { @@ -1875,7 +1987,7 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { const scripts = WriteFile.create(b); _ = scripts.add("liba.so", "INPUT(libfoo.so)"); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, "int main() { return 0; }", &.{}); exe.linkSystemLibrary2("a", .{}); exe.addLibraryPath(scripts.getDirectory()); @@ -1895,13 +2007,15 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step { fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "mismatched-cpu-architecture-error", opts); - const obj = addObject(b, "a", .{ - .target = .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .gnu }, + const obj = addObject(b, .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .gnu }), + }, .{ + .name = "a", + .c_source_bytes = "int foo;", + .strip = true, }); - addCSourceBytes(obj, "int foo;", &.{}); - obj.strip = true; - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\extern int foo; \\int main() { @@ -1922,7 +2036,7 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step { fn testLinkingC(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "linking-c", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, \\#include \\int main() { @@ -1951,7 +2065,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step { fn testLinkingCpp(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "linking-cpp", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCppSourceBytes(exe, \\#include \\int main() { @@ -1981,24 +2095,28 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step { fn testLinkingObj(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "linking-obj", opts); - const obj = addObject(b, "aobj", opts); - addZigSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "aobj", + .zig_source_bytes = \\extern var mod: usize; \\export fn callMe() usize { \\ return me * mod; \\} \\var me: usize = 42; - ); + , + }); - const exe = addExecutable(b, "testobj", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "testobj", + .zig_source_bytes = \\const std = @import("std"); \\extern fn callMe() usize; \\export var mod: usize = 2; \\pub fn main() void { \\ std.debug.print("{d}\n", .{callMe()}); \\} - ); + , + }); exe.addObject(obj); const run = addRunArtifact(exe); @@ -2011,26 +2129,32 @@ fn testLinkingObj(b: *Build, opts: Options) *Step { fn testLinkingStaticLib(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "linking-static-lib", opts); - const obj = addObject(b, "bobj", opts); - addZigSourceBytes(obj, "export var bar: i32 = -42;"); + const obj = addObject(b, opts, .{ + .name = "bobj", + .zig_source_bytes = "export var bar: i32 = -42;", + }); - const lib = addStaticLibrary(b, "alib", opts); - addZigSourceBytes(lib, + const lib = addStaticLibrary(b, opts, .{ + .name = "alib", + .zig_source_bytes = \\export fn foo() i32 { \\ return 42; \\} - ); + , + }); lib.addObject(obj); - const exe = addExecutable(b, "testlib", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "testlib", + .zig_source_bytes = \\const std = @import("std"); \\extern fn foo() i32; \\extern var bar: i32; \\pub fn main() void { \\ std.debug.print("{d}\n", .{foo() + bar}); \\} - ); + , + }); exe.linkLibrary(lib); const run = addRunArtifact(exe); @@ -2043,12 +2167,14 @@ fn testLinkingStaticLib(b: *Build, opts: Options) *Step { fn testLinkingZig(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "linking-zig-static", opts); - const exe = addExecutable(b, "test", opts); - addZigSourceBytes(exe, + const exe = addExecutable(b, opts, .{ + .name = "test", + .zig_source_bytes = \\pub fn main() void { \\ @import("std").debug.print("Hello World!\n", .{}); \\} - ); + , + }); const run = addRunArtifact(exe); run.expectStdErrEqual("Hello World!\n"); @@ -2069,7 +2195,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step { fn testNoEhFrameHdr(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "no-eh-frame-hdr", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, "int main() { return 0; }", &.{}); exe.link_eh_frame_hdr = false; exe.linkLibC(); @@ -2086,7 +2212,7 @@ fn testNoEhFrameHdr(b: *Build, opts: Options) *Step { fn testPie(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "hello-pie", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\int main() { @@ -2095,7 +2221,7 @@ fn testPie(b: *Build, opts: Options) *Step { \\} , &.{}); exe.linkLibC(); - exe.force_pic = true; + exe.root_module.pic = true; exe.pie = true; const run = addRunArtifact(exe); @@ -2117,7 +2243,7 @@ fn testPie(b: *Build, opts: Options) *Step { fn testPltGot(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "plt-got", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\#include \\void ignore(void *foo) {} @@ -2127,7 +2253,7 @@ fn testPltGot(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\void ignore(void *); \\int hello(); @@ -2135,7 +2261,7 @@ fn testPltGot(b: *Build, opts: Options) *Step { \\int main() { hello(); } , &.{}); exe.linkLibrary(dso); - exe.force_pic = true; + exe.root_module.pic = true; exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -2151,10 +2277,12 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "preinit-array", opts); { - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, "void _start() {}", &.{}); + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = "void _start() {}", + }); - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(obj); const check = exe.checkObject(); @@ -2163,7 +2291,7 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); addCSourceBytes(exe, \\void preinit_fn() {} \\int main() {} @@ -2183,38 +2311,48 @@ fn testPreinitArray(b: *Build, opts: Options) *Step { fn testRelocatableArchive(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "relocatable-archive", opts); - const obj1 = addObject(b, "obj1", opts); - addCSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .c_source_bytes = \\void bar(); \\void foo() { \\ bar(); \\} - , &.{}); + , + }); - const obj2 = addObject(b, "obj2", opts); - addCSourceBytes(obj2, + const obj2 = addObject(b, opts, .{ + .name = "obj2", + .c_source_bytes = \\void bar() {} - , &.{}); + , + }); - const obj3 = addObject(b, "obj3", opts); - addCSourceBytes(obj3, + const obj3 = addObject(b, opts, .{ + .name = "obj3", + .c_source_bytes = \\void baz(); - , &.{}); + , + }); - const obj4 = addObject(b, "obj4", opts); - addCSourceBytes(obj4, + const obj4 = addObject(b, opts, .{ + .name = "obj4", + .c_source_bytes = \\void foo(); \\int main() { \\ foo(); \\} - , &.{}); + , + }); - const lib = addStaticLibrary(b, "lib", opts); + const lib = addStaticLibrary(b, opts, .{ .name = "lib" }); lib.addObject(obj1); lib.addObject(obj2); lib.addObject(obj3); - const obj5 = addObject(b, "obj5", opts); + const obj5 = addObject(b, opts, .{ + .name = "obj5", + }); obj5.addObject(obj4); obj5.linkLibrary(lib); @@ -2234,13 +2372,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "relocatable-eh-frame", opts); { - const obj = addObject(b, "obj1", opts); - addCppSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj1", + .cpp_source_bytes = \\#include \\int try_me() { \\ throw std::runtime_error("Oh no!"); \\} - , &.{}); + , + }); addCppSourceBytes(obj, \\extern int try_me(); \\int try_again() { @@ -2249,7 +2389,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { , &.{}); obj.linkLibCpp(); - const exe = addExecutable(b, "test1", opts); + const exe = addExecutable(b, opts, .{ .name = "test1" }); addCppSourceBytes(exe, \\#include \\#include @@ -2273,13 +2413,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { { // Let's make the object file COMDAT group heavy! - const obj = addObject(b, "obj2", opts); - addCppSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj2", + .cpp_source_bytes = \\#include \\int try_me() { \\ throw std::runtime_error("Oh no!"); \\} - , &.{}); + , + }); addCppSourceBytes(obj, \\extern int try_me(); \\int try_again() { @@ -2301,7 +2443,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { , &.{}); obj.linkLibCpp(); - const exe = addExecutable(b, "test2", opts); + const exe = addExecutable(b, opts, .{ .name = "test2" }); exe.addObject(obj); exe.linkLibCpp(); @@ -2316,13 +2458,18 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step { fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "relocatable-no-eh-frame", opts); - const obj1 = addObject(b, "obj1", opts); - addCSourceBytes(obj1, "int bar() { return 42; }", &.{ - "-fno-unwind-tables", - "-fno-asynchronous-unwind-tables", + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .c_source_bytes = "int bar() { return 42; }", + .c_source_flags = &.{ + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + }, }); - const obj2 = addObject(b, "obj2", opts); + const obj2 = addObject(b, opts, .{ + .name = "obj2", + }); obj2.addObject(obj1); const check1 = obj1.checkObject(); @@ -2343,23 +2490,25 @@ fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step { fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "shared-abs-symbol", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addAsmSourceBytes(dso, \\.globl foo \\foo = 3; ); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\#include \\extern char foo; \\int main() { printf("foo=%p\n", &foo); } - , &.{}); - obj.force_pic = true; + , + .pic = true, + }); obj.linkLibC(); { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(obj); exe.linkLibrary(dso); exe.pie = true; @@ -2380,7 +2529,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { // https://github.com/ziglang/zig/issues/17430 // { - // const exe = addExecutable(b, "main2", opts); + // const exe = addExecutable(b, opts, .{ .name = "main2"}); // exe.addObject(obj); // exe.linkLibrary(dso); // exe.pie = false; @@ -2405,20 +2554,22 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step { fn testStrip(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "strip", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\#include \\int main() { \\ printf("Hello!\n"); \\ return 0; \\} - , &.{}); + , + }); obj.linkLibC(); { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(obj); - exe.strip = false; + exe.root_module.strip = false; exe.linkLibC(); const check = exe.checkObject(); @@ -2429,9 +2580,9 @@ fn testStrip(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(obj); - exe.strip = true; + exe.root_module.strip = true; exe.linkLibC(); const check = exe.checkObject(); @@ -2447,16 +2598,19 @@ fn testStrip(b: *Build, opts: Options) *Step { fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-df-static-tls", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\static _Thread_local int foo = 5; \\void mutate() { ++foo; } \\int bar() { return foo; } - , &.{"-ftls-model=initial-exec"}); - obj.force_pic = true; + , + .c_source_flags = &.{"-ftls-model=initial-exec"}, + .pic = true, + }); { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(obj); // dso.link_relax = true; @@ -2468,7 +2622,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { // TODO add -Wl,--no-relax // { - // const dso = addSharedLibrary(b, "a", opts); + // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); // dso.addObject(obj); // dso.link_relax = false; @@ -2484,7 +2638,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { fn testTlsDso(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-dso", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\extern _Thread_local int foo; \\_Thread_local int bar; @@ -2492,7 +2646,7 @@ fn testTlsDso(b: *Build, opts: Options) *Step { \\int get_bar1() { return bar; } , &.{}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\_Thread_local int foo; @@ -2526,8 +2680,9 @@ fn testTlsDso(b: *Build, opts: Options) *Step { fn testTlsGd(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-gd", opts); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2; @@ -2540,37 +2695,42 @@ fn testTlsGd(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6()); \\ return 0; \\} - , &.{}); + , + .pic = true, + }); main_o.linkLibC(); - main_o.force_pic = true; - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5; \\int get_x5() { return x5; } - , &.{}); - a_o.force_pic = true; + , + .pic = true, + }); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6; \\int get_x6() { return x6; } - , &.{}); - b_o.force_pic = true; + , + .pic = true, + }); const exp_stdout = "1 2 3 4 5 6\n"; - const dso1 = addSharedLibrary(b, "a", opts); + const dso1 = addSharedLibrary(b, opts, .{ .name = "a" }); dso1.addObject(a_o); - const dso2 = addSharedLibrary(b, "b", opts); + const dso2 = addSharedLibrary(b, opts, .{ .name = "b" }); dso2.addObject(b_o); // dso2.link_relax = false; // TODO { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(main_o); exe.linkLibrary(dso1); exe.linkLibrary(dso2); @@ -2581,7 +2741,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(main_o); // exe.link_relax = false; // TODO exe.linkLibrary(dso1); @@ -2594,7 +2754,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { // https://github.com/ziglang/zig/issues/17430 ?? // { - // const exe = addExecutable(b, "main3", opts); + // const exe = addExecutable(b, opts, .{ .name = "main3"}); // exe.addObject(main_o); // exe.linkLibrary(dso1); // exe.linkLibrary(dso2); @@ -2606,7 +2766,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step { // } // { - // const exe = addExecutable(b, "main4", opts); + // const exe = addExecutable(b, opts, .{ .name = "main4"}); // exe.addObject(main_o); // // exe.link_relax = false; // TODO // exe.linkLibrary(dso1); @@ -2624,8 +2784,9 @@ fn testTlsGd(b: *Build, opts: Options) *Step { fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-gd-no-plt", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\#include \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2; @@ -2639,18 +2800,20 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6()); \\ return 0; \\} - , &.{"-fno-plt"}); - obj.force_pic = true; + , + .c_source_flags = &.{"-fno-plt"}, + .pic = true, + }); obj.linkLibC(); - const a_so = addSharedLibrary(b, "a", opts); + const a_so = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(a_so, \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5; \\int get_x5() { return x5; } , &.{"-fno-plt"}); - const b_so = addSharedLibrary(b, "b", opts); + const b_so = addSharedLibrary(b, opts, .{ .name = "b" }); addCSourceBytes(b_so, \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6; @@ -2659,7 +2822,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { // b_so.link_relax = false; // TODO { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(obj); exe.linkLibrary(a_so); exe.linkLibrary(b_so); @@ -2673,7 +2836,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(obj); exe.linkLibrary(a_so); exe.linkLibrary(b_so); @@ -2693,8 +2856,9 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step { fn testTlsGdToIe(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-gd-to-ie", opts); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\#include \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1; \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x2 = 2; @@ -2705,22 +2869,25 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { \\ printf("%d %d %d\n", x1, x2, x3); \\ return 0; \\} - , &.{}); + , + .pic = true, + }); a_o.linkLibC(); - a_o.force_pic = true; - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\int foo(); \\int main() { foo(); } - , &.{}); - b_o.force_pic = true; + , + .pic = true, + }); { - const dso = addSharedLibrary(b, "a1", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a1" }); dso.addObject(a_o); - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(b_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -2733,11 +2900,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { } { - const dso = addSharedLibrary(b, "a2", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a2" }); dso.addObject(a_o); // dso.link_relax = false; // TODO - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(b_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -2750,11 +2917,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { } // { - // const dso = addSharedLibrary(b, "a", opts); + // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); // dso.addObject(a_o); // dso.link_z_nodlopen = true; - // const exe = addExecutable(b, "main", opts); + // const exe = addExecutable(b, opts, .{ .name = "main"}); // exe.addObject(b_o); // exe.linkLibrary(dso); @@ -2764,12 +2931,12 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { // } // { - // const dso = addSharedLibrary(b, "a", opts); + // const dso = addSharedLibrary(b, opts, .{ .name = "a"}); // dso.addObject(a_o); // dso.link_relax = false; // dso.link_z_nodlopen = true; - // const exe = addExecutable(b, "main", opts); + // const exe = addExecutable(b, opts, .{ .name = "main"}); // exe.addObject(b_o); // exe.linkLibrary(dso); @@ -2784,7 +2951,7 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step { fn testTlsIe(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-ie", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\#include \\__attribute__((tls_model("initial-exec"))) static _Thread_local int foo; @@ -2799,8 +2966,9 @@ fn testTlsIe(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\_Thread_local int baz; \\void set(); @@ -2812,13 +2980,14 @@ fn testTlsIe(b: *Build, opts: Options) *Step { \\ print(); \\ printf("%d\n", baz); \\} - , &.{}); + , + }); main_o.linkLibC(); const exp_stdout = "0 0 3 5 7\n"; { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(main_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -2831,7 +3000,7 @@ fn testTlsIe(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(main_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -2850,38 +3019,46 @@ fn testTlsIe(b: *Build, opts: Options) *Step { fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-large-alignment", opts); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\__attribute__((section(".tdata1"))) \\_Thread_local int x = 42; - , &.{"-std=c11"}); - a_o.force_pic = true; + , + .c_source_flags = &.{"-std=c11"}, + .pic = true, + }); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\__attribute__((section(".tdata2"))) \\_Alignas(256) _Thread_local int y[] = { 1, 2, 3 }; - , &.{"-std=c11"}); - b_o.force_pic = true; + , + .c_source_flags = &.{"-std=c11"}, + .pic = true, + }); - const c_o = addObject(b, "c", opts); - addCSourceBytes(c_o, + const c_o = addObject(b, opts, .{ + .name = "c", + .c_source_bytes = \\#include \\extern _Thread_local int x; \\extern _Thread_local int y[]; \\int main() { \\ printf("%d %d %d %d\n", x, y[0], y[1], y[2]); \\} - , &.{}); - c_o.force_pic = true; + , + .pic = true, + }); c_o.linkLibC(); { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(a_o); dso.addObject(b_o); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(c_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -2894,7 +3071,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(a_o); exe.addObject(b_o); exe.addObject(c_o); @@ -2913,7 +3090,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step { fn testTlsLargeTbss(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-large-tbss", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addAsmSourceBytes(exe, \\.globl x, y \\.section .tbss,"awT",@nobits @@ -2947,7 +3124,7 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step { fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-large-static-image", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, "_Thread_local int x[] = { 1, 2, 3, [10000] = 5 };", &.{}); addCSourceBytes(exe, \\#include @@ -2956,7 +3133,7 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[10000]); \\} , &.{}); - exe.force_pic = true; + exe.root_module.pic = true; exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -2971,8 +3148,9 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step { fn testTlsLd(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-ld", opts); - const main_o = addObject(b, "main", opts); - addCSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .c_source_bytes = \\#include \\extern _Thread_local int foo; \\static _Thread_local int bar; @@ -2983,18 +3161,23 @@ fn testTlsLd(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); \\ return 0; \\} - , &.{"-ftls-model=local-dynamic"}); - main_o.force_pic = true; + , + .c_source_flags = &.{"-ftls-model=local-dynamic"}, + .pic = true, + }); main_o.linkLibC(); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, "_Thread_local int foo = 3;", &.{"-ftls-model=local-dynamic"}); - a_o.force_pic = true; + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = "_Thread_local int foo = 3;", + .c_source_flags = &.{"-ftls-model=local-dynamic"}, + .pic = true, + }); const exp_stdout = "3 5 3 5\n"; { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(main_o); exe.addObject(a_o); exe.linkLibC(); @@ -3007,7 +3190,7 @@ fn testTlsLd(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(main_o); exe.addObject(a_o); exe.linkLibC(); @@ -3026,14 +3209,14 @@ fn testTlsLd(b: *Build, opts: Options) *Step { fn testTlsLdDso(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-ld-dso", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\static _Thread_local int def, def1; \\int f0() { return ++def; } \\int f1() { return ++def1 + def; } , &.{"-ftls-model=local-dynamic"}); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\extern int f0(); @@ -3060,8 +3243,9 @@ fn testTlsLdDso(b: *Build, opts: Options) *Step { fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-ld-no-plt", opts); - const a_o = addObject(b, "a", opts); - addCSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\#include \\extern _Thread_local int foo; \\static _Thread_local int bar; @@ -3073,16 +3257,21 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); \\ return 0; \\} - , &.{ "-ftls-model=local-dynamic", "-fno-plt" }); + , + .c_source_flags = &.{ "-ftls-model=local-dynamic", "-fno-plt" }, + .pic = true, + }); a_o.linkLibC(); - a_o.force_pic = true; - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, "_Thread_local int foo = 3;", &.{ "-ftls-model=local-dynamic", "-fno-plt" }); - b_o.force_pic = true; + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = "_Thread_local int foo = 3;", + .c_source_flags = &.{ "-ftls-model=local-dynamic", "-fno-plt" }, + .pic = true, + }); { - const exe = addExecutable(b, "main1", opts); + const exe = addExecutable(b, opts, .{ .name = "main1" }); exe.addObject(a_o); exe.addObject(b_o); exe.linkLibC(); @@ -3095,7 +3284,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main2", opts); + const exe = addExecutable(b, opts, .{ .name = "main2" }); exe.addObject(a_o); exe.addObject(b_o); exe.linkLibC(); @@ -3114,7 +3303,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step { fn testTlsNoPic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-no-pic", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo; @@ -3132,7 +3321,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step { addCSourceBytes(exe, \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo; , &.{}); - exe.force_pic = false; + exe.root_module.pic = false; exe.linkLibC(); const run = addRunArtifact(exe); @@ -3145,7 +3334,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step { fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-offset-alignment", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\#include \\#include @@ -3163,7 +3352,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { , &.{}); dso.linkLibC(); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\#include @@ -3186,7 +3375,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { , &.{}); exe.addRPath(dso.getEmittedBinDirectory()); exe.linkLibC(); - exe.force_pic = true; + exe.root_module.pic = true; // https://github.com/ziglang/zig/issues/17619 exe.pie = true; @@ -3200,8 +3389,9 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step { fn testTlsPic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-pic", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\#include \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo; \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int bar; @@ -3213,11 +3403,12 @@ fn testTlsPic(b: *Build, opts: Options) *Step { \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar); \\ return 0; \\} - , &.{}); + , + .pic = true, + }); obj.linkLibC(); - obj.force_pic = true; - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo = 3; , &.{}); @@ -3236,30 +3427,38 @@ fn testTlsPic(b: *Build, opts: Options) *Step { fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-small-alignment", opts); - const a_o = addObject(b, "a", opts); - addAsmSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .asm_source_bytes = \\.text \\.byte 0 - ); - a_o.force_pic = true; + \\ + , + .pic = true, + }); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, "_Thread_local char x = 42;", &.{"-std=c11"}); - b_o.force_pic = true; + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = "_Thread_local char x = 42;", + .c_source_flags = &.{"-std=c11"}, + .pic = true, + }); - const c_o = addObject(b, "c", opts); - addCSourceBytes(c_o, + const c_o = addObject(b, opts, .{ + .name = "c", + .c_source_bytes = \\#include \\extern _Thread_local char x; \\int main() { \\ printf("%d\n", x); \\} - , &.{}); + , + .pic = true, + }); c_o.linkLibC(); - c_o.force_pic = true; { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(a_o); exe.addObject(b_o); exe.addObject(c_o); @@ -3273,11 +3472,11 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { } { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(a_o); dso.addObject(b_o); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(c_o); exe.linkLibrary(dso); exe.linkLibC(); @@ -3295,7 +3494,7 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step { fn testTlsStatic(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-static", opts); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); addCSourceBytes(exe, \\#include \\_Thread_local int a = 10; @@ -3326,12 +3525,14 @@ fn testTlsStatic(b: *Build, opts: Options) *Step { fn testUnknownFileTypeError(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "unknown-file-type-error", opts); - const dylib = addSharedLibrary(b, "a", .{ - .target = .{ .cpu_arch = .x86_64, .os_tag = .macos }, + const dylib = addSharedLibrary(b, .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .macos }), + }, .{ + .name = "a", + .zig_source_bytes = "export var foo: i32 = 0;", }); - addZigSourceBytes(dylib, "export var foo: i32 = 0;"); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\extern int foo; \\int main() { @@ -3354,28 +3555,34 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step { fn testUnresolvedError(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "unresolved-error", opts); - const obj1 = addObject(b, "a", opts); - addCSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "a", + .c_source_bytes = \\#include \\int foo(); \\int bar() { \\ return foo() + 1; \\} - , &.{"-ffunction-sections"}); + , + .c_source_flags = &.{"-ffunction-sections"}, + }); obj1.linkLibC(); - const obj2 = addObject(b, "b", opts); - addCSourceBytes(obj2, + const obj2 = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\#include \\int foo(); \\int bar(); \\int main() { \\ return foo() + bar(); \\} - , &.{"-ffunction-sections"}); + , + .c_source_flags = &.{"-ffunction-sections"}, + }); obj2.linkLibC(); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(obj1); exe.addObject(obj2); exe.linkLibC(); @@ -3392,19 +3599,21 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step { fn testWeakExports(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "weak-exports", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = \\#include \\__attribute__((weak)) int foo(); \\int main() { \\ printf("%d\n", foo ? foo() : 3); \\} - , &.{}); + , + .pic = true, + }); obj.linkLibC(); - obj.force_pic = true; { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(obj); dso.linkLibC(); @@ -3415,7 +3624,7 @@ fn testWeakExports(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); exe.addObject(obj); exe.linkLibC(); // https://github.com/ziglang/zig/issues/17619 @@ -3437,14 +3646,14 @@ fn testWeakExports(b: *Build, opts: Options) *Step { fn testWeakUndefsDso(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "weak-undef-dso", opts); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); addCSourceBytes(dso, \\__attribute__((weak)) int foo(); \\int bar() { return foo ? foo() : -1; } , &.{}); { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\int bar(); @@ -3461,7 +3670,7 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step { } { - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\int foo() { return 5; } @@ -3484,12 +3693,14 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step { fn testZNow(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "z-now", opts); - const obj = addObject(b, "obj", opts); - addCSourceBytes(obj, "int main() { return 0; }", &.{}); - obj.force_pic = true; + const obj = addObject(b, opts, .{ + .name = "obj", + .c_source_bytes = "int main() { return 0; }", + .pic = true, + }); { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(obj); const check = dso.checkObject(); @@ -3499,7 +3710,7 @@ fn testZNow(b: *Build, opts: Options) *Step { } { - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(obj); dso.link_z_lazy = true; @@ -3515,7 +3726,7 @@ fn testZNow(b: *Build, opts: Options) *Step { fn testZStackSize(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "z-stack-size", opts); - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, "int main() { return 0; }", &.{}); exe.stack_size = 0x800000; exe.linkLibC(); @@ -3540,8 +3751,9 @@ fn testZText(b: *Build, opts: Options) *Step { // musl supports only a very limited number of text relocations and only in DSOs (and // rightly so!). - const a_o = addObject(b, "a", opts); - addAsmSourceBytes(a_o, + const a_o = addObject(b, opts, .{ + .name = "a", + .asm_source_bytes = \\.globl fn1 \\fn1: \\ sub $8, %rsp @@ -3549,10 +3761,13 @@ fn testZText(b: *Build, opts: Options) *Step { \\ call *%rax \\ add $8, %rsp \\ ret - ); + \\ + , + }); - const b_o = addObject(b, "b", opts); - addCSourceBytes(b_o, + const b_o = addObject(b, opts, .{ + .name = "b", + .c_source_bytes = \\int fn1(); \\int fn2() { \\ return 3; @@ -3561,15 +3776,16 @@ fn testZText(b: *Build, opts: Options) *Step { \\int fnn() { \\ return fn1(); \\} - , &.{}); - b_o.force_pic = true; + , + .pic = true, + }); - const dso = addSharedLibrary(b, "a", opts); + const dso = addSharedLibrary(b, opts, .{ .name = "a" }); dso.addObject(a_o); dso.addObject(b_o); dso.link_z_notext = true; - const exe = addExecutable(b, "main", opts); + const exe = addExecutable(b, opts, .{ .name = "main" }); addCSourceBytes(exe, \\#include \\int fnn(); @@ -3608,7 +3824,6 @@ const addObject = link.addObject; const addRunArtifact = link.addRunArtifact; const addSharedLibrary = link.addSharedLibrary; const addStaticLibrary = link.addStaticLibrary; -const addZigSourceBytes = link.addZigSourceBytes; const expectLinkErrors = link.expectLinkErrors; const link = @import("link.zig"); const std = @import("std"); diff --git a/test/link/glibc_compat/build.zig b/test/link/glibc_compat/build.zig index a104633fd7..85cbc48e54 100644 --- a/test/link/glibc_compat/build.zig +++ b/test/link/glibc_compat/build.zig @@ -8,9 +8,9 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = t, .root_source_file = .{ .path = "main.c" }, - .target = std.zig.CrossTarget.parse( + .target = b.resolveTargetQuery(std.zig.CrossTarget.parse( .{ .arch_os_abi = t }, - ) catch unreachable, + ) catch unreachable), }); exe.linkLibC(); // TODO: actually test the output diff --git a/test/link/interdependent_static_c_libs/build.zig b/test/link/interdependent_static_c_libs/build.zig index 757c0d419b..01ed218cce 100644 --- a/test/link/interdependent_static_c_libs/build.zig +++ b/test/link/interdependent_static_c_libs/build.zig @@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib_a = b.addStaticLibrary(.{ .name = "a", .optimize = optimize, - .target = .{}, + .target = b.host, }); lib_a.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &[_][]const u8{} }); lib_a.addIncludePath(.{ .path = "." }); @@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib_b = b.addStaticLibrary(.{ .name = "b", .optimize = optimize, - .target = .{}, + .target = b.host, }); lib_b.addCSourceFile(.{ .file = .{ .path = "b.c" }, .flags = &[_][]const u8{} }); lib_b.addIncludePath(.{ .path = "." }); diff --git a/test/link/link.zig b/test/link/link.zig index b08a929d8b..d5bbbe9f4b 100644 --- a/test/link/link.zig +++ b/test/link/link.zig @@ -7,62 +7,160 @@ pub fn build(b: *Build) void { } pub const Options = struct { - target: CrossTarget, + target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode = .Debug, use_llvm: bool = true, use_lld: bool = false, }; -pub fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { - const target = opts.target.zigTriple(b.allocator) catch @panic("OOM"); +pub fn addTestStep(b: *Build, prefix: []const u8, opts: Options) *Step { + const target = opts.target.target.zigTriple(b.allocator) catch @panic("OOM"); const optimize = @tagName(opts.optimize); const use_llvm = if (opts.use_llvm) "llvm" else "no-llvm"; - const name = std.fmt.allocPrint(b.allocator, "test-" ++ prefix ++ "-{s}-{s}-{s}", .{ - target, - optimize, - use_llvm, + const name = std.fmt.allocPrint(b.allocator, "test-{s}-{s}-{s}-{s}", .{ + prefix, target, optimize, use_llvm, }) catch @panic("OOM"); return b.step(name, ""); } -pub fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile { - return b.addExecutable(.{ - .name = name, - .target = opts.target, - .optimize = opts.optimize, - .use_llvm = opts.use_llvm, - .use_lld = opts.use_lld, +const OverlayOptions = struct { + name: []const u8, + asm_source_bytes: ?[]const u8 = null, + c_source_bytes: ?[]const u8 = null, + c_source_flags: []const []const u8 = &.{}, + cpp_source_bytes: ?[]const u8 = null, + cpp_source_flags: []const []const u8 = &.{}, + zig_source_bytes: ?[]const u8 = null, + pic: ?bool = null, + strip: ?bool = null, +}; + +pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Step.Compile { + const compile_step = b.addExecutable(.{ + .name = overlay.name, + .root_source_file = rsf: { + const bytes = overlay.zig_source_bytes orelse break :rsf null; + break :rsf b.addWriteFiles().add("a.zig", bytes); + }, + .target = base.target, + .optimize = base.optimize, + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + .pic = overlay.pic, + .strip = overlay.strip, }); + if (overlay.cpp_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.cpp", bytes), + .flags = overlay.cpp_source_flags, + }); + } + if (overlay.c_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.c", bytes), + .flags = overlay.c_source_flags, + }); + } + if (overlay.asm_source_bytes) |bytes| { + compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes)); + } + return compile_step; } -pub fn addObject(b: *Build, name: []const u8, opts: Options) *Compile { - return b.addObject(.{ - .name = name, - .target = opts.target, - .optimize = opts.optimize, - .use_llvm = opts.use_llvm, - .use_lld = opts.use_lld, +pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Step.Compile { + const compile_step = b.addObject(.{ + .name = overlay.name, + .root_source_file = rsf: { + const bytes = overlay.zig_source_bytes orelse break :rsf null; + break :rsf b.addWriteFiles().add("a.zig", bytes); + }, + .target = base.target, + .optimize = base.optimize, + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + .pic = overlay.pic, + .strip = overlay.strip, }); + if (overlay.cpp_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.cpp", bytes), + .flags = overlay.cpp_source_flags, + }); + } + if (overlay.c_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.c", bytes), + .flags = overlay.c_source_flags, + }); + } + if (overlay.asm_source_bytes) |bytes| { + compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes)); + } + return compile_step; } -pub fn addStaticLibrary(b: *Build, name: []const u8, opts: Options) *Compile { - return b.addStaticLibrary(.{ - .name = name, - .target = opts.target, - .optimize = opts.optimize, - .use_llvm = opts.use_llvm, - .use_lld = opts.use_lld, +pub fn addStaticLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile { + const compile_step = b.addStaticLibrary(.{ + .name = overlay.name, + .root_source_file = rsf: { + const bytes = overlay.zig_source_bytes orelse break :rsf null; + break :rsf b.addWriteFiles().add("a.zig", bytes); + }, + .target = base.target, + .optimize = base.optimize, + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + .pic = overlay.pic, + .strip = overlay.strip, }); + if (overlay.cpp_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.cpp", bytes), + .flags = overlay.cpp_source_flags, + }); + } + if (overlay.c_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.c", bytes), + .flags = overlay.c_source_flags, + }); + } + if (overlay.asm_source_bytes) |bytes| { + compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes)); + } + return compile_step; } -pub fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile { - return b.addSharedLibrary(.{ - .name = name, - .target = opts.target, - .optimize = opts.optimize, - .use_llvm = opts.use_llvm, - .use_lld = opts.use_lld, +pub fn addSharedLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile { + const compile_step = b.addSharedLibrary(.{ + .name = overlay.name, + .root_source_file = rsf: { + const bytes = overlay.zig_source_bytes orelse break :rsf null; + break :rsf b.addWriteFiles().add("a.zig", bytes); + }, + .target = base.target, + .optimize = base.optimize, + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + .pic = overlay.pic, + .strip = overlay.strip, }); + if (overlay.cpp_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.cpp", bytes), + .flags = overlay.cpp_source_flags, + }); + } + if (overlay.c_source_bytes) |bytes| { + compile_step.addCSourceFile(.{ + .file = b.addWriteFiles().add("a.c", bytes), + .flags = overlay.c_source_flags, + }); + } + if (overlay.asm_source_bytes) |bytes| { + compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes)); + } + return compile_step; } pub fn addRunArtifact(comp: *Compile) *Run { @@ -72,13 +170,6 @@ pub fn addRunArtifact(comp: *Compile) *Run { return run; } -pub fn addZigSourceBytes(comp: *Compile, bytes: []const u8) void { - const b = comp.step.owner; - const file = WriteFile.create(b).add("a.zig", bytes); - file.addStepDependencies(&comp.step); - comp.root_src = file; -} - pub fn addCSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void { const b = comp.step.owner; const file = WriteFile.create(b).add("a.c", bytes); diff --git a/test/link/macho.zig b/test/link/macho.zig index f172d9af17..230107c9b2 100644 --- a/test/link/macho.zig +++ b/test/link/macho.zig @@ -1,26 +1,29 @@ //! Here we test our MachO linker for correctness and functionality. //! TODO migrate standalone tests from test/link/macho/* to here. -pub fn testAll(b: *Build) *Step { +pub fn testAll(b: *std.Build) *Step { const macho_step = b.step("test-macho", "Run MachO tests"); - const default_target = CrossTarget{ .os_tag = .macos }; - - macho_step.dependOn(testResolvingBoundarySymbols(b, .{ .target = default_target })); + macho_step.dependOn(testResolvingBoundarySymbols(b, .{ + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), + })); return macho_step; } -fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { +fn testResolvingBoundarySymbols(b: *std.Build, opts: Options) *Step { const test_step = addTestStep(b, "macho-resolving-boundary-symbols", opts); - const obj1 = addObject(b, "obj1", opts); - addCppSourceBytes(obj1, + const obj1 = addObject(b, opts, .{ + .name = "obj1", + .cpp_source_bytes = \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST,__message_ptr"))) = "codebase"; - , &.{}); + , + }); - const main_o = addObject(b, "main", opts); - addZigSourceBytes(main_o, + const main_o = addObject(b, opts, .{ + .name = "main", + .zig_source_bytes = \\const std = @import("std"); \\extern fn interop() [*:0]const u8; \\pub fn main() !void { @@ -28,23 +31,27 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { \\ std.mem.span(interop()), \\ }); \\} - ); + , + }); { - const obj2 = addObject(b, "obj2", opts); - addCppSourceBytes(obj2, + const obj2 = addObject(b, opts, .{ + .name = "obj2", + .cpp_source_bytes = \\extern const char* message_pointer __asm("section$start$__DATA_CONST$__message_ptr"); \\extern "C" const char* interop() { \\ return message_pointer; \\} - , &.{}); + , + }); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); exe.addObject(obj1); exe.addObject(obj2); exe.addObject(main_o); - const run = addRunArtifact(exe); + const run = b.addRunArtifact(exe); + run.skip_foreign_checks = true; run.expectStdErrEqual("All your codebase are belong to us.\n"); test_step.dependOn(&run.step); @@ -55,15 +62,17 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { } { - const obj3 = addObject(b, "obj3", opts); - addCppSourceBytes(obj3, + const obj3 = addObject(b, opts, .{ + .name = "obj3", + .cpp_source_bytes = \\extern const char* message_pointer __asm("section$start$__DATA$__message_ptr"); \\extern "C" const char* interop() { \\ return message_pointer; \\} - , &.{}); + , + }); - const exe = addExecutable(b, "test", opts); + const exe = addExecutable(b, opts, .{ .name = "test" }); exe.addObject(obj1); exe.addObject(obj3); exe.addObject(main_o); @@ -77,20 +86,16 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step { return test_step; } -fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step { +fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step { return link.addTestStep(b, "macho-" ++ prefix, opts); } -const addCppSourceBytes = link.addCppSourceBytes; -const addExecutable = link.addExecutable; const addObject = link.addObject; -const addRunArtifact = link.addRunArtifact; -const addZigSourceBytes = link.addZigSourceBytes; +const addExecutable = link.addExecutable; const expectLinkErrors = link.expectLinkErrors; const link = @import("link.zig"); const std = @import("std"); -const Build = std.Build; const CrossTarget = std.zig.CrossTarget; const Options = link.Options; -const Step = Build.Step; +const Step = std.Build.Step; diff --git a/test/link/macho/bugs/13056/build.zig b/test/link/macho/bugs/13056/build.zig index 5b19daab3c..c7136bbd7f 100644 --- a/test/link/macho/bugs/13056/build.zig +++ b/test/link/macho/bugs/13056/build.zig @@ -14,14 +14,14 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; - const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable; - const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); + const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse @panic("macOS SDK is required to run the test"); const exe = b.addExecutable(.{ .name = "test", .optimize = optimize, + .target = b.host, }); exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) }); exe.addIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include/c++/v1" }) }); diff --git a/test/link/macho/bugs/13457/build.zig b/test/link/macho/bugs/13457/build.zig index 89096bba38..fe835b5715 100644 --- a/test/link/macho/bugs/13457/build.zig +++ b/test/link/macho/bugs/13457/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const exe = b.addExecutable(.{ .name = "test", diff --git a/test/link/macho/bugs/16308/build.zig b/test/link/macho/bugs/16308/build.zig index 3d7a884bd0..f4456b111c 100644 --- a/test/link/macho/bugs/16308/build.zig +++ b/test/link/macho/bugs/16308/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const lib = b.addSharedLibrary(.{ .name = "a", diff --git a/test/link/macho/bugs/16628/build.zig b/test/link/macho/bugs/16628/build.zig index aa396f7a3b..59c666aa27 100644 --- a/test/link/macho/bugs/16628/build.zig +++ b/test/link/macho/bugs/16628/build.zig @@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const exe = b.addExecutable(.{ .name = "test", diff --git a/test/link/macho/dead_strip/build.zig b/test/link/macho/dead_strip/build.zig index 8b8449b6b2..a5bb28df9f 100644 --- a/test/link/macho/dead_strip/build.zig +++ b/test/link/macho/dead_strip/build.zig @@ -4,7 +4,7 @@ pub const requires_symlinks = true; pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const test_step = b.step("test", "Test the program"); b.default_step = test_step; @@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void { fn createScenario( b: *std.Build, optimize: std.builtin.OptimizeMode, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, name: []const u8, ) *std.Build.Step.Compile { const exe = b.addExecutable(.{ diff --git a/test/link/macho/dead_strip_dylibs/build.zig b/test/link/macho/dead_strip_dylibs/build.zig index 52d7f2eac8..7ab8c16dfe 100644 --- a/test/link/macho/dead_strip_dylibs/build.zig +++ b/test/link/macho/dead_strip_dylibs/build.zig @@ -52,6 +52,7 @@ fn createScenario( const exe = b.addExecutable(.{ .name = name, .optimize = optimize, + .target = b.host, }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); exe.linkLibC(); diff --git a/test/link/macho/dylib/build.zig b/test/link/macho/dylib/build.zig index beebfbdd02..abd7175eae 100644 --- a/test/link/macho/dylib/build.zig +++ b/test/link/macho/dylib/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const dylib = b.addSharedLibrary(.{ .name = "a", @@ -55,7 +55,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize check_exe.checkInHeaders(); check_exe.checkExact("cmd RPATH"); - check_exe.checkExactPath("path", dylib.getOutputDirectorySource()); + check_exe.checkExactPath("path", dylib.getEmittedBinDirectory()); test_step.dependOn(&check_exe.step); const run = b.addRunArtifact(exe); diff --git a/test/link/macho/empty/build.zig b/test/link/macho/empty/build.zig index 6a13507702..af38930ae8 100644 --- a/test/link/macho/empty/build.zig +++ b/test/link/macho/empty/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const exe = b.addExecutable(.{ .name = "test", diff --git a/test/link/macho/entry/build.zig b/test/link/macho/entry/build.zig index 9675935a9c..0ef717f292 100644 --- a/test/link/macho/entry/build.zig +++ b/test/link/macho/entry/build.zig @@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "main", .optimize = optimize, - .target = .{ .os_tag = .macos }, + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); exe.linkLibC(); diff --git a/test/link/macho/entry_in_archive/build.zig b/test/link/macho/entry_in_archive/build.zig index f48e612d95..72f340b204 100644 --- a/test/link/macho/entry_in_archive/build.zig +++ b/test/link/macho/entry_in_archive/build.zig @@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addStaticLibrary(.{ .name = "main", .optimize = optimize, - .target = .{ .os_tag = .macos }, + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), }); lib.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); lib.linkLibC(); @@ -24,7 +24,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "main", .optimize = optimize, - .target = .{ .os_tag = .macos }, + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), }); exe.linkLibrary(lib); exe.linkLibC(); diff --git a/test/link/macho/entry_in_dylib/build.zig b/test/link/macho/entry_in_dylib/build.zig index 5b93541a5a..7827552bcf 100644 --- a/test/link/macho/entry_in_dylib/build.zig +++ b/test/link/macho/entry_in_dylib/build.zig @@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addSharedLibrary(.{ .name = "bootstrap", .optimize = optimize, - .target = .{ .os_tag = .macos }, + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), }); lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} }); lib.linkLibC(); @@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "main", .optimize = optimize, - .target = .{ .os_tag = .macos }, + .target = b.resolveTargetQuery(.{ .os_tag = .macos }), }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); exe.linkLibrary(lib); diff --git a/test/link/macho/headerpad/build.zig b/test/link/macho/headerpad/build.zig index 3c0bb7c572..b982224e85 100644 --- a/test/link/macho/headerpad/build.zig +++ b/test/link/macho/headerpad/build.zig @@ -112,6 +112,7 @@ fn simpleExe( const exe = b.addExecutable(.{ .name = name, .optimize = optimize, + .target = b.host, }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} }); exe.linkLibC(); diff --git a/test/link/macho/linksection/build.zig b/test/link/macho/linksection/build.zig index 113034f96f..91ddfe530c 100644 --- a/test/link/macho/linksection/build.zig +++ b/test/link/macho/linksection/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target = std.zig.CrossTarget{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const obj = b.addObject(.{ .name = "test", diff --git a/test/link/macho/needed_framework/build.zig b/test/link/macho/needed_framework/build.zig index 45c046fe0b..83a3e75e2d 100644 --- a/test/link/macho/needed_framework/build.zig +++ b/test/link/macho/needed_framework/build.zig @@ -19,6 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "test", .optimize = optimize, + .target = b.host, }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); exe.linkLibC(); diff --git a/test/link/macho/needed_library/build.zig b/test/link/macho/needed_library/build.zig index cc9d2bd646..a07493a8b1 100644 --- a/test/link/macho/needed_library/build.zig +++ b/test/link/macho/needed_library/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const dylib = b.addSharedLibrary(.{ .name = "a", @@ -33,7 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); exe.linkLibC(); - exe.linkSystemLibraryNeeded("a"); + exe.root_module.linkSystemLibrary("a", .{ .needed = true }); exe.addLibraryPath(dylib.getEmittedBinDirectory()); exe.addRPath(dylib.getEmittedBinDirectory()); exe.dead_strip_dylibs = true; diff --git a/test/link/macho/objc/build.zig b/test/link/macho/objc/build.zig index 979c0aa943..26bbdc2673 100644 --- a/test/link/macho/objc/build.zig +++ b/test/link/macho/objc/build.zig @@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "test", .optimize = optimize, + .target = b.host, }); exe.addIncludePath(.{ .path = "." }); exe.addCSourceFile(.{ .file = .{ .path = "Foo.m" }, .flags = &[0][]const u8{} }); diff --git a/test/link/macho/objcpp/build.zig b/test/link/macho/objcpp/build.zig index 183d3cb9d3..53743fafdf 100644 --- a/test/link/macho/objcpp/build.zig +++ b/test/link/macho/objcpp/build.zig @@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "test", .optimize = optimize, + .target = b.host, }); b.default_step.dependOn(&exe.step); exe.addIncludePath(.{ .path = "." }); diff --git a/test/link/macho/pagezero/build.zig b/test/link/macho/pagezero/build.zig index 1ca7f28f11..cee2aa9fd5 100644 --- a/test/link/macho/pagezero/build.zig +++ b/test/link/macho/pagezero/build.zig @@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); { const exe = b.addExecutable(.{ diff --git a/test/link/macho/reexports/build.zig b/test/link/macho/reexports/build.zig index d9a9481fa0..44c96ecf7e 100644 --- a/test/link/macho/reexports/build.zig +++ b/test/link/macho/reexports/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const lib = b.addStaticLibrary(.{ .name = "a", diff --git a/test/link/macho/search_strategy/build.zig b/test/link/macho/search_strategy/build.zig index b76de65b0e..181d2df91a 100644 --- a/test/link/macho/search_strategy/build.zig +++ b/test/link/macho/search_strategy/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); { // -search_dylibs_first @@ -45,9 +45,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize fn createScenario( b: *std.Build, optimize: std.builtin.OptimizeMode, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, name: []const u8, - search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy, + search_strategy: std.Build.Module.SystemLib.SearchStrategy, ) *std.Build.Step.Compile { const static = b.addStaticLibrary(.{ .name = name, diff --git a/test/link/macho/stack_size/build.zig b/test/link/macho/stack_size/build.zig index 48496bd9d5..28a2602ea5 100644 --- a/test/link/macho/stack_size/build.zig +++ b/test/link/macho/stack_size/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const exe = b.addExecutable(.{ .name = "main", diff --git a/test/link/macho/strict_validation/build.zig b/test/link/macho/strict_validation/build.zig index 1cfaac4910..f35438369c 100644 --- a/test/link/macho/strict_validation/build.zig +++ b/test/link/macho/strict_validation/build.zig @@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const exe = b.addExecutable(.{ .name = "main", diff --git a/test/link/macho/tbdv3/build.zig b/test/link/macho/tbdv3/build.zig index ba11004f29..547f72c25f 100644 --- a/test/link/macho/tbdv3/build.zig +++ b/test/link/macho/tbdv3/build.zig @@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const lib = b.addSharedLibrary(.{ .name = "a", diff --git a/test/link/macho/tls/build.zig b/test/link/macho/tls/build.zig index 443f698ea6..af2ac8a9c6 100644 --- a/test/link/macho/tls/build.zig +++ b/test/link/macho/tls/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const lib = b.addSharedLibrary(.{ .name = "a", diff --git a/test/link/macho/unwind_info/build.zig b/test/link/macho/unwind_info/build.zig index 96c4a67568..534cc4e51a 100644 --- a/test/link/macho/unwind_info/build.zig +++ b/test/link/macho/unwind_info/build.zig @@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); testUnwindInfo(b, test_step, optimize, target, false, "no-dead-strip"); testUnwindInfo(b, test_step, optimize, target, true, "yes-dead-strip"); @@ -24,7 +24,7 @@ fn testUnwindInfo( b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, dead_strip: bool, name: []const u8, ) void { @@ -66,7 +66,7 @@ fn testUnwindInfo( fn createScenario( b: *std.Build, optimize: std.builtin.OptimizeMode, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, name: []const u8, ) *std.Build.Step.Compile { const exe = b.addExecutable(.{ diff --git a/test/link/macho/weak_framework/build.zig b/test/link/macho/weak_framework/build.zig index dfb41b7457..2a430443d4 100644 --- a/test/link/macho/weak_framework/build.zig +++ b/test/link/macho/weak_framework/build.zig @@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "test", .optimize = optimize, + .target = b.host, }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); exe.linkLibC(); diff --git a/test/link/macho/weak_library/build.zig b/test/link/macho/weak_library/build.zig index 7ae7c7c2d6..0d73b9f4ea 100644 --- a/test/link/macho/weak_library/build.zig +++ b/test/link/macho/weak_library/build.zig @@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void { } fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { - const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + const target = b.resolveTargetQuery(.{ .os_tag = .macos }); const dylib = b.addSharedLibrary(.{ .name = "a", @@ -32,7 +32,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize }); exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} }); exe.linkLibC(); - exe.linkSystemLibraryWeak("a"); + exe.root_module.linkSystemLibrary("a", .{ .weak = true }); exe.addLibraryPath(dylib.getEmittedBinDirectory()); exe.addRPath(dylib.getEmittedBinDirectory()); diff --git a/test/link/static_libs_from_object_files/build.zig b/test/link/static_libs_from_object_files/build.zig index e5a4b79acd..d0ea78bbd6 100644 --- a/test/link/static_libs_from_object_files/build.zig +++ b/test/link/static_libs_from_object_files/build.zig @@ -59,7 +59,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built .name = "test1", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = .{}, + .target = b.host, }); for (files) |file| { @@ -77,12 +77,12 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built { const lib_a = b.addStaticLibrary(.{ .name = "test2_a", - .target = .{}, + .target = b.host, .optimize = optimize, }); const lib_b = b.addStaticLibrary(.{ .name = "test2_b", - .target = .{}, + .target = b.host, .optimize = optimize, }); @@ -94,6 +94,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built const exe = b.addExecutable(.{ .name = "test2", .root_source_file = .{ .path = "main.zig" }, + .target = b.host, .optimize = optimize, }); exe.linkLibrary(lib_a); @@ -110,19 +111,19 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built { const lib_a = b.addStaticLibrary(.{ .name = "test3_a", - .target = .{}, + .target = b.host, .optimize = optimize, }); const lib_b = b.addStaticLibrary(.{ .name = "test3_b", - .target = .{}, + .target = b.host, .optimize = optimize, }); for (files, 1..) |file, i| { const obj = b.addObject(.{ .name = b.fmt("obj_{}", .{i}), - .target = .{}, + .target = b.host, .optimize = optimize, }); obj.addCSourceFile(.{ .file = file, .flags = &flags }); @@ -134,6 +135,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built const exe = b.addExecutable(.{ .name = "test3", .root_source_file = .{ .path = "main.zig" }, + .target = b.host, .optimize = optimize, }); exe.linkLibrary(lib_a); diff --git a/test/link/wasm/archive/build.zig b/test/link/wasm/archive/build.zig index 95aea2913e..1d5e031848 100644 --- a/test/link/wasm/archive/build.zig +++ b/test/link/wasm/archive/build.zig @@ -20,11 +20,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; const check = lib.checkObject(); check.checkInHeaders(); diff --git a/test/link/wasm/basic-features/build.zig b/test/link/wasm/basic-features/build.zig index 9cf28ea31e..6f9e82d09d 100644 --- a/test/link/wasm/basic-features/build.zig +++ b/test/link/wasm/basic-features/build.zig @@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void { .name = "lib", .root_source_file = .{ .path = "main.zig" }, .optimize = .Debug, - .target = .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, .cpu_features_add = std.Target.wasm.featureSet(&.{.atomics}), .os_tag = .freestanding, - }, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/bss/build.zig b/test/link/wasm/bss/build.zig index c569225f8b..3a1592f394 100644 --- a/test/link/wasm/bss/build.zig +++ b/test/link/wasm/bss/build.zig @@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize_mode, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; // to make sure the bss segment is emitted, we must import memory lib.import_memory = true; lib.link_gc_sections = false; @@ -65,13 +65,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib2.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize_mode, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; // to make sure the bss segment is emitted, we must import memory lib.import_memory = true; lib.link_gc_sections = false; diff --git a/test/link/wasm/export-data/build.zig b/test/link/wasm/export-data/build.zig index f1bba98d5f..bba00d5c12 100644 --- a/test/link/wasm/export-data/build.zig +++ b/test/link/wasm/export-data/build.zig @@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void { }); lib.entry = .disabled; lib.use_lld = false; - lib.export_symbol_names = &.{ "foo", "bar" }; + lib.root_module.export_symbol_names = &.{ "foo", "bar" }; lib.global_base = 0; // put data section at address 0 to make data symbols easier to parse const check_lib = lib.checkObject(); diff --git a/test/link/wasm/export/build.zig b/test/link/wasm/export/build.zig index 2183ccd585..ab2893ce3c 100644 --- a/test/link/wasm/export/build.zig +++ b/test/link/wasm/export/build.zig @@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .name = "no-export", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), }); no_export.entry = .disabled; no_export.use_llvm = false; @@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .name = "dynamic", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), }); dynamic_export.entry = .disabled; dynamic_export.rdynamic = true; @@ -38,10 +38,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .name = "force", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), }); force_export.entry = .disabled; - force_export.export_symbol_names = &.{"foo"}; + force_export.root_module.export_symbol_names = &.{"foo"}; force_export.use_llvm = false; force_export.use_lld = false; diff --git a/test/link/wasm/extern-mangle/build.zig b/test/link/wasm/extern-mangle/build.zig index d361dc140e..41a00eefc9 100644 --- a/test/link/wasm/extern-mangle/build.zig +++ b/test/link/wasm/extern-mangle/build.zig @@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, }); lib.entry = .disabled; diff --git a/test/link/wasm/extern/build.zig b/test/link/wasm/extern/build.zig index a505899520..baa2b6d61e 100644 --- a/test/link/wasm/extern/build.zig +++ b/test/link/wasm/extern/build.zig @@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .name = "extern", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }), }); exe.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} }); exe.use_llvm = false; diff --git a/test/link/wasm/function-table/build.zig b/test/link/wasm/function-table/build.zig index 5a139acb3e..aca66e4f71 100644 --- a/test/link/wasm/function-table/build.zig +++ b/test/link/wasm/function-table/build.zig @@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const import_table = b.addExecutable(.{ .name = "import_table", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, }); import_table.entry = .disabled; @@ -28,7 +28,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const export_table = b.addExecutable(.{ .name = "export_table", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, }); export_table.entry = .disabled; @@ -40,7 +40,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const regular_table = b.addExecutable(.{ .name = "regular_table", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, }); regular_table.entry = .disabled; diff --git a/test/link/wasm/infer-features/build.zig b/test/link/wasm/infer-features/build.zig index c883063dc5..e3fe860f54 100644 --- a/test/link/wasm/infer-features/build.zig +++ b/test/link/wasm/infer-features/build.zig @@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void { const c_obj = b.addObject(.{ .name = "c_obj", .optimize = .Debug, - .target = .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge }, .os_tag = .freestanding, - }, + }), }); c_obj.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} }); @@ -21,11 +21,11 @@ pub fn build(b: *std.Build) void { .name = "lib", .root_source_file = .{ .path = "main.zig" }, .optimize = .Debug, - .target = .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, .os_tag = .freestanding, - }, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/producers/build.zig b/test/link/wasm/producers/build.zig index b66521a456..4fb777e123 100644 --- a/test/link/wasm/producers/build.zig +++ b/test/link/wasm/producers/build.zig @@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; b.installArtifact(lib); const version_fmt = "version " ++ builtin.zig_version_string; diff --git a/test/link/wasm/segments/build.zig b/test/link/wasm/segments/build.zig index 6ab2e4a7a3..86073ff977 100644 --- a/test/link/wasm/segments/build.zig +++ b/test/link/wasm/segments/build.zig @@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; lib.link_gc_sections = false; // so data is not garbage collected and we can verify data section b.installArtifact(lib); diff --git a/test/link/wasm/shared-memory/build.zig b/test/link/wasm/shared-memory/build.zig index a1d660d135..f8751d99c0 100644 --- a/test/link/wasm/shared-memory/build.zig +++ b/test/link/wasm/shared-memory/build.zig @@ -21,16 +21,16 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt .os_tag = .freestanding, }, .optimize = optimize_mode, + .strip = false, + .single_threaded = false, }); lib.entry = .disabled; lib.use_lld = false; - lib.strip = false; lib.import_memory = true; lib.export_memory = true; lib.shared_memory = true; lib.max_memory = 67108864; - lib.single_threaded = false; - lib.export_symbol_names = &.{"foo"}; + lib.root_module.export_symbol_names = &.{"foo"}; const check_lib = lib.checkObject(); diff --git a/test/link/wasm/stack_pointer/build.zig b/test/link/wasm/stack_pointer/build.zig index 93c0f10e14..e95c27827e 100644 --- a/test/link/wasm/stack_pointer/build.zig +++ b/test/link/wasm/stack_pointer/build.zig @@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size lib.link_gc_sections = false; b.installArtifact(lib); diff --git a/test/link/wasm/type/build.zig b/test/link/wasm/type/build.zig index 88ded91403..a318ddb1f9 100644 --- a/test/link/wasm/type/build.zig +++ b/test/link/wasm/type/build.zig @@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const lib = b.addExecutable(.{ .name = "lib", .root_source_file = .{ .path = "lib.zig" }, - .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding }, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), .optimize = optimize, + .strip = false, }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.strip = false; b.installArtifact(lib); const check_lib = lib.checkObject(); diff --git a/test/llvm_targets.zig b/test/llvm_targets.zig index 6f01925a9f..6a3139dd9f 100644 --- a/test/llvm_targets.zig +++ b/test/llvm_targets.zig @@ -127,17 +127,21 @@ const targets = [_]std.zig.CrossTarget{ .{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none }, }; -pub fn addCases(ctx: *Cases, build_options: @import("cases.zig").BuildOptions) !void { +pub fn addCases( + ctx: *Cases, + build_options: @import("cases.zig").BuildOptions, + b: *std.Build, +) !void { if (!build_options.enable_llvm) return; - for (targets) |target| { - if (target.cpu_arch) |arch| switch (arch) { + for (targets) |target_query| { + if (target_query.cpu_arch) |arch| switch (arch) { .m68k => if (!build_options.llvm_has_m68k) continue, .csky => if (!build_options.llvm_has_csky) continue, .arc => if (!build_options.llvm_has_arc) continue, .xtensa => if (!build_options.llvm_has_xtensa) continue, else => {}, }; - var case = ctx.noEmitUsingLlvmBackend("llvm_targets", target); + var case = ctx.noEmitUsingLlvmBackend("llvm_targets", b.resolveTargetQuery(target_query)); case.addCompile(""); } } diff --git a/test/nvptx.zig b/test/nvptx.zig index c3748570e8..fd4c66db89 100644 --- a/test/nvptx.zig +++ b/test/nvptx.zig @@ -1,9 +1,14 @@ const std = @import("std"); const Cases = @import("src/Cases.zig"); -pub fn addCases(ctx: *Cases) !void { +pub fn addCases(ctx: *Cases, b: *std.Build) !void { + const target = b.resolveTargetQuery(.{ + .cpu_arch = .nvptx64, + .os_tag = .cuda, + }); + { - var case = addPtx(ctx, "simple addition and subtraction"); + var case = addPtx(ctx, target, "simple addition and subtraction"); case.addCompile( \\fn add(a: i32, b: i32) i32 { @@ -20,7 +25,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = addPtx(ctx, "read special registers"); + var case = addPtx(ctx, target, "read special registers"); case.addCompile( \\fn threadIdX() u32 { @@ -37,7 +42,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = addPtx(ctx, "address spaces"); + var case = addPtx(ctx, target, "address spaces"); case.addCompile( \\var x: i32 addrspace(.global) = 0; @@ -50,7 +55,7 @@ pub fn addCases(ctx: *Cases) !void { } { - var case = addPtx(ctx, "reduce in shared mem"); + var case = addPtx(ctx, target, "reduce in shared mem"); case.addCompile( \\fn threadIdX() u32 { \\ return asm ("mov.u32 \t%[r], %tid.x;" @@ -82,18 +87,10 @@ pub fn addCases(ctx: *Cases) !void { } } -const nvptx_target = std.zig.CrossTarget{ - .cpu_arch = .nvptx64, - .os_tag = .cuda, -}; - -pub fn addPtx( - ctx: *Cases, - name: []const u8, -) *Cases.Case { +fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Cases.Case { ctx.cases.append(.{ .name = name, - .target = nvptx_target, + .target = target, .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator), .output_mode = .Obj, .deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator), diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 262f8e9ac7..2aa92fc908 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -76,7 +76,7 @@ pub const Case = struct { name: []const u8, /// The platform the test targets. For non-native platforms, an emulator /// such as QEMU is required for tests to complete. - target: CrossTarget, + target: std.Build.ResolvedTarget, /// In order to be able to run e.g. Execution updates, this must be set /// to Executable. output_mode: std.builtin.OutputMode, @@ -155,7 +155,7 @@ pub const Translate = struct { name: []const u8, input: [:0]const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, link_libc: bool, c_frontend: CFrontend, kind: union(enum) { @@ -171,7 +171,7 @@ pub const Translate = struct { pub fn addExe( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, ) *Case { ctx.cases.append(Case{ .name = name, @@ -184,16 +184,16 @@ pub fn addExe( } /// Adds a test case for Zig input, producing an executable -pub fn exe(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { return ctx.addExe(name, target); } -pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { - var target_adjusted = target; - target_adjusted.ofmt = .c; +pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.zig.CrossTarget, b: *std.Build) *Case { + var adjusted_query = target_query; + adjusted_query.ofmt = .c; ctx.cases.append(Case{ .name = name, - .target = target_adjusted, + .target = b.resolveTargetQuery(adjusted_query), .updates = std.ArrayList(Update).init(ctx.cases.allocator), .output_mode = .Exe, .deps = std.ArrayList(DepModule).init(ctx.arena), @@ -202,7 +202,7 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Cas return &ctx.cases.items[ctx.cases.items.len - 1]; } -pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { ctx.cases.append(Case{ .name = name, .target = target, @@ -217,7 +217,7 @@ pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget /// Adds a test case that uses the LLVM backend to emit an executable. /// Currently this implies linking libc, because only then we can generate a testable executable. -pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { ctx.cases.append(Case{ .name = name, .target = target, @@ -233,7 +233,7 @@ pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) * pub fn addObj( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, ) *Case { ctx.cases.append(Case{ .name = name, @@ -248,7 +248,7 @@ pub fn addObj( pub fn addTest( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, ) *Case { ctx.cases.append(Case{ .name = name, @@ -262,17 +262,17 @@ pub fn addTest( } /// Adds a test case for Zig input, producing an object file. -pub fn obj(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn obj(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { return ctx.addObj(name, target); } /// Adds a test case for ZIR input, producing an object file. -pub fn objZIR(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn objZIR(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { return ctx.addObj(name, target, .ZIR); } /// Adds a test case for Zig or ZIR input, producing C code. -pub fn addC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case { +pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case { var target_adjusted = target; target_adjusted.ofmt = std.Target.ObjectFormat.c; ctx.cases.append(Case{ @@ -308,7 +308,7 @@ pub fn compareOutput( pub fn addTransform( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, src: [:0]const u8, result: [:0]const u8, ) void { @@ -320,7 +320,7 @@ pub fn addTransform( pub fn transform( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, src: [:0]const u8, result: [:0]const u8, ) void { @@ -330,7 +330,7 @@ pub fn transform( pub fn addError( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, src: [:0]const u8, expected_errors: []const []const u8, ) void { @@ -343,7 +343,7 @@ pub fn addError( pub fn compileError( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, src: [:0]const u8, expected_errors: []const []const u8, ) void { @@ -355,7 +355,7 @@ pub fn compileError( pub fn addCompile( ctx: *Cases, name: []const u8, - target: CrossTarget, + target: std.Build.ResolvedTarget, src: [:0]const u8, ) void { ctx.addObj(name, target).addCompile(src); @@ -368,9 +368,9 @@ pub fn addCompile( /// Each file should include a test manifest as a contiguous block of comments at /// the end of the file. The first line should be the test type, followed by a set of /// key-value config values, followed by a blank line, then the expected output. -pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir) void { +pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir, b: *std.Build) void { var current_file: []const u8 = "none"; - ctx.addFromDirInner(dir, ¤t_file) catch |err| { + ctx.addFromDirInner(dir, ¤t_file, b) catch |err| { std.debug.panicExtra( @errorReturnTrace(), @returnAddress(), @@ -386,6 +386,7 @@ fn addFromDirInner( /// This is kept up to date with the currently being processed file so /// that if any errors occur the caller knows it happened during this file. current_file: *[]const u8, + b: *std.Build, ) !void { var it = try iterable_dir.walk(ctx.arena); var filenames = std.ArrayList([]const u8).init(ctx.arena); @@ -422,7 +423,7 @@ fn addFromDirInner( var manifest = try TestManifest.parse(ctx.arena, src); const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend); - const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget); + const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.zig.CrossTarget); const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); @@ -430,12 +431,12 @@ fn addFromDirInner( if (manifest.type == .translate_c) { for (c_frontends) |c_frontend| { - for (targets) |target| { + for (targets) |target_query| { const output = try manifest.trailingLinesSplit(ctx.arena); try ctx.translate.append(.{ .name = std.fs.path.stem(filename), .c_frontend = c_frontend, - .target = target, + .target = b.resolveTargetQuery(target_query), .link_libc = link_libc, .input = src, .kind = .{ .translate = output }, @@ -446,12 +447,12 @@ fn addFromDirInner( } if (manifest.type == .run_translated_c) { for (c_frontends) |c_frontend| { - for (targets) |target| { + for (targets) |target_query| { const output = try manifest.trailingSplit(ctx.arena); try ctx.translate.append(.{ .name = std.fs.path.stem(filename), .c_frontend = c_frontend, - .target = target, + .target = b.resolveTargetQuery(target_query), .link_libc = link_libc, .input = src, .kind = .{ .run = output }, @@ -464,16 +465,18 @@ fn addFromDirInner( var cases = std.ArrayList(usize).init(ctx.arena); // Cross-product to get all possible test combinations - for (backends) |backend| { - for (targets) |target| { + for (targets) |target_query| { + const resolved_target = b.resolveTargetQuery(target_query); + const target = resolved_target.target; + for (backends) |backend| { if (backend == .stage2 and - target.getCpuArch() != .wasm32 and target.getCpuArch() != .x86_64) + target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64) { // Other backends don't support new liveness format continue; } - if (backend == .stage2 and target.getOsTag() == .macos and - target.getCpuArch() == .x86_64 and builtin.cpu.arch == .aarch64) + if (backend == .stage2 and target.os.tag == .macos and + target.cpu.arch == .x86_64 and builtin.cpu.arch == .aarch64) { // Rosetta has issues with ZLD continue; @@ -482,7 +485,7 @@ fn addFromDirInner( const next = ctx.cases.items.len; try ctx.cases.append(.{ .name = std.fs.path.stem(filename), - .target = target, + .target = resolved_target, .backend = backend, .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator), .is_test = is_test, @@ -622,8 +625,8 @@ pub fn lowerToBuildSteps( } for (case.deps.items) |dep| { - artifact.addAnonymousModule(dep.name, .{ - .source_file = file_sources.get(dep.path).?, + artifact.root_module.addAnonymousImport(dep.name, .{ + .root_source_file = file_sources.get(dep.path).?, }); } @@ -644,9 +647,8 @@ pub fn lowerToBuildSteps( parent_step.dependOn(&artifact.step); }, .Execution => |expected_stdout| no_exec: { - const run = if (case.target.ofmt == .c) run_step: { - const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err| - std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)}); + const run = if (case.target.target.ofmt == .c) run_step: { + const target_info = case.target.toNativeTargetInfo(); if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. break :no_exec; @@ -666,7 +668,7 @@ pub fn lowerToBuildSteps( "--", "-lc", "-target", - case.target.zigTriple(b.allocator) catch @panic("OOM"), + case.target.target.zigTriple(b.allocator) catch @panic("OOM"), }); run_c.addArtifactArg(artifact); break :run_step run_c; @@ -692,8 +694,7 @@ pub fn lowerToBuildSteps( continue; // Pass test. } - const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err| - std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)}); + const target_info = case.target.toNativeTargetInfo(); if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. continue; // Pass test. @@ -1159,9 +1160,9 @@ const TestManifest = struct { } fn getDefaultParser(comptime T: type) ParseFn(T) { - if (T == CrossTarget) return struct { + if (T == std.zig.CrossTarget) return struct { fn parse(str: []const u8) anyerror!T { - return CrossTarget.parse(.{ .arch_os_abi = str }); + return std.zig.CrossTarget.parse(.{ .arch_os_abi = str }); } }.parse; @@ -1198,7 +1199,6 @@ const builtin = @import("builtin"); const std = @import("std"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; -const CrossTarget = std.zig.CrossTarget; const Compilation = @import("../../src/Compilation.zig"); const zig_h = @import("../../src/link.zig").File.C.zig_h; const introspect = @import("../../src/introspect.zig"); @@ -1287,7 +1287,7 @@ pub fn main() !void { if (cases.items.len == 0) { const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend); - const targets = try manifest.getConfigForKeyAlloc(arena, "target", CrossTarget); + const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.zig.CrossTarget); const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); @@ -1295,12 +1295,12 @@ pub fn main() !void { if (manifest.type == .translate_c) { for (c_frontends) |c_frontend| { - for (targets) |target| { + for (targets) |target_query| { const output = try manifest.trailingLinesSplit(ctx.arena); try ctx.translate.append(.{ .name = std.fs.path.stem(filename), .c_frontend = c_frontend, - .target = target, + .target = resolveTargetQuery(target_query), .is_test = is_test, .link_libc = link_libc, .input = src, @@ -1312,12 +1312,12 @@ pub fn main() !void { } if (manifest.type == .run_translated_c) { for (c_frontends) |c_frontend| { - for (targets) |target| { + for (targets) |target_query| { const output = try manifest.trailingSplit(ctx.arena); try ctx.translate.append(.{ .name = std.fs.path.stem(filename), .c_frontend = c_frontend, - .target = target, + .target = resolveTargetQuery(target_query), .is_test = is_test, .link_libc = link_libc, .output = output, @@ -1385,6 +1385,17 @@ pub fn main() !void { return runCases(&ctx, zig_exe_path); } +fn resolveTargetQuery(query: std.zig.CrossTarget) std.Build.ResolvedTarget { + const result = std.zig.system.NativeTargetInfo.detect(query) catch + @panic("unable to resolve target query"); + + return .{ + .query = query, + .target = result.target, + .dynamic_linker = result.dynamic_linker, + }; +} + fn runCases(self: *Cases, zig_exe_path: []const u8) !void { const host = try std.zig.system.NativeTargetInfo.detect(.{}); diff --git a/test/src/CompareOutput.zig b/test/src/CompareOutput.zig index 39226f0369..b3570b6ee2 100644 --- a/test/src/CompareOutput.zig +++ b/test/src/CompareOutput.zig @@ -96,7 +96,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { const exe = b.addExecutable(.{ .name = "test", - .target = .{}, + .target = b.host, .optimize = .Debug, }); exe.addAssemblyFile(write_src.files.items[0].getPath()); @@ -121,7 +121,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { .name = "test", .root_source_file = write_src.files.items[0].getPath(), .optimize = optimize, - .target = .{}, + .target = b.host, }); if (case.link_libc) { exe.linkSystemLibrary("c"); @@ -146,7 +146,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { const exe = b.addExecutable(.{ .name = "test", .root_source_file = write_src.files.items[0].getPath(), - .target = .{}, + .target = b.host, .optimize = .Debug, }); if (case.link_libc) { diff --git a/test/src/StackTrace.zig b/test/src/StackTrace.zig index c42e9114be..f0dc9a8c0c 100644 --- a/test/src/StackTrace.zig +++ b/test/src/StackTrace.zig @@ -77,7 +77,7 @@ fn addExpect( .name = "test", .root_source_file = write_src.files.items[0].getPath(), .optimize = optimize_mode, - .target = .{}, + .target = b.host, }); const run = b.addRunArtifact(exe); diff --git a/test/src/run_translated_c.zig b/test/src/run_translated_c.zig index cd2d0d9e3b..544f9a5309 100644 --- a/test/src/run_translated_c.zig +++ b/test/src/run_translated_c.zig @@ -11,7 +11,7 @@ pub const RunTranslatedCContext = struct { step: *std.Build.Step, test_index: usize, test_filter: ?[]const u8, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, const TestCase = struct { name: []const u8, @@ -86,7 +86,7 @@ pub const RunTranslatedCContext = struct { } const translate_c = b.addTranslateC(.{ .source_file = write_src.files.items[0].getPath(), - .target = .{}, + .target = b.host, .optimize = .Debug, }); diff --git a/test/src/translate_c.zig b/test/src/translate_c.zig index a71886099f..71288c11da 100644 --- a/test/src/translate_c.zig +++ b/test/src/translate_c.zig @@ -18,7 +18,7 @@ pub const TranslateCContext = struct { sources: ArrayList(SourceFile), expected_lines: ArrayList([]const u8), allow_warnings: bool, - target: CrossTarget = CrossTarget{}, + target: CrossTarget = .{}, const SourceFile = struct { filename: []const u8, @@ -109,7 +109,7 @@ pub const TranslateCContext = struct { const translate_c = b.addTranslateC(.{ .source_file = write_src.files.items[0].getPath(), - .target = case.target, + .target = b.resolveTargetQuery(case.target), .optimize = .Debug, }); diff --git a/test/standalone.zig b/test/standalone.zig index fc455a2aa7..fdd3185cdf 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -89,10 +89,6 @@ pub const build_cases = [_]BuildCase{ // .build_root = "test/standalone/issue_13970", // .import = @import("standalone/issue_13970/build.zig"), //}, - .{ - .build_root = "test/standalone/main_pkg_path", - .import = @import("standalone/main_pkg_path/build.zig"), - }, .{ .build_root = "test/standalone/shared_library", .import = @import("standalone/shared_library/build.zig"), diff --git a/test/standalone/c_compiler/build.zig b/test/standalone/c_compiler/build.zig index a2191f2f2e..236042d487 100644 --- a/test/standalone/c_compiler/build.zig +++ b/test/standalone/c_compiler/build.zig @@ -23,7 +23,7 @@ fn add( cpp_name: []const u8, optimize: std.builtin.OptimizeMode, ) void { - const target: std.zig.CrossTarget = .{}; + const target = b.host; const exe_c = b.addExecutable(.{ .name = c_name, @@ -42,7 +42,7 @@ fn add( exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} }); exe_cpp.linkLibCpp(); - switch (target.getOsTag()) { + switch (target.target.os.tag) { .windows => { // https://github.com/ziglang/zig/issues/8531 exe_cpp.want_lto = false; diff --git a/test/standalone/child_process/build.zig b/test/standalone/child_process/build.zig index b874a7acc5..89558c00e6 100644 --- a/test/standalone/child_process/build.zig +++ b/test/standalone/child_process/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; if (builtin.os.tag == .wasi) return; diff --git a/test/standalone/compiler_rt_panic/build.zig b/test/standalone/compiler_rt_panic/build.zig index 3d22319bac..cb275e08df 100644 --- a/test/standalone/compiler_rt_panic/build.zig +++ b/test/standalone/compiler_rt_panic/build.zig @@ -4,16 +4,16 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const target = b.standardTargetOptions(.{}); + const resolved_target = b.standardTargetOptions(.{}); + const target = resolved_target.target; const optimize = b.standardOptimizeOption(.{}); - const abi = target.getAbi(); - if (target.getObjectFormat() != .elf or !(abi.isMusl() or abi.isGnu())) return; + if (target.ofmt != .elf or !(target.abi.isMusl() or target.abi.isGnu())) return; const exe = b.addExecutable(.{ .name = "main", .optimize = optimize, - .target = target, + .target = resolved_target, }); exe.linkLibC(); exe.addCSourceFile(.{ diff --git a/test/standalone/dep_diamond/build.zig b/test/standalone/dep_diamond/build.zig index 6c6d9b6d1a..9190b29594 100644 --- a/test/standalone/dep_diamond/build.zig +++ b/test/standalone/dep_diamond/build.zig @@ -7,21 +7,22 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const shared = b.createModule(.{ - .source_file = .{ .path = "shared.zig" }, + .root_source_file = .{ .path = "shared.zig" }, }); const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "test.zig" }, + .target = b.host, .optimize = optimize, }); - exe.addAnonymousModule("foo", .{ - .source_file = .{ .path = "foo.zig" }, - .dependencies = &.{.{ .name = "shared", .module = shared }}, + exe.root_module.addAnonymousImport("foo", .{ + .root_source_file = .{ .path = "foo.zig" }, + .imports = &.{.{ .name = "shared", .module = shared }}, }); - exe.addAnonymousModule("bar", .{ - .source_file = .{ .path = "bar.zig" }, - .dependencies = &.{.{ .name = "shared", .module = shared }}, + exe.root_module.addAnonymousImport("bar", .{ + .root_source_file = .{ .path = "bar.zig" }, + .imports = &.{.{ .name = "shared", .module = shared }}, }); const run = b.addRunArtifact(exe); diff --git a/test/standalone/dep_mutually_recursive/build.zig b/test/standalone/dep_mutually_recursive/build.zig index e70e775401..04589d9b5b 100644 --- a/test/standalone/dep_mutually_recursive/build.zig +++ b/test/standalone/dep_mutually_recursive/build.zig @@ -7,20 +7,21 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const foo = b.createModule(.{ - .source_file = .{ .path = "foo.zig" }, + .root_source_file = .{ .path = "foo.zig" }, }); const bar = b.createModule(.{ - .source_file = .{ .path = "bar.zig" }, + .root_source_file = .{ .path = "bar.zig" }, }); - foo.dependencies.put("bar", bar) catch @panic("OOM"); - bar.dependencies.put("foo", foo) catch @panic("OOM"); + foo.addImport("bar", bar); + bar.addImport("foo", foo); const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "test.zig" }, + .target = b.host, .optimize = optimize, }); - exe.addModule("foo", foo); + exe.root_module.addImport("foo", foo); const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); diff --git a/test/standalone/dep_recursive/build.zig b/test/standalone/dep_recursive/build.zig index 2e2cf4ea4d..a6334e6a97 100644 --- a/test/standalone/dep_recursive/build.zig +++ b/test/standalone/dep_recursive/build.zig @@ -7,16 +7,17 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const foo = b.createModule(.{ - .source_file = .{ .path = "foo.zig" }, + .root_source_file = .{ .path = "foo.zig" }, }); - foo.dependencies.put("foo", foo) catch @panic("OOM"); + foo.addImport("foo", foo); const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "test.zig" }, + .target = b.host, .optimize = optimize, }); - exe.addModule("foo", foo); + exe.root_module.addImport("foo", foo); const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); diff --git a/test/standalone/dep_shared_builtin/build.zig b/test/standalone/dep_shared_builtin/build.zig index 175118d331..33d53ad166 100644 --- a/test/standalone/dep_shared_builtin/build.zig +++ b/test/standalone/dep_shared_builtin/build.zig @@ -9,10 +9,11 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "test.zig" }, + .target = b.host, .optimize = optimize, }); - exe.addAnonymousModule("foo", .{ - .source_file = .{ .path = "foo.zig" }, + exe.root_module.addAnonymousImport("foo", .{ + .root_source_file = .{ .path = "foo.zig" }, }); const run = b.addRunArtifact(exe); diff --git a/test/standalone/dep_triangle/build.zig b/test/standalone/dep_triangle/build.zig index 63eed997ce..b155554997 100644 --- a/test/standalone/dep_triangle/build.zig +++ b/test/standalone/dep_triangle/build.zig @@ -7,19 +7,20 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const shared = b.createModule(.{ - .source_file = .{ .path = "shared.zig" }, + .root_source_file = .{ .path = "shared.zig" }, }); const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "test.zig" }, + .target = b.host, .optimize = optimize, }); - exe.addAnonymousModule("foo", .{ - .source_file = .{ .path = "foo.zig" }, - .dependencies = &.{.{ .name = "shared", .module = shared }}, + exe.root_module.addAnonymousImport("foo", .{ + .root_source_file = .{ .path = "foo.zig" }, + .imports = &.{.{ .name = "shared", .module = shared }}, }); - exe.addModule("shared", shared); + exe.root_module.addImport("shared", shared); const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); diff --git a/test/standalone/embed_generated_file/build.zig b/test/standalone/embed_generated_file/build.zig index ca05c33c39..3f67cdea54 100644 --- a/test/standalone/embed_generated_file/build.zig +++ b/test/standalone/embed_generated_file/build.zig @@ -7,10 +7,10 @@ pub fn build(b: *std.Build) void { const bootloader = b.addExecutable(.{ .name = "bootloader", .root_source_file = .{ .path = "bootloader.zig" }, - .target = .{ + .target = b.resolveTargetQuery(.{ .cpu_arch = .x86, .os_tag = .freestanding, - }, + }), .optimize = .ReleaseSmall, }); @@ -18,8 +18,8 @@ pub fn build(b: *std.Build) void { .root_source_file = .{ .path = "main.zig" }, .optimize = .Debug, }); - exe.addAnonymousModule("bootloader.elf", .{ - .source_file = bootloader.getEmittedBin(), + exe.root_module.addAnonymousImport("bootloader.elf", .{ + .root_source_file = bootloader.getEmittedBin(), }); // TODO: actually check the output diff --git a/test/standalone/empty_env/build.zig b/test/standalone/empty_env/build.zig index 27ec75be22..a2fe483128 100644 --- a/test/standalone/empty_env/build.zig +++ b/test/standalone/empty_env/build.zig @@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void { const main = b.addExecutable(.{ .name = "main", .root_source_file = .{ .path = "main.zig" }, + .target = b.host, .optimize = optimize, }); diff --git a/test/standalone/extern/build.zig b/test/standalone/extern/build.zig index 153380e91d..401deb3dc4 100644 --- a/test/standalone/extern/build.zig +++ b/test/standalone/extern/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "exports", .root_source_file = .{ .path = "exports.zig" }, - .target = .{}, + .target = b.host, .optimize = optimize, }); const main = b.addTest(.{ diff --git a/test/standalone/global_linkage/build.zig b/test/standalone/global_linkage/build.zig index d560027265..13b7fcfa0e 100644 --- a/test/standalone/global_linkage/build.zig +++ b/test/standalone/global_linkage/build.zig @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; const obj1 = b.addStaticLibrary(.{ .name = "obj1", diff --git a/test/standalone/install_raw_hex/build.zig b/test/standalone/install_raw_hex/build.zig index c05490a3e5..d1ec55ab53 100644 --- a/test/standalone/install_raw_hex/build.zig +++ b/test/standalone/install_raw_hex/build.zig @@ -5,12 +5,12 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const target = .{ + const target = b.resolveTargetQuery(.{ .cpu_arch = .thumb, .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 }, .os_tag = .freestanding, .abi = .gnueabihf, - }; + }); const optimize: std.builtin.OptimizeMode = .Debug; diff --git a/test/standalone/ios/build.zig b/test/standalone/ios/build.zig index 1816868844..7642f3a3e8 100644 --- a/test/standalone/ios/build.zig +++ b/test/standalone/ios/build.zig @@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{ + const target = b.resolveTargetQuery(.{ .cpu_arch = .aarch64, .os_tag = .ios, - }; - const target_info = std.zig.system.NativeTargetInfo.detect(target) catch @panic("couldn't detect native target"); - const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse @panic("no iOS SDK found"); + }); + const sdk = std.zig.system.darwin.getSdk(b.allocator, target.target) orelse + @panic("no iOS SDK found"); b.sysroot = sdk; const exe = b.addExecutable(.{ diff --git a/test/standalone/issue_11595/build.zig b/test/standalone/issue_11595/build.zig index e69b4bfdd5..c591b3058b 100644 --- a/test/standalone/issue_11595/build.zig +++ b/test/standalone/issue_11595/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; if (builtin.os.tag == .windows) { // https://github.com/ziglang/zig/issues/12419 diff --git a/test/standalone/issue_12588/build.zig b/test/standalone/issue_12588/build.zig index e6d01192d3..aaf8f6c314 100644 --- a/test/standalone/issue_12588/build.zig +++ b/test/standalone/issue_12588/build.zig @@ -5,13 +5,12 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; const obj = b.addObject(.{ .name = "main", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, - .target = target, + .target = b.host, }); _ = obj.getEmittedLlvmIr(); _ = obj.getEmittedLlvmBc(); diff --git a/test/standalone/issue_12706/build.zig b/test/standalone/issue_12706/build.zig index fb60ac28a1..9a80dae256 100644 --- a/test/standalone/issue_12706/build.zig +++ b/test/standalone/issue_12706/build.zig @@ -1,13 +1,12 @@ const std = @import("std"); const builtin = @import("builtin"); -const CrossTarget = std.zig.CrossTarget; pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; const exe = b.addExecutable(.{ .name = "main", diff --git a/test/standalone/issue_339/build.zig b/test/standalone/issue_339/build.zig index d53ba992ea..5dc686a779 100644 --- a/test/standalone/issue_339/build.zig +++ b/test/standalone/issue_339/build.zig @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; const obj = b.addObject(.{ .name = "test", diff --git a/test/standalone/issue_8550/build.zig b/test/standalone/issue_8550/build.zig index a781561874..557019cfdc 100644 --- a/test/standalone/issue_8550/build.zig +++ b/test/standalone/issue_8550/build.zig @@ -5,13 +5,13 @@ pub fn build(b: *std.Build) !void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target = std.zig.CrossTarget{ + const target = b.resolveTargetQuery(.{ .os_tag = .freestanding, .cpu_arch = .arm, .cpu_model = .{ .explicit = &std.Target.arm.cpu.arm1176jz_s, }, - }; + }); const kernel = b.addExecutable(.{ .name = "kernel", diff --git a/test/standalone/load_dynamic_library/build.zig b/test/standalone/load_dynamic_library/build.zig index 5dc605e711..140f276ebe 100644 --- a/test/standalone/load_dynamic_library/build.zig +++ b/test/standalone/load_dynamic_library/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; if (builtin.os.tag == .wasi) return; diff --git a/test/standalone/main_pkg_path/a/test.zig b/test/standalone/main_pkg_path/a/test.zig deleted file mode 100644 index 286489912b..0000000000 --- a/test/standalone/main_pkg_path/a/test.zig +++ /dev/null @@ -1,5 +0,0 @@ -const b = @import("../b.zig"); - -test "main pkg path" { - b.foo(); -} diff --git a/test/standalone/main_pkg_path/b.zig b/test/standalone/main_pkg_path/b.zig deleted file mode 100644 index 87d61fa63e..0000000000 --- a/test/standalone/main_pkg_path/b.zig +++ /dev/null @@ -1 +0,0 @@ -pub fn foo() void {} diff --git a/test/standalone/main_pkg_path/build.zig b/test/standalone/main_pkg_path/build.zig deleted file mode 100644 index d1b67592b5..0000000000 --- a/test/standalone/main_pkg_path/build.zig +++ /dev/null @@ -1,13 +0,0 @@ -const std = @import("std"); - -pub fn build(b: *std.Build) void { - const test_step = b.step("test", "Test it"); - b.default_step = test_step; - - const test_exe = b.addTest(.{ - .root_source_file = .{ .path = "a/test.zig" }, - .main_pkg_path = .{ .path = "." }, - }); - - test_step.dependOn(&b.addRunArtifact(test_exe).step); -} diff --git a/test/standalone/mix_c_files/build.zig b/test/standalone/mix_c_files/build.zig index b675be9eeb..e91f87e132 100644 --- a/test/standalone/mix_c_files/build.zig +++ b/test/standalone/mix_c_files/build.zig @@ -19,6 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const exe = b.addExecutable(.{ .name = "test", .root_source_file = .{ .path = "main.zig" }, + .target = b.host, .optimize = optimize, }); exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &[_][]const u8{"-std=c11"} }); diff --git a/test/standalone/mix_o_files/build.zig b/test/standalone/mix_o_files/build.zig index 980e52ad3b..aa648145a8 100644 --- a/test/standalone/mix_o_files/build.zig +++ b/test/standalone/mix_o_files/build.zig @@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; const obj = b.addObject(.{ .name = "base64", diff --git a/test/standalone/options/build.zig b/test/standalone/options/build.zig index d87610ba22..97cf91c1fb 100644 --- a/test/standalone/options/build.zig +++ b/test/standalone/options/build.zig @@ -3,7 +3,7 @@ const std = @import("std"); pub fn build(b: *std.Build) void { const main = b.addTest(.{ .root_source_file = .{ .path = "src/main.zig" }, - .target = .{}, + .target = b.host, .optimize = .Debug, }); diff --git a/test/standalone/pie/build.zig b/test/standalone/pie/build.zig index 1efcd5c26e..2e9f99ff4b 100644 --- a/test/standalone/pie/build.zig +++ b/test/standalone/pie/build.zig @@ -5,10 +5,10 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{ + const target = b.resolveTargetQuery(.{ .os_tag = .linux, .cpu_arch = .x86_64, - }; + }); const main = b.addTest(.{ .root_source_file = .{ .path = "main.zig" }, diff --git a/test/standalone/pkg_import/build.zig b/test/standalone/pkg_import/build.zig index 30f4b2ede4..207f924f9b 100644 --- a/test/standalone/pkg_import/build.zig +++ b/test/standalone/pkg_import/build.zig @@ -10,8 +10,9 @@ pub fn build(b: *std.Build) void { .name = "test", .root_source_file = .{ .path = "test.zig" }, .optimize = optimize, + .target = b.host, }); - exe.addAnonymousModule("my_pkg", .{ .source_file = .{ .path = "pkg.zig" } }); + exe.root_module.addAnonymousImport("my_pkg", .{ .root_source_file = .{ .path = "pkg.zig" } }); const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); diff --git a/test/standalone/self_exe_symlink/build.zig b/test/standalone/self_exe_symlink/build.zig index 10e0a6a512..c4720ce967 100644 --- a/test/standalone/self_exe_symlink/build.zig +++ b/test/standalone/self_exe_symlink/build.zig @@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; // The test requires getFdPath in order to to get the path of the // File returned by openSelfExe - if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return; + if (!std.os.isGetFdPathSupportedOnTarget(target.target.os)) return; const main = b.addExecutable(.{ .name = "main", diff --git a/test/standalone/shared_library/build.zig b/test/standalone/shared_library/build.zig index 4b4a154225..4d409295e8 100644 --- a/test/standalone/shared_library/build.zig +++ b/test/standalone/shared_library/build.zig @@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void { } const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; const lib = b.addSharedLibrary(.{ .name = "mathtest", .root_source_file = .{ .path = "mathtest.zig" }, diff --git a/test/standalone/stack_iterator/build.zig b/test/standalone/stack_iterator/build.zig index 628210452c..6a98011e41 100644 --- a/test/standalone/stack_iterator/build.zig +++ b/test/standalone/stack_iterator/build.zig @@ -22,11 +22,10 @@ pub fn build(b: *std.Build) void { .root_source_file = .{ .path = "unwind.zig" }, .target = target, .optimize = optimize, + .unwind_tables = target.target.isDarwin(), + .omit_frame_pointer = false, }); - if (target.isDarwin()) exe.unwind_tables = true; - exe.omit_frame_pointer = false; - const run_cmd = b.addRunArtifact(exe); test_step.dependOn(&run_cmd.step); } @@ -46,11 +45,10 @@ pub fn build(b: *std.Build) void { .root_source_file = .{ .path = "unwind.zig" }, .target = target, .optimize = optimize, + .unwind_tables = true, + .omit_frame_pointer = true, }); - exe.omit_frame_pointer = true; - exe.unwind_tables = true; - const run_cmd = b.addRunArtifact(exe); test_step.dependOn(&run_cmd.step); } @@ -69,11 +67,12 @@ pub fn build(b: *std.Build) void { .name = "c_shared_lib", .target = target, .optimize = optimize, + .strip = false, }); - if (target.isWindows()) c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)"); + if (target.target.os.tag == .windows) + c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)"); - c_shared_lib.strip = false; c_shared_lib.addCSourceFile(.{ .file = .{ .path = "shared_lib.c" }, .flags = &.{"-fomit-frame-pointer"}, @@ -85,10 +84,10 @@ pub fn build(b: *std.Build) void { .root_source_file = .{ .path = "shared_lib_unwind.zig" }, .target = target, .optimize = optimize, + .unwind_tables = target.target.isDarwin(), + .omit_frame_pointer = true, }); - if (target.isDarwin()) exe.unwind_tables = true; - exe.omit_frame_pointer = true; exe.linkLibrary(c_shared_lib); const run_cmd = b.addRunArtifact(exe); diff --git a/test/standalone/static_c_lib/build.zig b/test/standalone/static_c_lib/build.zig index 1e3e80c363..244107b0f1 100644 --- a/test/standalone/static_c_lib/build.zig +++ b/test/standalone/static_c_lib/build.zig @@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void { const foo = b.addStaticLibrary(.{ .name = "foo", .optimize = optimize, - .target = .{}, + .target = b.host, }); foo.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &[_][]const u8{} }); foo.addIncludePath(.{ .path = "." }); diff --git a/test/standalone/strip_empty_loop/build.zig b/test/standalone/strip_empty_loop/build.zig index e64781d991..4875bd9128 100644 --- a/test/standalone/strip_empty_loop/build.zig +++ b/test/standalone/strip_empty_loop/build.zig @@ -5,15 +5,15 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize = std.builtin.OptimizeMode.Debug; - const target = std.zig.CrossTarget{}; + const target = b.host; const main = b.addExecutable(.{ .name = "main", .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, .target = target, + .strip = true, }); - main.strip = true; // TODO: actually check the output _ = main.getEmittedBin(); diff --git a/test/standalone/strip_struct_init/build.zig b/test/standalone/strip_struct_init/build.zig index b67da46819..2d903f973a 100644 --- a/test/standalone/strip_struct_init/build.zig +++ b/test/standalone/strip_struct_init/build.zig @@ -9,8 +9,8 @@ pub fn build(b: *std.Build) void { const main = b.addTest(.{ .root_source_file = .{ .path = "main.zig" }, .optimize = optimize, + .strip = true, }); - main.strip = true; test_step.dependOn(&b.addRunArtifact(main).step); } diff --git a/test/standalone/test_runner_module_imports/build.zig b/test/standalone/test_runner_module_imports/build.zig index f277718898..af8e68d717 100644 --- a/test/standalone/test_runner_module_imports/build.zig +++ b/test/standalone/test_runner_module_imports/build.zig @@ -6,13 +6,13 @@ pub fn build(b: *std.Build) void { .test_runner = "test_runner/main.zig", }); - const module1 = b.createModule(.{ .source_file = .{ .path = "module1/main.zig" } }); + const module1 = b.createModule(.{ .root_source_file = .{ .path = "module1/main.zig" } }); const module2 = b.createModule(.{ - .source_file = .{ .path = "module2/main.zig" }, - .dependencies = &.{.{ .name = "module1", .module = module1 }}, + .root_source_file = .{ .path = "module2/main.zig" }, + .imports = &.{.{ .name = "module1", .module = module1 }}, }); - t.addModule("module2", module2); + t.root_module.addImport("module2", module2); const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&b.addRunArtifact(t).step); diff --git a/test/standalone/windows_resources/build.zig b/test/standalone/windows_resources/build.zig index 9476fa7839..e927a03fc4 100644 --- a/test/standalone/windows_resources/build.zig +++ b/test/standalone/windows_resources/build.zig @@ -4,21 +4,25 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const native_target: std.zig.CrossTarget = .{}; - const cross_target = .{ + const cross_target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu, - }; + }); - add(b, native_target, .any, test_step); + add(b, b.host, .any, test_step); add(b, cross_target, .any, test_step); - add(b, native_target, .gnu, test_step); + add(b, b.host, .gnu, test_step); add(b, cross_target, .gnu, test_step); } -fn add(b: *std.Build, target: std.zig.CrossTarget, rc_includes: enum { any, gnu }, test_step: *std.Build.Step) void { +fn add( + b: *std.Build, + target: std.Build.ResolvedTarget, + rc_includes: enum { any, gnu }, + test_step: *std.Build.Step, +) void { const exe = b.addExecutable(.{ .name = "zig_resource_test", .root_source_file = .{ .path = "main.zig" }, diff --git a/test/standalone/windows_spawn/build.zig b/test/standalone/windows_spawn/build.zig index 6c865f0a9f..a52cbd7202 100644 --- a/test/standalone/windows_spawn/build.zig +++ b/test/standalone/windows_spawn/build.zig @@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const optimize: std.builtin.OptimizeMode = .Debug; - const target: std.zig.CrossTarget = .{}; + const target = b.host; if (builtin.os.tag != .windows) return; diff --git a/test/standalone/zerolength_check/build.zig b/test/standalone/zerolength_check/build.zig index 4e5c1937f7..dacfc841c1 100644 --- a/test/standalone/zerolength_check/build.zig +++ b/test/standalone/zerolength_check/build.zig @@ -13,11 +13,11 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const unit_tests = b.addTest(.{ .root_source_file = .{ .path = "src/main.zig" }, - .target = .{ + .target = b.resolveTargetQuery(.{ .os_tag = .wasi, .cpu_arch = .wasm32, .cpu_features_add = std.Target.wasm.featureSet(&.{.bulk_memory}), - }, + }), .optimize = optimize, }); diff --git a/test/tests.zig b/test/tests.zig index 808ffad6ee..a8f9b62810 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1,7 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); const assert = std.debug.assert; -const CrossTarget = std.zig.CrossTarget; const mem = std.mem; const OptimizeMode = std.builtin.OptimizeMode; const Step = std.Build.Step; @@ -22,13 +21,13 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig"); pub const StackTracesContext = @import("src/StackTrace.zig"); const TestTarget = struct { - target: CrossTarget = .{}, + target: std.zig.CrossTarget = .{}, optimize_mode: std.builtin.OptimizeMode = .Debug, link_libc: ?bool = null, single_threaded: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, - force_pic: ?bool = null, + pic: ?bool = null, strip: ?bool = null, }; @@ -105,7 +104,7 @@ const test_targets = blk: { }, .use_llvm = false, .use_lld = false, - .force_pic = true, + .pic = true, }, .{ .target = .{ @@ -146,7 +145,7 @@ const test_targets = blk: { //}, // https://github.com/ziglang/zig/issues/13623 //.{ - // .target = CrossTarget.parse(.{ + // .target = std.zig.CrossTarget.parse(.{ // .arch_os_abi = "arm-linux-none", // .cpu_features = "generic+v8a", // }) catch unreachable, @@ -287,13 +286,13 @@ const test_targets = blk: { }, .{ - .target = CrossTarget.parse(.{ + .target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "arm-linux-none", .cpu_features = "generic+v8a", }) catch unreachable, }, .{ - .target = CrossTarget.parse(.{ + .target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "arm-linux-musleabihf", .cpu_features = "generic+v8a", }) catch unreachable, @@ -301,7 +300,7 @@ const test_targets = blk: { }, // https://github.com/ziglang/zig/issues/3287 //.{ - // .target = CrossTarget.parse(.{ + // .target = std.zig.CrossTarget.parse(.{ // .arch_os_abi = "arm-linux-gnueabihf", // .cpu_features = "generic+v8a", // }) catch unreachable, @@ -495,10 +494,10 @@ const test_targets = blk: { }; const CAbiTarget = struct { - target: CrossTarget = .{}, + target: std.zig.CrossTarget = .{}, use_llvm: ?bool = null, use_lld: ?bool = null, - force_pic: ?bool = null, + pic: ?bool = null, strip: ?bool = null, c_defines: []const []const u8 = &.{}, }; @@ -543,7 +542,7 @@ const c_abi_targets = [_]CAbiTarget{ }, .use_llvm = false, .use_lld = false, - .force_pic = true, + .pic = true, .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"}, }, .{ @@ -645,7 +644,7 @@ pub fn addStackTraceTests( const check_exe = b.addExecutable(.{ .name = "check-stack-trace", .root_source_file = .{ .path = "test/src/check-stack-trace.zig" }, - .target = .{}, + .target = b.host, .optimize = .Debug, }); @@ -682,12 +681,14 @@ pub fn addStandaloneTests( if (os_tag != builtin.os.tag) continue; } + const resolved_target = b.resolveTargetQuery(case.target); + if (case.is_exe) { const exe = b.addExecutable(.{ .name = std.fs.path.stem(case.src_path), .root_source_file = .{ .path = case.src_path }, .optimize = optimize, - .target = case.target, + .target = resolved_target, }); if (case.link_libc) exe.linkLibC(); @@ -701,7 +702,7 @@ pub fn addStandaloneTests( .name = std.fs.path.stem(case.src_path), .root_source_file = .{ .path = case.src_path }, .optimize = optimize, - .target = case.target, + .target = resolved_target, }); if (case.link_libc) exe.linkLibC(); @@ -1001,7 +1002,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step { pub fn addRunTranslatedCTests( b: *std.Build, test_filter: ?[]const u8, - target: std.zig.CrossTarget, + target: std.Build.ResolvedTarget, ) *Step { const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM"); cases.* = .{ @@ -1105,7 +1106,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { const these_tests = b.addTest(.{ .root_source_file = .{ .path = options.root_src }, .optimize = test_target.optimize_mode, - .target = test_target.target, + .target = b.resolveTargetQuery(test_target.target), .max_rss = max_rss, .filter = options.test_filter, .link_libc = test_target.link_libc, @@ -1113,9 +1114,9 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { .use_llvm = test_target.use_llvm, .use_lld = test_target.use_lld, .zig_lib_dir = .{ .path = "lib" }, + .pic = test_target.pic, + .strip = test_target.strip, }); - these_tests.force_pic = test_target.force_pic; - these_tests.strip = test_target.strip; const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else ""; const backend_suffix = if (test_target.use_llvm == true) "-llvm" @@ -1126,7 +1127,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { else ""; const use_lld = if (test_target.use_lld == false) "-no-lld" else ""; - const use_pic = if (test_target.force_pic == true) "-pic" else ""; + const use_pic = if (test_target.pic == true) "-pic" else ""; these_tests.addIncludePath(.{ .path = "test" }); @@ -1154,7 +1155,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { const compile_c = b.addExecutable(.{ .name = qualified_name, .link_libc = test_target.link_libc, - .target = altered_target, + .target = b.resolveTargetQuery(altered_target), .zig_lib_dir = .{ .path = "lib" }, }); compile_c.addCSourceFile(.{ @@ -1229,41 +1230,39 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S for (c_abi_targets) |c_abi_target| { if (skip_non_native and !c_abi_target.target.isNative()) continue; - if (c_abi_target.target.isWindows() and c_abi_target.target.getCpuArch() == .aarch64) { + const resolved_target = b.resolveTargetQuery(c_abi_target.target); + const target = resolved_target.target; + + if (target.os.tag == .windows and target.cpu.arch == .aarch64) { // https://github.com/ziglang/zig/issues/14908 continue; } const test_step = b.addTest(.{ .name = b.fmt("test-c-abi-{s}-{s}-{s}{s}{s}{s}", .{ - c_abi_target.target.zigTriple(b.allocator) catch @panic("OOM"), - c_abi_target.target.getCpuModel().name, + target.zigTriple(b.allocator) catch @panic("OOM"), + target.cpu.model.name, @tagName(optimize_mode), if (c_abi_target.use_llvm == true) "-llvm" - else if (c_abi_target.target.ofmt == std.Target.ObjectFormat.c) + else if (target.ofmt == .c) "-cbe" else if (c_abi_target.use_llvm == false) "-selfhosted" else "", if (c_abi_target.use_lld == false) "-no-lld" else "", - if (c_abi_target.force_pic == true) "-pic" else "", + if (c_abi_target.pic == true) "-pic" else "", }), .root_source_file = .{ .path = "test/c_abi/main.zig" }, - .target = c_abi_target.target, + .target = resolved_target, .optimize = optimize_mode, .link_libc = true, .use_llvm = c_abi_target.use_llvm, .use_lld = c_abi_target.use_lld, + .pic = c_abi_target.pic, + .strip = c_abi_target.strip, }); - test_step.force_pic = c_abi_target.force_pic; - test_step.strip = c_abi_target.strip; - if (c_abi_target.target.abi != null and c_abi_target.target.abi.?.isMusl()) { - // TODO NativeTargetInfo insists on dynamically linking musl - // for some reason? - test_step.target_info.dynamic_linker.max_byte = null; - } test_step.addCSourceFile(.{ .file = .{ .path = "test/c_abi/cfuncs.c" }, .flags = &.{"-std=c99"}, @@ -1297,8 +1296,8 @@ pub fn addCases( var dir = try b.build_root.handle.openDir("test/cases", .{ .iterate = true }); defer dir.close(); - cases.addFromDir(dir); - try @import("cases.zig").addCases(&cases, build_options); + cases.addFromDir(dir, b); + try @import("cases.zig").addCases(&cases, build_options, b); const cases_dir_path = try b.build_root.join(b.allocator, &.{ "test", "cases" }); cases.lowerToBuildSteps(