diff --git a/build.zig b/build.zig index 47f4bad49c..d79a785c76 100644 --- a/build.zig +++ b/build.zig @@ -50,10 +50,12 @@ pub fn build(b: *std.Build) !void { const autodoc_test = b.addObject(.{ .name = "std", - .root_source_file = b.path("lib/std/std.zig"), - .target = target, .zig_lib_dir = b.path("lib"), - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib/std/std.zig"), + .target = target, + .optimize = .Debug, + }), }); const install_std_docs = b.addInstallDirectory(.{ .source_dir = autodoc_test.getEmittedDocs(), @@ -234,7 +236,7 @@ pub fn build(b: *std.Build) !void { exe_options.addOption(DevEnv, "dev", b.option(DevEnv, "dev", "Build a compiler with a reduced feature set for development of specific features") orelse if (only_c) .bootstrap else .full); if (link_libc) { - exe.linkLibC(); + exe.root_module.link_libc = true; } const is_debug = optimize == .Debug; @@ -330,15 +332,15 @@ pub fn build(b: *std.Build) !void { try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx); } else { // Here we are -Denable-llvm but no cmake integration. - try addStaticLlvmOptionsToExe(exe); + try addStaticLlvmOptionsToModule(exe.root_module); } if (target.result.os.tag == .windows) { // LLVM depends on networking as of version 18. - exe.linkSystemLibrary("ws2_32"); + exe.root_module.linkSystemLibrary("ws2_32", .{}); - exe.linkSystemLibrary("version"); - exe.linkSystemLibrary("uuid"); - exe.linkSystemLibrary("ole32"); + exe.root_module.linkSystemLibrary("version", .{}); + exe.root_module.linkSystemLibrary("uuid", .{}); + exe.root_module.linkSystemLibrary("ole32", .{}); } } @@ -364,16 +366,16 @@ pub fn build(b: *std.Build) !void { else &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" }; - exe.addIncludePath(.{ .cwd_relative = tracy_path }); - exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); + exe.root_module.addIncludePath(.{ .cwd_relative = tracy_path }); + exe.root_module.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags }); if (!enable_llvm) { exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no }); } - exe.linkLibC(); + exe.root_module.link_libc = true; if (target.result.os.tag == .windows) { - exe.linkSystemLibrary("dbghelp"); - exe.linkSystemLibrary("ws2_32"); + exe.root_module.linkSystemLibrary("dbghelp", .{}); + exe.root_module.linkSystemLibrary("ws2_32", .{}); } } @@ -559,8 +561,10 @@ pub fn build(b: *std.Build) !void { if (opt_mingw_src_path) |mingw_src_path| { const update_mingw_exe = b.addExecutable(.{ .name = "update_mingw", - .target = b.graph.host, - .root_source_file = b.path("tools/update_mingw.zig"), + .root_module = b.createModule(.{ + .target = b.graph.host, + .root_source_file = b.path("tools/update_mingw.zig"), + }), }); const update_mingw_run = b.addRunArtifact(update_mingw_exe); update_mingw_run.addDirectoryArg(b.path("lib")); @@ -636,12 +640,10 @@ const AddCompilerStepOptions = struct { }; fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile { - const exe = b.addExecutable(.{ - .name = "zig", + const compiler_mod = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = options.target, .optimize = options.optimize, - .max_rss = 7_800_000_000, .strip = options.strip, .sanitize_thread = options.sanitize_thread, .single_threaded = options.single_threaded, @@ -663,26 +665,28 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St .loongarch32, .loongarch64 => .medium, else => .default, }, + .valgrind = options.valgrind, }); - exe.root_module.valgrind = options.valgrind; - exe.stack_size = stack_size; - const aro_module = b.createModule(.{ + const aro_mod = b.createModule(.{ .root_source_file = b.path("lib/compiler/aro/aro.zig"), }); - const aro_translate_c_module = b.createModule(.{ + const aro_translate_c_mod = b.createModule(.{ .root_source_file = b.path("lib/compiler/aro_translate_c.zig"), - .imports = &.{ - .{ - .name = "aro", - .module = aro_module, - }, - }, }); - exe.root_module.addImport("aro", aro_module); - exe.root_module.addImport("aro_translate_c", aro_translate_c_module); + aro_translate_c_mod.addImport("aro", aro_mod); + compiler_mod.addImport("aro", aro_mod); + compiler_mod.addImport("aro_translate_c", aro_translate_c_mod); + + const exe = b.addExecutable(.{ + .name = "zig", + .max_rss = 7_800_000_000, + .root_module = compiler_mod, + }); + exe.stack_size = stack_size; + return exe; } @@ -707,11 +711,15 @@ fn addCmakeCfgOptionsToExe( exe: *std.Build.Step.Compile, use_zig_libcxx: bool, ) !void { - if (exe.rootModuleTarget().isDarwin()) { + const mod = exe.root_module; + const target = mod.resolved_target.?.result; + + if (target.isDarwin()) { // useful for package maintainers exe.headerpad_max_install_names = true; } - exe.addObjectFile(.{ .cwd_relative = b.pathJoin(&[_][]const u8{ + + mod.addObjectFile(.{ .cwd_relative = b.pathJoin(&.{ cfg.cmake_binary_dir, "zigcpp", b.fmt("{s}{s}{s}", .{ @@ -721,38 +729,38 @@ fn addCmakeCfgOptionsToExe( }), }) }); assert(cfg.lld_include_dir.len != 0); - exe.addIncludePath(.{ .cwd_relative = cfg.lld_include_dir }); - exe.addIncludePath(.{ .cwd_relative = cfg.llvm_include_dir }); - exe.addLibraryPath(.{ .cwd_relative = cfg.llvm_lib_dir }); - addCMakeLibraryList(exe, cfg.clang_libraries); - addCMakeLibraryList(exe, cfg.lld_libraries); - addCMakeLibraryList(exe, cfg.llvm_libraries); + mod.addIncludePath(.{ .cwd_relative = cfg.lld_include_dir }); + mod.addIncludePath(.{ .cwd_relative = cfg.llvm_include_dir }); + mod.addLibraryPath(.{ .cwd_relative = cfg.llvm_lib_dir }); + addCMakeLibraryList(mod, cfg.clang_libraries); + addCMakeLibraryList(mod, cfg.lld_libraries); + addCMakeLibraryList(mod, cfg.llvm_libraries); if (use_zig_libcxx) { - exe.linkLibCpp(); + mod.link_libcpp = true; } else { // System -lc++ must be used because in this code path we are attempting to link // against system-provided LLVM, Clang, LLD. const need_cpp_includes = true; const static = cfg.llvm_linkage == .static; - const lib_suffix = if (static) exe.rootModuleTarget().staticLibSuffix()[1..] else exe.rootModuleTarget().dynamicLibSuffix()[1..]; - switch (exe.rootModuleTarget().os.tag) { + const lib_suffix = if (static) target.staticLibSuffix()[1..] else target.dynamicLibSuffix()[1..]; + switch (target.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. addCxxKnownPath(b, cfg, exe, b.fmt("lib{s}.{s}", .{ cfg.system_libcxx, lib_suffix }), "", need_cpp_includes) catch |err| switch (err) { error.RequiredLibraryNotFound => { - exe.linkLibCpp(); + mod.link_libcpp = true; }, else => |e| return e, }; - exe.linkSystemLibrary("unwind"); + mod.linkSystemLibrary("unwind", .{}); }, .ios, .macos, .watchos, .tvos, .visionos => { - exe.linkLibCpp(); + mod.link_libcpp = true; }, .windows => { - if (exe.rootModuleTarget().abi != .msvc) exe.linkLibCpp(); + if (target.abi != .msvc) mod.link_libcpp = true; }, .freebsd => { if (static) { @@ -786,46 +794,46 @@ fn addCmakeCfgOptionsToExe( } if (cfg.dia_guids_lib.len != 0) { - exe.addObjectFile(.{ .cwd_relative = cfg.dia_guids_lib }); + mod.addObjectFile(.{ .cwd_relative = cfg.dia_guids_lib }); } } -fn addStaticLlvmOptionsToExe(exe: *std.Build.Step.Compile) !void { +fn addStaticLlvmOptionsToModule(mod: *std.Build.Module) !void { // Adds the Zig C++ sources which both stage1 and stage2 need. // // We need this because otherwise zig_clang_cc1_main.cpp ends up pulling // in a dependency on llvm::cfg::Update::dump() which is // unavailable when LLVM is compiled in Release mode. const zig_cpp_cflags = exe_cflags ++ [_][]const u8{"-DNDEBUG=1"}; - exe.addCSourceFiles(.{ + mod.addCSourceFiles(.{ .files = &zig_cpp_sources, .flags = &zig_cpp_cflags, }); for (clang_libs) |lib_name| { - exe.linkSystemLibrary(lib_name); + mod.linkSystemLibrary(lib_name, .{}); } for (lld_libs) |lib_name| { - exe.linkSystemLibrary(lib_name); + mod.linkSystemLibrary(lib_name, .{}); } for (llvm_libs) |lib_name| { - exe.linkSystemLibrary(lib_name); + mod.linkSystemLibrary(lib_name, .{}); } - exe.linkSystemLibrary("z"); - exe.linkSystemLibrary("zstd"); + mod.linkSystemLibrary("z", .{}); + mod.linkSystemLibrary("zstd", .{}); - if (exe.rootModuleTarget().os.tag != .windows or exe.rootModuleTarget().abi != .msvc) { + if (mod.resolved_target.?.result.os.tag != .windows or mod.resolved_target.?.result.abi != .msvc) { // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries. - exe.linkSystemLibrary("c++"); + mod.linkSystemLibrary("c++", .{}); } - if (exe.rootModuleTarget().os.tag == .windows) { - exe.linkSystemLibrary("version"); - exe.linkSystemLibrary("uuid"); - exe.linkSystemLibrary("ole32"); + if (mod.resolved_target.?.result.os.tag == .windows) { + mod.linkSystemLibrary("version", .{}); + mod.linkSystemLibrary("uuid", .{}); + mod.linkSystemLibrary("ole32", .{}); } } @@ -862,29 +870,29 @@ fn addCxxKnownPath( // but libc++ may very well be one, so force all inputs to be checked when passing // an explicit path to libc++. exe.allow_so_scripts = true; - exe.addObjectFile(.{ .cwd_relative = path_unpadded }); + exe.root_module.addObjectFile(.{ .cwd_relative = path_unpadded }); // TODO a way to integrate with system c++ include files here // c++ -E -Wp,-v -xc++ /dev/null if (need_cpp_includes) { // I used these temporarily for testing something but we obviously need a // more general purpose solution here. - //exe.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0"); - //exe.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu"); + //exe.root_module.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0"); + //exe.root_module.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu"); } } -fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void { +fn addCMakeLibraryList(mod: *std.Build.Module, list: []const u8) void { var it = mem.tokenizeScalar(u8, list, ';'); while (it.next()) |lib| { if (mem.startsWith(u8, lib, "-l")) { - exe.linkSystemLibrary(lib["-l".len..]); - } else if (exe.rootModuleTarget().os.tag == .windows and + mod.linkSystemLibrary(lib["-l".len..], .{}); + } else if (mod.resolved_target.?.result.os.tag == .windows and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) { - exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]); + mod.linkSystemLibrary(lib[0 .. lib.len - ".lib".len], .{}); } else { - exe.addObjectFile(.{ .cwd_relative = lib }); + mod.addObjectFile(.{ .cwd_relative = lib }); } } } @@ -1306,9 +1314,11 @@ const llvm_libs = [_][]const u8{ fn generateLangRef(b: *std.Build) std.Build.LazyPath { const doctest_exe = b.addExecutable(.{ .name = "doctest", - .root_source_file = b.path("tools/doctest.zig"), - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("tools/doctest.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), }); var dir = b.build_root.handle.openDir("doc/langref", .{ .iterate = true }) catch |err| { @@ -1343,9 +1353,11 @@ fn generateLangRef(b: *std.Build) std.Build.LazyPath { const docgen_exe = b.addExecutable(.{ .name = "docgen", - .root_source_file = b.path("tools/docgen.zig"), - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("tools/docgen.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), }); const docgen_cmd = b.addRunArtifact(docgen_exe); diff --git a/lib/compiler/build_runner.zig b/lib/compiler/build_runner.zig index 632982e812..91443a093a 100644 --- a/lib/compiler/build_runner.zig +++ b/lib/compiler/build_runner.zig @@ -337,6 +337,7 @@ pub fn main() !void { var prog_node = main_progress_node.start("Configure", 0); defer prog_node.end(); try builder.runBuild(root); + createModuleDependencies(builder) catch @panic("OOM"); } if (graph.needed_lazy_dependencies.entries.len != 0) { @@ -1440,3 +1441,80 @@ fn validateSystemLibraryOptions(b: *std.Build) void { process.exit(1); } } + +/// Starting from all top-level steps in `b`, traverses the entire step graph +/// and adds all step dependencies implied by module graphs. +fn createModuleDependencies(b: *std.Build) Allocator.Error!void { + const arena = b.graph.arena; + + var all_steps: std.AutoArrayHashMapUnmanaged(*Step, void) = .empty; + var next_step_idx: usize = 0; + + try all_steps.ensureUnusedCapacity(arena, b.top_level_steps.count()); + for (b.top_level_steps.values()) |tls| { + all_steps.putAssumeCapacityNoClobber(&tls.step, {}); + } + + while (next_step_idx < all_steps.count()) { + const step = all_steps.keys()[next_step_idx]; + next_step_idx += 1; + + // Set up any implied dependencies for this step. It's important that we do this first, so + // that the loop below discovers steps implied by the module graph. + try createModuleDependenciesForStep(step); + + try all_steps.ensureUnusedCapacity(arena, step.dependencies.items.len); + for (step.dependencies.items) |other_step| { + all_steps.putAssumeCapacity(other_step, {}); + } + } +} + +/// If the given `Step` is a `Step.Compile`, adds any dependencies for that step which +/// are implied by the module graph rooted at `step.cast(Step.Compile).?.root_module`. +fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { + const root_module = if (step.cast(Step.Compile)) |cs| root: { + break :root cs.root_module; + } else return; // not a compile step so no module dependencies + + // Starting from `root_module`, discover all modules in this graph. + const modules = root_module.getGraph().modules; + + // For each of those modules, set up the implied step dependencies. + for (modules) |mod| { + if (mod.root_source_file) |lp| lp.addStepDependencies(step); + for (mod.include_dirs.items) |include_dir| switch (include_dir) { + .path, + .path_system, + .path_after, + .framework_path, + .framework_path_system, + => |lp| lp.addStepDependencies(step), + + .other_step => |other| { + other.getEmittedIncludeTree().addStepDependencies(step); + step.dependOn(&other.step); + }, + + .config_header_step => |other| step.dependOn(&other.step), + }; + for (mod.lib_paths.items) |lp| lp.addStepDependencies(step); + for (mod.rpaths.items) |rpath| switch (rpath) { + .lazy_path => |lp| lp.addStepDependencies(step), + .special => {}, + }; + for (mod.link_objects.items) |link_object| switch (link_object) { + .static_path, + .assembly_file, + => |lp| lp.addStepDependencies(step), + .other_step => |other| step.dependOn(&other.step), + .system_lib => {}, + .c_source_file => |source| source.file.addStepDependencies(step), + .c_source_files => |source_files| source_files.root.addStepDependencies(step), + .win32_resource_file => |rc_source| { + rc_source.file.addStepDependencies(step); + for (rc_source.include_paths) |lp| lp.addStepDependencies(step); + }, + }; + } +} diff --git a/lib/init/build.zig b/lib/init/build.zig index d53cbbb982..c75a4e6be3 100644 --- a/lib/init/build.zig +++ b/lib/init/build.zig @@ -15,8 +15,12 @@ pub fn build(b: *std.Build) void { // set a preferred release mode, allowing the user to decide how to optimize. const optimize = b.standardOptimizeOption(.{}); - const lib = b.addStaticLibrary(.{ - .name = "$", + // This creates a "module", which represents a collection of source files alongside + // some compilation options, such as optimization mode and linked system libraries. + // Every executable or library we compile will be based on one or more modules. + const lib_mod = b.createModule(.{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. // In this case the main source file is merely a path, however, in more // complicated build scripts, this could be a generated file. .root_source_file = b.path("src/root.zig"), @@ -24,16 +28,40 @@ pub fn build(b: *std.Build) void { .optimize = optimize, }); + // We will also create a module for our other entry point, 'main.zig'. + const exe_mod = b.createModule(.{ + // `root_source_file` is the Zig "entry point" of the module. If a module + // only contains e.g. external object files, you can make this `null`. + // In this case the main source file is merely a path, however, in more + // complicated build scripts, this could be a generated file. + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + + // Modules can depend on one another using the `std.Build.Module.addImport` function. + // This is what allows Zig source code to use `@import("foo")` where 'foo' is not a + // file path. In this case, we set up `exe_mod` to import `lib_mod`. + exe_mod.addImport("$_lib", lib_mod); + + // Now, we will create a static library based on the module we created above. + // This creates a `std.Build.Step.Compile`, which is the build step responsible + // for actually invoking the compiler. + const lib = b.addStaticLibrary(.{ + .name = "$", + .root_module = lib_mod, + }); + // This declares intent for the library to be installed into the standard // location when the user invokes the "install" step (the default step when // running `zig build`). b.installArtifact(lib); + // This creates another `std.Build.Step.Compile`, but this one builds an executable + // rather than a static library. const exe = b.addExecutable(.{ .name = "$", - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, + .root_module = exe_mod, }); // This declares intent for the executable to be installed into the @@ -67,17 +95,13 @@ pub fn build(b: *std.Build) void { // Creates a step for unit testing. This only builds the test executable // but does not run it. const lib_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, + .root_module = lib_mod, }); const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); const exe_unit_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, + .root_module = exe_mod, }); const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); diff --git a/lib/init/src/main.zig b/lib/init/src/main.zig index ba5a2ccef2..caf8f4f37a 100644 --- a/lib/init/src/main.zig +++ b/lib/init/src/main.zig @@ -1,7 +1,6 @@ //! By convention, main.zig is where your main function lives in the case that //! you are building an executable. If you are making a library, the convention //! is to delete this file and start with root.zig instead. -const std = @import("std"); pub fn main() !void { // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`) @@ -26,6 +25,10 @@ test "simple test" { try std.testing.expectEqual(@as(i32, 42), list.pop()); } +test "use other module" { + try std.testing.expectEqual(@as(i32, 150), lib.add(100, 50)); +} + test "fuzz example" { const global = struct { fn testOne(input: []const u8) anyerror!void { @@ -35,3 +38,8 @@ test "fuzz example" { }; try std.testing.fuzz(global.testOne, .{}); } + +const std = @import("std"); + +/// This imports the separate module containing `root.zig`. Take a look in `build.zig` for details. +const lib = @import("$_lib"); diff --git a/lib/init/src/root.zig b/lib/init/src/root.zig index f034ca3589..27d2be80b5 100644 --- a/lib/init/src/root.zig +++ b/lib/init/src/root.zig @@ -4,7 +4,7 @@ const std = @import("std"); const testing = std.testing; -export fn add(a: i32, b: i32) i32 { +pub export fn add(a: i32, b: i32) i32 { return a + b; } diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 65e2db3d1d..636b5bbe4f 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -81,9 +81,6 @@ enable_wine: bool = false, /// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`. glibc_runtimes_dir: ?[]const u8 = null, -/// Deprecated. Use `b.graph.host`. -host: ResolvedTarget, - dep_prefix: []const u8 = "", modules: std.StringArrayHashMap(*Module), @@ -301,7 +298,6 @@ pub fn create( }, .install_path = undefined, .args = null, - .host = graph.host, .modules = .init(arena), .named_writefiles = .init(arena), .named_lazy_paths = .init(arena), @@ -393,7 +389,6 @@ fn createChildOnly( .enable_wasmtime = parent.enable_wasmtime, .enable_wine = parent.enable_wine, .glibc_runtimes_dir = parent.glibc_runtimes_dir, - .host = parent.host, .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), .modules = .init(allocator), .named_writefiles = .init(allocator), @@ -692,24 +687,9 @@ pub fn addOptions(b: *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, - optimize: std.builtin.OptimizeMode = .Debug, - code_model: std.builtin.CodeModel = .default, linkage: ?std.builtin.LinkMode = null, max_rss: usize = 0, - link_libc: ?bool = null, - single_threaded: ?bool = null, - pic: ?bool = null, - strip: ?bool = null, - unwind_tables: ?std.builtin.UnwindTables = null, - omit_frame_pointer: ?bool = null, - sanitize_thread: ?bool = null, - error_tracing: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -719,14 +699,47 @@ pub const ExecutableOptions = struct { /// Can be set regardless of target. The `.manifest` file will be ignored /// if the target object format does not support embedded manifests. win32_manifest: ?LazyPath = null, + + /// Prefer populating this field (using e.g. `createModule`) instead of populating + /// the following fields (`root_source_file` etc). In a future release, those fields + /// will be removed, and this field will become non-optional. + root_module: ?*Module = null, + + /// Deprecated; prefer populating `root_module`. + root_source_file: ?LazyPath = null, + /// Deprecated; prefer populating `root_module`. + target: ?ResolvedTarget = null, + /// Deprecated; prefer populating `root_module`. + optimize: std.builtin.OptimizeMode = .Debug, + /// Deprecated; prefer populating `root_module`. + code_model: std.builtin.CodeModel = .default, + /// Deprecated; prefer populating `root_module`. + link_libc: ?bool = null, + /// Deprecated; prefer populating `root_module`. + single_threaded: ?bool = null, + /// Deprecated; prefer populating `root_module`. + pic: ?bool = null, + /// Deprecated; prefer populating `root_module`. + strip: ?bool = null, + /// Deprecated; prefer populating `root_module`. + unwind_tables: ?std.builtin.UnwindTables = null, + /// Deprecated; prefer populating `root_module`. + omit_frame_pointer: ?bool = null, + /// Deprecated; prefer populating `root_module`. + sanitize_thread: ?bool = null, + /// Deprecated; prefer populating `root_module`. + error_tracing: ?bool = null, }; pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { - return Step.Compile.create(b, .{ + if (options.root_module != null and options.target != null) { + @panic("`root_module` and `target` cannot both be populated"); + } + return .create(b, .{ .name = options.name, - .root_module = .{ + .root_module = options.root_module orelse b.createModule(.{ .root_source_file = options.root_source_file, - .target = options.target, + .target = options.target orelse @panic("`root_module` and `target` cannot both be null"), .optimize = options.optimize, .link_libc = options.link_libc, .single_threaded = options.single_threaded, @@ -737,7 +750,7 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { .sanitize_thread = options.sanitize_thread, .error_tracing = options.error_tracing, .code_model = options.code_model, - }, + }), .version = options.version, .kind = .exe, .linkage = options.linkage, @@ -751,32 +764,51 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile { pub const ObjectOptions = struct { name: []const u8, - root_source_file: ?LazyPath = null, - /// To choose the same computer as the one building the package, pass the - /// `host` field of the package's `Build` instance. - target: ResolvedTarget, - code_model: std.builtin.CodeModel = .default, - optimize: std.builtin.OptimizeMode, max_rss: usize = 0, - link_libc: ?bool = null, - single_threaded: ?bool = null, - pic: ?bool = null, - strip: ?bool = null, - unwind_tables: ?std.builtin.UnwindTables = null, - omit_frame_pointer: ?bool = null, - sanitize_thread: ?bool = null, - error_tracing: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, + + /// Prefer populating this field (using e.g. `createModule`) instead of populating + /// the following fields (`root_source_file` etc). In a future release, those fields + /// will be removed, and this field will become non-optional. + root_module: ?*Module = null, + + /// Deprecated; prefer populating `root_module`. + root_source_file: ?LazyPath = null, + /// Deprecated; prefer populating `root_module`. + target: ?ResolvedTarget = null, + /// Deprecated; prefer populating `root_module`. + optimize: std.builtin.OptimizeMode = .Debug, + /// Deprecated; prefer populating `root_module`. + code_model: std.builtin.CodeModel = .default, + /// Deprecated; prefer populating `root_module`. + link_libc: ?bool = null, + /// Deprecated; prefer populating `root_module`. + single_threaded: ?bool = null, + /// Deprecated; prefer populating `root_module`. + pic: ?bool = null, + /// Deprecated; prefer populating `root_module`. + strip: ?bool = null, + /// Deprecated; prefer populating `root_module`. + unwind_tables: ?std.builtin.UnwindTables = null, + /// Deprecated; prefer populating `root_module`. + omit_frame_pointer: ?bool = null, + /// Deprecated; prefer populating `root_module`. + sanitize_thread: ?bool = null, + /// Deprecated; prefer populating `root_module`. + error_tracing: ?bool = null, }; pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile { - return Step.Compile.create(b, .{ + if (options.root_module != null and options.target != null) { + @panic("`root_module` and `target` cannot both be populated"); + } + return .create(b, .{ .name = options.name, - .root_module = .{ + .root_module = options.root_module orelse b.createModule(.{ .root_source_file = options.root_source_file, - .target = options.target, + .target = options.target orelse @panic("`root_module` and `target` cannot both be null"), .optimize = options.optimize, .link_libc = options.link_libc, .single_threaded = options.single_threaded, @@ -787,7 +819,7 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile { .sanitize_thread = options.sanitize_thread, .error_tracing = options.error_tracing, .code_model = options.code_model, - }, + }), .kind = .obj, .max_rss = options.max_rss, .use_llvm = options.use_llvm, @@ -798,22 +830,8 @@ 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, - code_model: std.builtin.CodeModel = .default, - root_source_file: ?LazyPath = null, version: ?std.SemanticVersion = null, max_rss: usize = 0, - link_libc: ?bool = null, - single_threaded: ?bool = null, - pic: ?bool = null, - strip: ?bool = null, - unwind_tables: ?std.builtin.UnwindTables = null, - omit_frame_pointer: ?bool = null, - sanitize_thread: ?bool = null, - error_tracing: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, @@ -823,13 +841,46 @@ pub const SharedLibraryOptions = struct { /// Can be set regardless of target. The `.manifest` file will be ignored /// if the target object format does not support embedded manifests. win32_manifest: ?LazyPath = null, + + /// Prefer populating this field (using e.g. `createModule`) instead of populating + /// the following fields (`root_source_file` etc). In a future release, those fields + /// will be removed, and this field will become non-optional. + root_module: ?*Module = null, + + /// Deprecated; prefer populating `root_module`. + root_source_file: ?LazyPath = null, + /// Deprecated; prefer populating `root_module`. + target: ?ResolvedTarget = null, + /// Deprecated; prefer populating `root_module`. + optimize: std.builtin.OptimizeMode = .Debug, + /// Deprecated; prefer populating `root_module`. + code_model: std.builtin.CodeModel = .default, + /// Deprecated; prefer populating `root_module`. + link_libc: ?bool = null, + /// Deprecated; prefer populating `root_module`. + single_threaded: ?bool = null, + /// Deprecated; prefer populating `root_module`. + pic: ?bool = null, + /// Deprecated; prefer populating `root_module`. + strip: ?bool = null, + /// Deprecated; prefer populating `root_module`. + unwind_tables: ?std.builtin.UnwindTables = null, + /// Deprecated; prefer populating `root_module`. + omit_frame_pointer: ?bool = null, + /// Deprecated; prefer populating `root_module`. + sanitize_thread: ?bool = null, + /// Deprecated; prefer populating `root_module`. + error_tracing: ?bool = null, }; pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile { - return Step.Compile.create(b, .{ + if (options.root_module != null and options.target != null) { + @panic("`root_module` and `target` cannot both be populated"); + } + return .create(b, .{ .name = options.name, - .root_module = .{ - .target = options.target, + .root_module = options.root_module orelse b.createModule(.{ + .target = options.target orelse @panic("`root_module` and `target` cannot both be null"), .optimize = options.optimize, .root_source_file = options.root_source_file, .link_libc = options.link_libc, @@ -841,7 +892,7 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile .sanitize_thread = options.sanitize_thread, .error_tracing = options.error_tracing, .code_model = options.code_model, - }, + }), .kind = .lib, .linkage = .dynamic, .version = options.version, @@ -855,32 +906,51 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile pub const StaticLibraryOptions = struct { name: []const u8, - root_source_file: ?LazyPath = null, - /// 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, - code_model: std.builtin.CodeModel = .default, version: ?std.SemanticVersion = null, max_rss: usize = 0, - link_libc: ?bool = null, - single_threaded: ?bool = null, - pic: ?bool = null, - strip: ?bool = null, - unwind_tables: ?std.builtin.UnwindTables = null, - omit_frame_pointer: ?bool = null, - sanitize_thread: ?bool = null, - error_tracing: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, + + /// Prefer populating this field (using e.g. `createModule`) instead of populating + /// the following fields (`root_source_file` etc). In a future release, those fields + /// will be removed, and this field will become non-optional. + root_module: ?*Module = null, + + /// Deprecated; prefer populating `root_module`. + root_source_file: ?LazyPath = null, + /// Deprecated; prefer populating `root_module`. + target: ?ResolvedTarget = null, + /// Deprecated; prefer populating `root_module`. + optimize: std.builtin.OptimizeMode = .Debug, + /// Deprecated; prefer populating `root_module`. + code_model: std.builtin.CodeModel = .default, + /// Deprecated; prefer populating `root_module`. + link_libc: ?bool = null, + /// Deprecated; prefer populating `root_module`. + single_threaded: ?bool = null, + /// Deprecated; prefer populating `root_module`. + pic: ?bool = null, + /// Deprecated; prefer populating `root_module`. + strip: ?bool = null, + /// Deprecated; prefer populating `root_module`. + unwind_tables: ?std.builtin.UnwindTables = null, + /// Deprecated; prefer populating `root_module`. + omit_frame_pointer: ?bool = null, + /// Deprecated; prefer populating `root_module`. + sanitize_thread: ?bool = null, + /// Deprecated; prefer populating `root_module`. + error_tracing: ?bool = null, }; pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile { - return Step.Compile.create(b, .{ + if (options.root_module != null and options.target != null) { + @panic("`root_module` and `target` cannot both be populated"); + } + return .create(b, .{ .name = options.name, - .root_module = .{ - .target = options.target, + .root_module = options.root_module orelse b.createModule(.{ + .target = options.target orelse @panic("`root_module` and `target` cannot both be null"), .optimize = options.optimize, .root_source_file = options.root_source_file, .link_libc = options.link_libc, @@ -892,7 +962,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile .sanitize_thread = options.sanitize_thread, .error_tracing = options.error_tracing, .code_model = options.code_model, - }, + }), .kind = .lib, .linkage = .static, .version = options.version, @@ -905,27 +975,46 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile pub const TestOptions = struct { name: []const u8 = "test", - root_source_file: LazyPath, - target: ?ResolvedTarget = null, - optimize: std.builtin.OptimizeMode = .Debug, - version: ?std.SemanticVersion = null, max_rss: usize = 0, - /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`. + /// Deprecated; use `.filters = &.{filter}` instead of `.filter = filter`. filter: ?[]const u8 = null, filters: []const []const u8 = &.{}, test_runner: ?LazyPath = null, - link_libc: ?bool = null, - link_libcpp: ?bool = null, - single_threaded: ?bool = null, - pic: ?bool = null, - strip: ?bool = null, - unwind_tables: ?std.builtin.UnwindTables = null, - omit_frame_pointer: ?bool = null, - sanitize_thread: ?bool = null, - error_tracing: ?bool = null, use_llvm: ?bool = null, use_lld: ?bool = null, zig_lib_dir: ?LazyPath = null, + + /// Prefer populating this field (using e.g. `createModule`) instead of populating + /// the following fields (`root_source_file` etc). In a future release, those fields + /// will be removed, and this field will become non-optional. + root_module: ?*Module = null, + + /// Deprecated; prefer populating `root_module`. + root_source_file: ?LazyPath = null, + /// Deprecated; prefer populating `root_module`. + target: ?ResolvedTarget = null, + /// Deprecated; prefer populating `root_module`. + optimize: std.builtin.OptimizeMode = .Debug, + /// Deprecated; prefer populating `root_module`. + version: ?std.SemanticVersion = null, + /// Deprecated; prefer populating `root_module`. + link_libc: ?bool = null, + /// Deprecated; prefer populating `root_module`. + link_libcpp: ?bool = null, + /// Deprecated; prefer populating `root_module`. + single_threaded: ?bool = null, + /// Deprecated; prefer populating `root_module`. + pic: ?bool = null, + /// Deprecated; prefer populating `root_module`. + strip: ?bool = null, + /// Deprecated; prefer populating `root_module`. + unwind_tables: ?std.builtin.UnwindTables = null, + /// Deprecated; prefer populating `root_module`. + omit_frame_pointer: ?bool = null, + /// Deprecated; prefer populating `root_module`. + sanitize_thread: ?bool = null, + /// Deprecated; prefer populating `root_module`. + error_tracing: ?bool = null, }; /// Creates an executable containing unit tests. @@ -937,11 +1026,14 @@ pub const TestOptions = struct { /// two steps are separated because they are independently configured and /// cached. pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { - return Step.Compile.create(b, .{ + if (options.root_module != null and options.root_source_file != null) { + @panic("`root_module` and `root_source_file` cannot both be populated"); + } + return .create(b, .{ .name = options.name, .kind = .@"test", - .root_module = .{ - .root_source_file = options.root_source_file, + .root_module = options.root_module orelse b.createModule(.{ + .root_source_file = options.root_source_file orelse @panic("`root_module` and `root_source_file` cannot both be null"), .target = options.target orelse b.graph.host, .optimize = options.optimize, .link_libc = options.link_libc, @@ -953,7 +1045,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile { .omit_frame_pointer = options.omit_frame_pointer, .sanitize_thread = options.sanitize_thread, .error_tracing = options.error_tracing, - }, + }), .max_rss = options.max_rss, .filters = if (options.filter != null and options.filters.len > 0) filters: { const filters = b.allocator.alloc([]const u8, 1 + options.filters.len) catch @panic("OOM"); @@ -979,19 +1071,20 @@ pub const AssemblyOptions = struct { zig_lib_dir: ?LazyPath = null, }; +/// Deprecated; prefer using `addObject` where the `root_module` has an empty +/// `root_source_file` and contains an assembly file via `Module.addAssemblyFile`. pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile { - const obj_step = Step.Compile.create(b, .{ + const root_module = b.createModule(.{ + .target = options.target, + .optimize = options.optimize, + }); + root_module.addAssemblyFile(options.source_file); + return b.addObject(.{ .name = options.name, - .kind = .obj, - .root_module = .{ - .target = options.target, - .optimize = options.optimize, - }, .max_rss = options.max_rss, .zig_lib_dir = options.zig_lib_dir, + .root_module = root_module, }); - obj_step.addAssemblyFile(options.source_file); - return obj_step; } /// This function creates a module and adds it to the package's module set, making diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig index 0e421280f0..1f2b4f3fcb 100644 --- a/lib/std/Build/Module.zig +++ b/lib/std/Build/Module.zig @@ -1,9 +1,5 @@ /// The one responsible for creating this module. 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(*Step.Compile, void), root_source_file: ?LazyPath, /// The modules that are mapped into this module's import table. /// Use `addImport` rather than modifying this field directly in order to @@ -41,6 +37,10 @@ link_libcpp: ?bool, /// Symbols to be exported when compiling to WebAssembly. export_symbol_names: []const []const u8 = &.{}, +/// Caches the result of `getGraph` when called multiple times. +/// Use `getGraph` instead of accessing this field directly. +cached_graph: Graph = .{ .modules = &.{}, .names = &.{} }, + pub const RPath = union(enum) { lazy_path: LazyPath, special: []const u8, @@ -242,59 +242,61 @@ pub const Import = struct { module: *Module, }; -pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*Step.Compile) void { +pub fn init( + m: *Module, + owner: *std.Build, + value: union(enum) { options: CreateOptions, existing: *const Module }, +) 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 = .{}, - .resolved_target = options.target, - .optimize = options.optimize, - .link_libc = options.link_libc, - .link_libcpp = options.link_libcpp, - .dwarf_format = options.dwarf_format, - .c_macros = .{}, - .include_dirs = .{}, - .lib_paths = .{}, - .rpaths = .{}, - .frameworks = .{}, - .link_objects = .{}, - .strip = options.strip, - .unwind_tables = options.unwind_tables, - .single_threaded = options.single_threaded, - .stack_protector = options.stack_protector, - .stack_check = options.stack_check, - .sanitize_c = options.sanitize_c, - .sanitize_thread = options.sanitize_thread, - .fuzz = options.fuzz, - .code_model = options.code_model, - .valgrind = options.valgrind, - .pic = options.pic, - .red_zone = options.red_zone, - .omit_frame_pointer = options.omit_frame_pointer, - .error_tracing = options.error_tracing, - .export_symbol_names = &.{}, - }; + switch (value) { + .options => |options| { + m.* = .{ + .owner = owner, + .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null, + .import_table = .{}, + .resolved_target = options.target, + .optimize = options.optimize, + .link_libc = options.link_libc, + .link_libcpp = options.link_libcpp, + .dwarf_format = options.dwarf_format, + .c_macros = .{}, + .include_dirs = .{}, + .lib_paths = .{}, + .rpaths = .{}, + .frameworks = .{}, + .link_objects = .{}, + .strip = options.strip, + .unwind_tables = options.unwind_tables, + .single_threaded = options.single_threaded, + .stack_protector = options.stack_protector, + .stack_check = options.stack_check, + .sanitize_c = options.sanitize_c, + .sanitize_thread = options.sanitize_thread, + .fuzz = options.fuzz, + .code_model = options.code_model, + .valgrind = options.valgrind, + .pic = options.pic, + .red_zone = options.red_zone, + .omit_frame_pointer = options.omit_frame_pointer, + .error_tracing = options.error_tracing, + .export_symbol_names = &.{}, + }; - m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM"); - for (options.imports) |dep| { - m.import_table.putAssumeCapacity(dep.name, dep.module); + m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM"); + for (options.imports) |dep| { + m.import_table.putAssumeCapacity(dep.name, dep.module); + } + }, + .existing => |existing| { + m.* = existing.*; + }, } - - if (compile) |c| { - m.depending_steps.put(allocator, c, {}) catch @panic("OOM"); - } - - // This logic accesses `depending_steps` which was just modified above. - var it = m.iterateDependencies(null, false); - 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 = options }); return m; } @@ -302,69 +304,6 @@ pub fn create(owner: *std.Build, options: CreateOptions) *Module { pub fn addImport(m: *Module, name: []const u8, module: *Module) void { const b = m.owner; m.import_table.put(b.allocator, b.dupe(name), module) catch @panic("OOM"); - - var it = module.iterateDependencies(null, false); - while (it.next()) |item| addShallowDependencies(m, item.module); -} - -/// Creates step dependencies and updates `depending_steps` of `dependee` so that -/// subsequent calls to `addImport` on `dependee` will additionally create step -/// dependencies on `m`'s `depending_steps`. -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| 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); - addLazyPathDependenciesOnly(m, compile.getEmittedIncludeTree()); - }, - - .static_path, - .assembly_file, - => |lp| addLazyPathDependencies(m, dependee, lp), - - .c_source_file => |x| addLazyPathDependencies(m, dependee, x.file), - .win32_resource_file => |x| addLazyPathDependencies(m, dependee, x.file), - - .c_source_files, - .system_lib, - => {}, - }; -} - -fn addLazyPathDependencies(m: *Module, module: *Module, lazy_path: LazyPath) void { - addLazyPathDependenciesOnly(m, lazy_path); - if (m != module) { - for (m.depending_steps.keys()) |compile| { - module.depending_steps.put(m.owner.allocator, compile, {}) catch @panic("OOM"); - } - } -} - -fn addLazyPathDependenciesOnly(m: *Module, lazy_path: LazyPath) void { - for (m.depending_steps.keys()) |compile| { - lazy_path.addStepDependencies(&compile.step); - } -} - -fn addStepDependencies(m: *Module, module: *Module, dependee: *Step) void { - addStepDependenciesOnly(m, dependee); - if (m != module) { - for (m.depending_steps.keys()) |compile| { - module.depending_steps.put(m.owner.allocator, compile, {}) catch @panic("OOM"); - } - } -} - -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`. @@ -380,91 +319,6 @@ pub fn addOptions(m: *Module, module_name: []const u8, options: *Step.Options) v addImport(m, module_name, options.createModule()); } -pub const DependencyIterator = struct { - allocator: std.mem.Allocator, - index: usize, - set: std.AutoArrayHashMapUnmanaged(Key, []const u8), - chase_dyn_libs: bool, - - pub const Key = struct { - /// The compilation that contains the `Module`. Note that a `Module` might be - /// used by more than one compilation. - 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: ?*Step.Compile, - module: *Module, - name: []const u8, - }; - - pub fn deinit(it: *DependencyIterator) void { - it.set.deinit(it.allocator); - it.* = undefined; - } - - pub fn next(it: *DependencyIterator) ?Item { - if (it.index >= it.set.count()) { - it.set.clearAndFree(it.allocator); - return null; - } - const key = it.set.keys()[it.index]; - const name = it.set.values()[it.index]; - it.index += 1; - const module = key.module; - it.set.ensureUnusedCapacity(it.allocator, module.import_table.count()) catch - @panic("OOM"); - for (module.import_table.keys(), module.import_table.values()) |dep_name, dep| { - it.set.putAssumeCapacity(.{ - .module = dep, - .compile = key.compile, - }, dep_name); - } - - if (key.compile != null) { - for (module.link_objects.items) |link_object| switch (link_object) { - .other_step => |compile| { - if (!it.chase_dyn_libs and compile.isDynamicLibrary()) continue; - - it.set.put(it.allocator, .{ - .module = &compile.root_module, - .compile = compile, - }, "root") catch @panic("OOM"); - }, - else => {}, - }; - } - - return .{ - .compile = key.compile, - .module = key.module, - .name = name, - }; - } -}; - -pub fn iterateDependencies( - m: *Module, - chase_steps: ?*Step.Compile, - chase_dyn_libs: bool, -) DependencyIterator { - var it: DependencyIterator = .{ - .allocator = m.owner.allocator, - .index = 0, - .set = .{}, - .chase_dyn_libs = chase_dyn_libs, - }; - it.set.ensureUnusedCapacity(m.owner.allocator, m.import_table.count() + 1) catch @panic("OOM"); - it.set.putAssumeCapacity(.{ - .module = m, - .compile = chase_steps, - }, "root"); - return it; -} - pub const LinkSystemLibraryOptions = struct { /// Causes dynamic libraries to be linked regardless of whether they are /// actually depended on. When false, dynamic libraries with no referenced @@ -547,7 +401,6 @@ pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void { .flags = b.dupeStrings(options.flags), }; m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM"); - addLazyPathDependenciesOnly(m, c_source_files.root); } pub fn addCSourceFile(m: *Module, source: CSourceFile) void { @@ -556,7 +409,6 @@ pub fn addCSourceFile(m: *Module, source: CSourceFile) void { 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); } /// Resource files must have the extension `.rc`. @@ -573,22 +425,16 @@ pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void { 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); - for (source.include_paths) |include_path| { - addLazyPathDependenciesOnly(m, include_path); - } } pub fn addAssemblyFile(m: *Module, source: LazyPath) void { 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, 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 { @@ -604,51 +450,43 @@ pub fn linkLibrary(m: *Module, library: *Step.Compile) void { 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; 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 { @@ -772,7 +610,6 @@ fn addFlag( 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. @@ -780,8 +617,6 @@ fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void { m.link_objects.append(allocator, .{ .other_step = other }) catch @panic("OOM"); m.include_dirs.append(allocator, .{ .other_step = other }) catch @panic("OOM"); - - addLazyPathDependenciesOnly(m, other.getEmittedIncludeTree()); } fn requireKnownTarget(m: *Module) std.Target { @@ -790,6 +625,46 @@ fn requireKnownTarget(m: *Module) std.Target { return resolved_target.result; } +/// Elements of `modules` and `names` are matched one-to-one. +pub const Graph = struct { + modules: []const *Module, + names: []const []const u8, +}; + +/// Intended to be used during the make phase only. +/// +/// Given that `root` is the root `Module` of a compilation, return all `Module`s +/// in the module graph, including `root` itself. `root` is guaranteed to be the +/// first module in the returned slice. +pub fn getGraph(root: *Module) Graph { + if (root.cached_graph.modules.len != 0) { + return root.cached_graph; + } + + const arena = root.owner.graph.arena; + + var modules: std.AutoArrayHashMapUnmanaged(*std.Build.Module, []const u8) = .empty; + var next_idx: usize = 0; + + modules.putNoClobber(arena, root, "root") catch @panic("OOM"); + + while (next_idx < modules.count()) { + const mod = modules.keys()[next_idx]; + next_idx += 1; + modules.ensureUnusedCapacity(arena, mod.import_table.count()) catch @panic("OOM"); + for (mod.import_table.keys(), mod.import_table.values()) |import_name, other_mod| { + modules.putAssumeCapacity(other_mod, import_name); + } + } + + const result: Graph = .{ + .modules = modules.keys(), + .names = modules.values(), + }; + root.cached_graph = result; + return result; +} + const Module = @This(); const std = @import("std"); const assert = std.debug.assert; diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 1dd444abf2..3c6e8231ca 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -22,7 +22,7 @@ const Path = std.Build.Cache.Path; pub const base_id: Step.Id = .compile; step: Step, -root_module: Module, +root_module: *Module, name: []const u8, linker_script: ?LazyPath = null, @@ -262,7 +262,7 @@ pub const Entry = union(enum) { pub const Options = struct { name: []const u8, - root_module: Module.CreateOptions, + root_module: *Module, kind: Kind, linkage: ?std.builtin.LinkMode = null, version: ?std.SemanticVersion = null, @@ -359,7 +359,8 @@ pub fn create(owner: *std.Build, options: Options) *Compile { else owner.fmt("{s} ", .{name}); - const resolved_target = options.root_module.target.?; + const resolved_target = options.root_module.resolved_target orelse + @panic("the root Module of a Compile step must be created with a known 'target' field"); const target = resolved_target.result; const step_name = owner.fmt("{s} {s}{s} {s}", .{ @@ -388,7 +389,7 @@ pub fn create(owner: *std.Build, options: Options) *Compile { const compile = owner.allocator.create(Compile) catch @panic("OOM"); compile.* = .{ - .root_module = undefined, + .root_module = options.root_module, .verbose_link = false, .verbose_cc = false, .linkage = options.linkage, @@ -432,8 +433,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile { .zig_process = null, }; - compile.root_module.init(owner, options.root_module, compile); - if (options.zig_lib_dir) |lp| { compile.zig_lib_dir = lp.dupe(compile.step.owner); lp.addStepDependencies(&compile.step); @@ -583,9 +582,6 @@ pub fn checkObject(compile: *Compile) *Step.CheckObject { return Step.CheckObject.create(compile.step.owner, compile.getEmittedBin(), compile.rootModuleTarget().ofmt); } -/// deprecated: use `setLinkerScript` -pub const setLinkerScriptPath = setLinkerScript; - pub fn setLinkerScript(compile: *Compile, source: LazyPath) void { const b = compile.step.owner; compile.linker_script = source.dupe(b); @@ -609,16 +605,17 @@ pub fn dependsOnSystemLibrary(compile: *const Compile, name: []const u8) bool { var is_linking_libc = false; var is_linking_libcpp = false; - var dep_it = compile.root_module.iterateDependencies(compile, true); - while (dep_it.next()) |module| { - for (module.link_objects.items) |link_object| { - switch (link_object) { - .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true, - else => continue, + for (compile.getCompileDependencies(true)) |some_compile| { + for (some_compile.root_module.getGraph().modules) |mod| { + for (mod.link_objects.items) |lo| { + switch (lo) { + .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true, + else => {}, + } } + if (mod.link_libc) is_linking_libc = true; + if (mod.link_libcpp) is_linking_libcpp = true; } - is_linking_libc = is_linking_libc or module.link_libc == true; - is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true; } const target = compile.rootModuleTarget(); @@ -675,11 +672,6 @@ pub fn linkLibCpp(compile: *Compile) void { compile.root_module.link_libcpp = true; } -/// 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"); -} - const PkgConfigResult = struct { cflags: []const []const u8, libs: []const []const u8, @@ -805,16 +797,6 @@ 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(compile: *Compile, options: Module.AddCSourceFilesOptions) void { compile.root_module.addCSourceFiles(options); @@ -978,23 +960,22 @@ const CliNamedModules = struct { .modules = .{}, .names = .{}, }; - var dep_it = root_module.iterateDependencies(null, false); + const graph = root_module.getGraph(); { - const item = dep_it.next().?; - assert(root_module == item.module); + assert(graph.modules[0] == root_module); try compile.modules.put(arena, root_module, {}); try compile.names.put(arena, "root", {}); } - while (dep_it.next()) |item| { - var name = item.name; + for (graph.modules[1..], graph.names[1..]) |mod, orig_name| { + var name = orig_name; var n: usize = 0; while (true) { const gop = try compile.names.getOrPut(arena, name); if (!gop.found_existing) { - try compile.modules.putNoClobber(arena, item.module, {}); + try compile.modules.putNoClobber(arena, mod, {}); break; } - name = try std.fmt.allocPrint(arena, "{s}{d}", .{ item.name, n }); + name = try std.fmt.allocPrint(arena, "{s}{d}", .{ orig_name, n }); n += 1; } } @@ -1097,279 +1078,278 @@ fn getZigArgs(compile: *Compile, fuzz: bool) ![][]const u8 { // emitted if there is nothing to link. var total_linker_objects: usize = @intFromBool(compile.root_module.root_source_file != null); - { - // Fully recursive iteration including dynamic libraries to detect - // libc and libc++ linkage. - var dep_it = compile.root_module.iterateDependencies(compile, true); - while (dep_it.next()) |key| { - if (key.module.link_libc == true) compile.is_linking_libc = true; - if (key.module.link_libcpp == true) compile.is_linking_libcpp = true; + // Fully recursive iteration including dynamic libraries to detect + // libc and libc++ linkage. + for (compile.getCompileDependencies(true)) |some_compile| { + for (some_compile.root_module.getGraph().modules) |mod| { + if (mod.link_libc == true) compile.is_linking_libc = true; + if (mod.link_libcpp == true) compile.is_linking_libcpp = true; } } - var cli_named_modules = try CliNamedModules.init(arena, &compile.root_module); + var cli_named_modules = try CliNamedModules.init(arena, compile.root_module); // For this loop, don't chase dynamic libraries because their link // objects are already linked. - var dep_it = compile.root_module.iterateDependencies(compile, false); + for (compile.getCompileDependencies(false)) |dep_compile| { + for (dep_compile.root_module.getGraph().modules) |mod| { + // While walking transitive dependencies, if a given link object is + // already included in a library, it should not redundantly be + // placed on the linker line of the dependee. + const my_responsibility = dep_compile == compile; + const already_linked = !my_responsibility and dep_compile.isDynamicLibrary(); - while (dep_it.next()) |dep| { - // While walking transitive dependencies, if a given link object is - // already included in a library, it should not redundantly be - // placed on the linker line of the dependee. - const my_responsibility = dep.compile.? == compile; - const already_linked = !my_responsibility and dep.compile.?.isDynamicLibrary(); - - // Inherit dependencies on darwin frameworks. - if (!already_linked) { - for (dep.module.frameworks.keys(), dep.module.frameworks.values()) |name, info| { - try frameworks.put(arena, name, info); - } - } - - // Inherit dependencies on system libraries and static libraries. - for (dep.module.link_objects.items) |link_object| { - switch (link_object) { - .static_path => |static_path| { - if (my_responsibility) { - try zig_args.append(static_path.getPath2(dep.module.owner, step)); - total_linker_objects += 1; - } - }, - .system_lib => |system_lib| { - const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name); - if (system_lib_gop.found_existing) { - try zig_args.appendSlice(system_lib_gop.value_ptr.*); - continue; - } else { - system_lib_gop.value_ptr.* = &.{}; - } - - if (already_linked) - continue; - - if ((system_lib.search_strategy != prev_search_strategy or - system_lib.preferred_link_mode != prev_preferred_link_mode) and - compile.linkage != .static) - { - switch (system_lib.search_strategy) { - .no_fallback => switch (system_lib.preferred_link_mode) { - .dynamic => try zig_args.append("-search_dylibs_only"), - .static => try zig_args.append("-search_static_only"), - }, - .paths_first => switch (system_lib.preferred_link_mode) { - .dynamic => try zig_args.append("-search_paths_first"), - .static => try zig_args.append("-search_paths_first_static"), - }, - .mode_first => switch (system_lib.preferred_link_mode) { - .dynamic => try zig_args.append("-search_dylibs_first"), - .static => try zig_args.append("-search_static_first"), - }, - } - prev_search_strategy = system_lib.search_strategy; - prev_preferred_link_mode = system_lib.preferred_link_mode; - } - - const prefix: []const u8 = prefix: { - if (system_lib.needed) break :prefix "-needed-l"; - if (system_lib.weak) break :prefix "-weak-l"; - break :prefix "-l"; - }; - switch (system_lib.use_pkg_config) { - .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })), - .yes, .force => { - if (compile.runPkgConfig(system_lib.name)) |result| { - try zig_args.appendSlice(result.cflags); - try zig_args.appendSlice(result.libs); - try seen_system_libs.put(arena, system_lib.name, result.cflags); - } else |err| switch (err) { - error.PkgConfigInvalidOutput, - error.PkgConfigCrashed, - error.PkgConfigFailed, - error.PkgConfigNotInstalled, - error.PackageNotFound, - => switch (system_lib.use_pkg_config) { - .yes => { - // pkg-config failed, so fall back to linking the library - // by name directly. - try zig_args.append(b.fmt("{s}{s}", .{ - prefix, - system_lib.name, - })); - }, - .force => { - panic("pkg-config failed for library {s}", .{system_lib.name}); - }, - .no => unreachable, - }, - - else => |e| return e, - } - }, - } - }, - .other_step => |other| { - switch (other.kind) { - .exe => return step.fail("cannot link with an executable build artifact", .{}), - .@"test" => return step.fail("cannot link with a test", .{}), - .obj => { - const included_in_lib_or_obj = !my_responsibility and - (dep.compile.?.kind == .lib or dep.compile.?.kind == .obj); - if (!already_linked and !included_in_lib_or_obj) { - try zig_args.append(other.getEmittedBin().getPath2(b, step)); - total_linker_objects += 1; - } - }, - .lib => l: { - const other_produces_implib = other.producesImplib(); - const other_is_static = other_produces_implib or other.isStaticLibrary(); - - if (compile.isStaticLibrary() and other_is_static) { - // Avoid putting a static library inside a static library. - break :l; - } - - // For DLLs, we must link against the implib. - // For everything else, we directly link - // against the library file. - const full_path_lib = if (other_produces_implib) - other.getGeneratedFilePath("generated_implib", &compile.step) - else - other.getGeneratedFilePath("generated_bin", &compile.step); - - try zig_args.append(full_path_lib); - total_linker_objects += 1; - - if (other.linkage == .dynamic and - compile.rootModuleTarget().os.tag != .windows) - { - if (fs.path.dirname(full_path_lib)) |dirname| { - try zig_args.append("-rpath"); - try zig_args.append(dirname); - } - } - }, - } - }, - .assembly_file => |asm_file| l: { - if (!my_responsibility) break :l; - - if (prev_has_cflags) { - try zig_args.append("-cflags"); - try zig_args.append("--"); - prev_has_cflags = false; - } - try zig_args.append(asm_file.getPath2(dep.module.owner, step)); - total_linker_objects += 1; - }, - - .c_source_file => |c_source_file| l: { - if (!my_responsibility) break :l; - - if (c_source_file.flags.len == 0) { - if (prev_has_cflags) { - try zig_args.append("-cflags"); - try zig_args.append("--"); - prev_has_cflags = false; - } - } else { - try zig_args.append("-cflags"); - for (c_source_file.flags) |arg| { - try zig_args.append(arg); - } - try zig_args.append("--"); - prev_has_cflags = true; - } - try zig_args.append(c_source_file.file.getPath2(dep.module.owner, step)); - total_linker_objects += 1; - }, - - .c_source_files => |c_source_files| l: { - if (!my_responsibility) break :l; - - if (c_source_files.flags.len == 0) { - if (prev_has_cflags) { - try zig_args.append("-cflags"); - try zig_args.append("--"); - prev_has_cflags = false; - } - } else { - try zig_args.append("-cflags"); - for (c_source_files.flags) |flag| { - try zig_args.append(flag); - } - try zig_args.append("--"); - prev_has_cflags = true; - } - - const root_path = c_source_files.root.getPath2(dep.module.owner, step); - for (c_source_files.files) |file| { - try zig_args.append(b.pathJoin(&.{ root_path, file })); - } - - total_linker_objects += c_source_files.files.len; - }, - - .win32_resource_file => |rc_source_file| l: { - if (!my_responsibility) break :l; - - if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) { - if (prev_has_rcflags) { - try zig_args.append("-rcflags"); - try zig_args.append("--"); - prev_has_rcflags = false; - } - } else { - try zig_args.append("-rcflags"); - for (rc_source_file.flags) |arg| { - try zig_args.append(arg); - } - for (rc_source_file.include_paths) |include_path| { - try zig_args.append("/I"); - try zig_args.append(include_path.getPath2(dep.module.owner, step)); - } - try zig_args.append("--"); - prev_has_rcflags = true; - } - try zig_args.append(rc_source_file.file.getPath2(dep.module.owner, step)); - total_linker_objects += 1; - }, - } - } - - // We need to emit the --mod argument here so that the above link objects - // have the correct parent module, but only if the module is part of - // this compilation. - if (!my_responsibility) continue; - if (cli_named_modules.modules.getIndex(dep.module)) |module_cli_index| { - const module_cli_name = cli_named_modules.names.keys()[module_cli_index]; - try dep.module.appendZigProcessFlags(&zig_args, step); - - // --dep arguments - try zig_args.ensureUnusedCapacity(dep.module.import_table.count() * 2); - for (dep.module.import_table.keys(), dep.module.import_table.values()) |name, import| { - const import_index = cli_named_modules.modules.getIndex(import).?; - const import_cli_name = cli_named_modules.names.keys()[import_index]; - zig_args.appendAssumeCapacity("--dep"); - if (std.mem.eql(u8, import_cli_name, name)) { - zig_args.appendAssumeCapacity(import_cli_name); - } else { - zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, import_cli_name })); + // Inherit dependencies on darwin frameworks. + if (!already_linked) { + for (mod.frameworks.keys(), mod.frameworks.values()) |name, info| { + try frameworks.put(arena, name, info); } } - // When the CLI sees a -M argument, it determines whether it - // implies the existence of a Zig compilation unit based on - // whether there is a root source file. If there is no root - // source file, then this is not a zig compilation unit - it is - // perhaps a set of linker objects, or C source files instead. - // Linker objects are added to the CLI globally, while C source - // files must have a module parent. - if (dep.module.root_source_file) |lp| { - const src = lp.getPath2(dep.module.owner, step); - try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src })); - } else if (moduleNeedsCliArg(dep.module)) { - try zig_args.append(b.fmt("-M{s}", .{module_cli_name})); + // Inherit dependencies on system libraries and static libraries. + for (mod.link_objects.items) |link_object| { + switch (link_object) { + .static_path => |static_path| { + if (my_responsibility) { + try zig_args.append(static_path.getPath2(mod.owner, step)); + total_linker_objects += 1; + } + }, + .system_lib => |system_lib| { + const system_lib_gop = try seen_system_libs.getOrPut(arena, system_lib.name); + if (system_lib_gop.found_existing) { + try zig_args.appendSlice(system_lib_gop.value_ptr.*); + continue; + } else { + system_lib_gop.value_ptr.* = &.{}; + } + + if (already_linked) + continue; + + if ((system_lib.search_strategy != prev_search_strategy or + system_lib.preferred_link_mode != prev_preferred_link_mode) and + compile.linkage != .static) + { + switch (system_lib.search_strategy) { + .no_fallback => switch (system_lib.preferred_link_mode) { + .dynamic => try zig_args.append("-search_dylibs_only"), + .static => try zig_args.append("-search_static_only"), + }, + .paths_first => switch (system_lib.preferred_link_mode) { + .dynamic => try zig_args.append("-search_paths_first"), + .static => try zig_args.append("-search_paths_first_static"), + }, + .mode_first => switch (system_lib.preferred_link_mode) { + .dynamic => try zig_args.append("-search_dylibs_first"), + .static => try zig_args.append("-search_static_first"), + }, + } + prev_search_strategy = system_lib.search_strategy; + prev_preferred_link_mode = system_lib.preferred_link_mode; + } + + const prefix: []const u8 = prefix: { + if (system_lib.needed) break :prefix "-needed-l"; + if (system_lib.weak) break :prefix "-weak-l"; + break :prefix "-l"; + }; + switch (system_lib.use_pkg_config) { + .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })), + .yes, .force => { + if (compile.runPkgConfig(system_lib.name)) |result| { + try zig_args.appendSlice(result.cflags); + try zig_args.appendSlice(result.libs); + try seen_system_libs.put(arena, system_lib.name, result.cflags); + } else |err| switch (err) { + error.PkgConfigInvalidOutput, + error.PkgConfigCrashed, + error.PkgConfigFailed, + error.PkgConfigNotInstalled, + error.PackageNotFound, + => switch (system_lib.use_pkg_config) { + .yes => { + // pkg-config failed, so fall back to linking the library + // by name directly. + try zig_args.append(b.fmt("{s}{s}", .{ + prefix, + system_lib.name, + })); + }, + .force => { + panic("pkg-config failed for library {s}", .{system_lib.name}); + }, + .no => unreachable, + }, + + else => |e| return e, + } + }, + } + }, + .other_step => |other| { + switch (other.kind) { + .exe => return step.fail("cannot link with an executable build artifact", .{}), + .@"test" => return step.fail("cannot link with a test", .{}), + .obj => { + const included_in_lib_or_obj = !my_responsibility and + (dep_compile.kind == .lib or dep_compile.kind == .obj); + if (!already_linked and !included_in_lib_or_obj) { + try zig_args.append(other.getEmittedBin().getPath2(b, step)); + total_linker_objects += 1; + } + }, + .lib => l: { + const other_produces_implib = other.producesImplib(); + const other_is_static = other_produces_implib or other.isStaticLibrary(); + + if (compile.isStaticLibrary() and other_is_static) { + // Avoid putting a static library inside a static library. + break :l; + } + + // For DLLs, we must link against the implib. + // For everything else, we directly link + // against the library file. + const full_path_lib = if (other_produces_implib) + other.getGeneratedFilePath("generated_implib", &compile.step) + else + other.getGeneratedFilePath("generated_bin", &compile.step); + + try zig_args.append(full_path_lib); + total_linker_objects += 1; + + if (other.linkage == .dynamic and + compile.rootModuleTarget().os.tag != .windows) + { + if (fs.path.dirname(full_path_lib)) |dirname| { + try zig_args.append("-rpath"); + try zig_args.append(dirname); + } + } + }, + } + }, + .assembly_file => |asm_file| l: { + if (!my_responsibility) break :l; + + if (prev_has_cflags) { + try zig_args.append("-cflags"); + try zig_args.append("--"); + prev_has_cflags = false; + } + try zig_args.append(asm_file.getPath2(mod.owner, step)); + total_linker_objects += 1; + }, + + .c_source_file => |c_source_file| l: { + if (!my_responsibility) break :l; + + if (c_source_file.flags.len == 0) { + if (prev_has_cflags) { + try zig_args.append("-cflags"); + try zig_args.append("--"); + prev_has_cflags = false; + } + } else { + try zig_args.append("-cflags"); + for (c_source_file.flags) |arg| { + try zig_args.append(arg); + } + try zig_args.append("--"); + prev_has_cflags = true; + } + try zig_args.append(c_source_file.file.getPath2(mod.owner, step)); + total_linker_objects += 1; + }, + + .c_source_files => |c_source_files| l: { + if (!my_responsibility) break :l; + + if (c_source_files.flags.len == 0) { + if (prev_has_cflags) { + try zig_args.append("-cflags"); + try zig_args.append("--"); + prev_has_cflags = false; + } + } else { + try zig_args.append("-cflags"); + for (c_source_files.flags) |flag| { + try zig_args.append(flag); + } + try zig_args.append("--"); + prev_has_cflags = true; + } + + const root_path = c_source_files.root.getPath2(mod.owner, step); + for (c_source_files.files) |file| { + try zig_args.append(b.pathJoin(&.{ root_path, file })); + } + + total_linker_objects += c_source_files.files.len; + }, + + .win32_resource_file => |rc_source_file| l: { + if (!my_responsibility) break :l; + + if (rc_source_file.flags.len == 0 and rc_source_file.include_paths.len == 0) { + if (prev_has_rcflags) { + try zig_args.append("-rcflags"); + try zig_args.append("--"); + prev_has_rcflags = false; + } + } else { + try zig_args.append("-rcflags"); + for (rc_source_file.flags) |arg| { + try zig_args.append(arg); + } + for (rc_source_file.include_paths) |include_path| { + try zig_args.append("/I"); + try zig_args.append(include_path.getPath2(mod.owner, step)); + } + try zig_args.append("--"); + prev_has_rcflags = true; + } + try zig_args.append(rc_source_file.file.getPath2(mod.owner, step)); + total_linker_objects += 1; + }, + } + } + + // We need to emit the --mod argument here so that the above link objects + // have the correct parent module, but only if the module is part of + // this compilation. + if (!my_responsibility) continue; + if (cli_named_modules.modules.getIndex(mod)) |module_cli_index| { + const module_cli_name = cli_named_modules.names.keys()[module_cli_index]; + try mod.appendZigProcessFlags(&zig_args, step); + + // --dep arguments + try zig_args.ensureUnusedCapacity(mod.import_table.count() * 2); + for (mod.import_table.keys(), mod.import_table.values()) |name, import| { + const import_index = cli_named_modules.modules.getIndex(import).?; + const import_cli_name = cli_named_modules.names.keys()[import_index]; + zig_args.appendAssumeCapacity("--dep"); + if (std.mem.eql(u8, import_cli_name, name)) { + zig_args.appendAssumeCapacity(import_cli_name); + } else { + zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, import_cli_name })); + } + } + + // When the CLI sees a -M argument, it determines whether it + // implies the existence of a Zig compilation unit based on + // whether there is a root source file. If there is no root + // source file, then this is not a zig compilation unit - it is + // perhaps a set of linker objects, or C source files instead. + // Linker objects are added to the CLI globally, while C source + // files must have a module parent. + if (mod.root_source_file) |lp| { + const src = lp.getPath2(mod.owner, step); + try zig_args.append(b.fmt("-M{s}={s}", .{ module_cli_name, src })); + } else if (moduleNeedsCliArg(mod)) { + try zig_args.append(b.fmt("-M{s}", .{module_cli_name})); + } } } } @@ -2081,3 +2061,35 @@ fn moduleNeedsCliArg(mod: *const Module) bool { else => continue, } else false; } + +/// Return the full set of `Step.Compile` which `start` depends on, recursively. `start` itself is +/// always returned as the first element. If `chase_dynamic` is `false`, then dynamic libraries are +/// not included, and their dependencies are not considered; if `chase_dynamic` is `true`, dynamic +/// libraries are treated the same as other linked `Compile`s. +pub fn getCompileDependencies(start: *Compile, chase_dynamic: bool) []const *Compile { + const arena = start.step.owner.graph.arena; + + var compiles: std.AutoArrayHashMapUnmanaged(*Compile, void) = .empty; + var next_idx: usize = 0; + + compiles.putNoClobber(arena, start, {}) catch @panic("OOM"); + + while (next_idx < compiles.count()) { + const compile = compiles.keys()[next_idx]; + next_idx += 1; + + for (compile.root_module.getGraph().modules) |mod| { + for (mod.link_objects.items) |lo| { + switch (lo) { + .other_step => |other_compile| { + if (!chase_dynamic and other_compile.isDynamicLibrary()) continue; + compiles.put(arena, other_compile, {}) catch @panic("OOM"); + }, + else => {}, + } + } + } + } + + return compiles.keys(); +} diff --git a/lib/std/Build/Step/ObjCopy.zig b/lib/std/Build/Step/ObjCopy.zig index 8f0f62e222..9b2c2d596f 100644 --- a/lib/std/Build/Step/ObjCopy.zig +++ b/lib/std/Build/Step/ObjCopy.zig @@ -135,9 +135,6 @@ pub fn create( return objcopy; } -/// deprecated: use getOutput -pub const getOutputSource = getOutput; - pub fn getOutput(objcopy: *const ObjCopy) std.Build.LazyPath { return .{ .generated = .{ .file = &objcopy.output_file } }; } diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 41739dba47..44228bef20 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -390,20 +390,12 @@ pub fn addOptionPath( path.addStepDependencies(&options.step); } -/// Deprecated: use `addOptionPath(options, name, artifact.getEmittedBin())` instead. -pub fn addOptionArtifact(options: *Options, name: []const u8, artifact: *Step.Compile) void { - return addOptionPath(options, name, artifact.getEmittedBin()); -} - pub fn createModule(options: *Options) *std.Build.Module { return options.step.owner.createModule(.{ .root_source_file = options.getOutput(), }); } -/// deprecated: use `getOutput` -pub const getSource = getOutput; - /// Returns the main artifact of this Build Step which is a Zig source file /// generated from the key-value pairs of the Options. pub fn getOutput(options: *Options) LazyPath { diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 6a2ebc6e9f..37db10916f 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -43,9 +43,6 @@ stdio: StdIo, /// It should be only set using `setStdIn`. stdin: StdIn, -/// Deprecated: use `addFileInput` -extra_file_dependencies: []const []const u8, - /// Additional input files that, when modified, indicate that the Run step /// should be re-executed. /// If the Run step is determined to have side-effects, the Run step is always @@ -178,7 +175,6 @@ pub fn create(owner: *std.Build, name: []const u8) *Run { .disable_zig_progress = false, .stdio = .infer_from_args, .stdin = .none, - .extra_file_dependencies = &.{}, .file_inputs = .{}, .rename_step_with_output_arg = true, .skip_foreign_checks = false, @@ -364,16 +360,10 @@ pub fn addPrefixedOutputDirectoryArg( return .{ .generated = .{ .file = &output.generated_file } }; } -/// deprecated: use `addDirectoryArg` -pub const addDirectorySourceArg = addDirectoryArg; - pub fn addDirectoryArg(run: *Run, directory_source: std.Build.LazyPath) void { run.addPrefixedDirectoryArg("", directory_source); } -// deprecated: use `addPrefixedDirectoryArg` -pub const addPrefixedDirectorySourceArg = addPrefixedDirectoryArg; - pub fn addPrefixedDirectoryArg(run: *Run, prefix: []const u8, directory_source: std.Build.LazyPath) void { const b = run.step.owner; @@ -698,9 +688,6 @@ fn make(step: *Step, options: Step.MakeOptions) !void { hashStdIo(&man.hash, run.stdio); - for (run.extra_file_dependencies) |file_path| { - _ = try man.addFile(b.pathFromRoot(file_path), null); - } for (run.file_inputs.items) |lazy_path| { _ = try man.addFile(lazy_path.getPath2(b, step), null); } @@ -1732,15 +1719,12 @@ fn evalGeneric(run: *Run, child: *std.process.Child) !StdIoResult { fn addPathForDynLibs(run: *Run, artifact: *Step.Compile) void { const b = run.step.owner; - var it = artifact.root_module.iterateDependencies(artifact, true); - while (it.next()) |item| { - const other = item.compile.?; - if (item.module == &other.root_module) { - if (item.module.resolved_target.?.result.os.tag == .windows and - other.isDynamicLibrary()) - { - addPathDir(run, fs.path.dirname(other.getEmittedBin().getPath2(b, &run.step)).?); - } + const compiles = artifact.getCompileDependencies(true); + for (compiles) |compile| { + if (compile.root_module.resolved_target.?.result.os.tag == .windows and + compile.isDynamicLibrary()) + { + addPathDir(run, fs.path.dirname(compile.getEmittedBin().getPath2(b, &run.step)).?); } } } diff --git a/lib/std/Build/Step/TranslateC.zig b/lib/std/Build/Step/TranslateC.zig index 13f4375999..2592719f80 100644 --- a/lib/std/Build/Step/TranslateC.zig +++ b/lib/std/Build/Step/TranslateC.zig @@ -63,6 +63,7 @@ pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath { return .{ .generated = .{ .file = &translate_c.output_file } }; } +/// Deprecated: use `createModule` or `addModule` with `std.Build.addExecutable` instead. /// Creates a step to build an executable from the translated source. pub fn addExecutable(translate_c: *TranslateC, options: AddExecutableOptions) *Step.Compile { return translate_c.step.owner.addExecutable(.{ @@ -81,6 +82,9 @@ pub fn addExecutable(translate_c: *TranslateC, options: AddExecutableOptions) *S pub fn addModule(translate_c: *TranslateC, name: []const u8) *std.Build.Module { return translate_c.step.owner.addModule(name, .{ .root_source_file = translate_c.getOutput(), + .target = translate_c.target, + .optimize = translate_c.optimize, + .link_libc = translate_c.link_libc, }); } diff --git a/test/link/bss/build.zig b/test/link/bss/build.zig index 27fd016ea1..128ec04caa 100644 --- a/test/link/bss/build.zig +++ b/test/link/bss/build.zig @@ -6,9 +6,11 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "bss", - .root_source_file = b.path("main.zig"), - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), }); const run = b.addRunArtifact(exe); diff --git a/test/link/common_symbols/build.zig b/test/link/common_symbols/build.zig index 3f0e4a19f0..d4826956a5 100644 --- a/test/link/common_symbols/build.zig +++ b/test/link/common_symbols/build.zig @@ -13,19 +13,24 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib_a = b.addStaticLibrary(.{ .name = "a", - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = b.graph.host, + }), }); - lib_a.addCSourceFiles(.{ + lib_a.root_module.addCSourceFiles(.{ .files = &.{ "c.c", "a.c", "b.c" }, .flags = &.{"-fcommon"}, }); const test_exe = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + }), }); - test_exe.linkLibrary(lib_a); + test_exe.root_module.linkLibrary(lib_a); test_step.dependOn(&b.addRunArtifact(test_exe).step); } diff --git a/test/link/common_symbols_alignment/build.zig b/test/link/common_symbols_alignment/build.zig index 384d60b90d..6f0a0efd80 100644 --- a/test/link/common_symbols_alignment/build.zig +++ b/test/link/common_symbols_alignment/build.zig @@ -13,19 +13,25 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib_a = b.addStaticLibrary(.{ .name = "a", - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = b.graph.host, + }), }); - lib_a.addCSourceFiles(.{ + lib_a.root_module.addCSourceFiles(.{ .files = &.{"a.c"}, .flags = &.{"-fcommon"}, }); const test_exe = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); - test_exe.linkLibrary(lib_a); + test_exe.root_module.linkLibrary(lib_a); test_step.dependOn(&b.addRunArtifact(test_exe).step); } diff --git a/test/link/glibc_compat/build.zig b/test/link/glibc_compat/build.zig index e9d7ee412e..972a7a6ae9 100644 --- a/test/link/glibc_compat/build.zig +++ b/test/link/glibc_compat/build.zig @@ -14,12 +14,15 @@ pub fn build(b: *std.Build) void { for ([_][]const u8{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| { const exe = b.addExecutable(.{ .name = t, - .target = b.resolveTargetQuery(std.Target.Query.parse( - .{ .arch_os_abi = t }, - ) catch unreachable), + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(std.Target.Query.parse( + .{ .arch_os_abi = t }, + ) catch unreachable), + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.path("main.c") }); - exe.linkLibC(); + exe.root_module.addCSourceFile(.{ .file = b.path("main.c") }); // TODO: actually test the output _ = exe.getEmittedBin(); test_step.dependOn(&exe.step); @@ -53,10 +56,13 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = t, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.path("glibc_runtime_check.c") }); - exe.linkLibC(); + exe.root_module.addCSourceFile(.{ .file = b.path("glibc_runtime_check.c") }); // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig // test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453 @@ -149,10 +155,12 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = t, - .root_source_file = b.path("glibc_runtime_check.zig"), - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("glibc_runtime_check.zig"), + .target = target, + .link_libc = true, + }), }); - exe.linkLibC(); // Only try running the test if the host glibc is known to be good enough. Ideally, the Zig // test runner would be able to check this, but see https://github.com/ziglang/zig/pull/17702#issuecomment-1831310453 diff --git a/test/link/interdependent_static_c_libs/build.zig b/test/link/interdependent_static_c_libs/build.zig index 8a700b74ff..b18371fdcc 100644 --- a/test/link/interdependent_static_c_libs/build.zig +++ b/test/link/interdependent_static_c_libs/build.zig @@ -13,27 +13,36 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib_a = b.addStaticLibrary(.{ .name = "a", - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = b.graph.host, + }), }); - lib_a.addCSourceFile(.{ .file = b.path("a.c"), .flags = &[_][]const u8{} }); - lib_a.addIncludePath(b.path(".")); + lib_a.root_module.addCSourceFile(.{ .file = b.path("a.c"), .flags = &[_][]const u8{} }); + lib_a.root_module.addIncludePath(b.path(".")); const lib_b = b.addStaticLibrary(.{ .name = "b", - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = b.graph.host, + }), }); - lib_b.addCSourceFile(.{ .file = b.path("b.c"), .flags = &[_][]const u8{} }); - lib_b.addIncludePath(b.path(".")); + lib_b.root_module.addCSourceFile(.{ .file = b.path("b.c"), .flags = &[_][]const u8{} }); + lib_b.root_module.addIncludePath(b.path(".")); const test_exe = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); - test_exe.linkLibrary(lib_a); - test_exe.linkLibrary(lib_b); - test_exe.addIncludePath(b.path(".")); + test_exe.root_module.linkLibrary(lib_a); + test_exe.root_module.linkLibrary(lib_b); + test_exe.root_module.addIncludePath(b.path(".")); test_step.dependOn(&b.addRunArtifact(test_exe).step); } diff --git a/test/link/link.zig b/test/link/link.zig index 4537846353..960d8fd743 100644 --- a/test/link/link.zig +++ b/test/link/link.zig @@ -47,81 +47,85 @@ const OverlayOptions = struct { }; pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Compile { - return addCompileStep(b, base, overlay, .exe); + return b.addExecutable(.{ + .name = overlay.name, + .root_module = createModule(b, base, overlay), + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + }); } pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Compile { - return addCompileStep(b, base, overlay, .obj); + return b.addObject(.{ + .name = overlay.name, + .root_module = createModule(b, base, overlay), + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + }); } pub fn addStaticLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile { - return addCompileStep(b, base, overlay, .static_lib); + return b.addStaticLibrary(.{ + .name = overlay.name, + .root_module = createModule(b, base, overlay), + .use_llvm = base.use_llvm, + .use_lld = base.use_lld, + }); } pub fn addSharedLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile { - return addCompileStep(b, base, overlay, .shared_lib); -} - -fn addCompileStep( - b: *Build, - base: Options, - overlay: OverlayOptions, - kind: enum { exe, obj, shared_lib, static_lib }, -) *Compile { - const compile_step = Compile.create(b, .{ + return b.addSharedLibrary(.{ .name = overlay.name, - .root_module = .{ - .target = base.target, - .optimize = base.optimize, - .root_source_file = rsf: { - const bytes = overlay.zig_source_bytes orelse break :rsf null; - const name = b.fmt("{s}.zig", .{overlay.name}); - break :rsf b.addWriteFiles().add(name, bytes); - }, - .pic = overlay.pic, - .strip = if (base.strip) |s| s else overlay.strip, - }, + .root_module = createModule(b, base, overlay), .use_llvm = base.use_llvm, .use_lld = base.use_lld, - .kind = switch (kind) { - .exe => .exe, - .obj => .obj, - .shared_lib, .static_lib => .lib, - }, - .linkage = switch (kind) { - .exe, .obj => null, - .shared_lib => .dynamic, - .static_lib => .static, - }, }); +} + +fn createModule(b: *Build, base: Options, overlay: OverlayOptions) *Build.Module { + const write_files = b.addWriteFiles(); + + const mod = b.createModule(.{ + .target = base.target, + .optimize = base.optimize, + .root_source_file = rsf: { + const bytes = overlay.zig_source_bytes orelse break :rsf null; + const name = b.fmt("{s}.zig", .{overlay.name}); + break :rsf write_files.add(name, bytes); + }, + .pic = overlay.pic, + .strip = if (base.strip) |s| s else overlay.strip, + }); + if (overlay.objcpp_source_bytes) |bytes| { - compile_step.addCSourceFile(.{ - .file = b.addWriteFiles().add("a.mm", bytes), + mod.addCSourceFile(.{ + .file = write_files.add("a.mm", bytes), .flags = overlay.objcpp_source_flags, }); } if (overlay.objc_source_bytes) |bytes| { - compile_step.addCSourceFile(.{ - .file = b.addWriteFiles().add("a.m", bytes), + mod.addCSourceFile(.{ + .file = write_files.add("a.m", bytes), .flags = overlay.objc_source_flags, }); } if (overlay.cpp_source_bytes) |bytes| { - compile_step.addCSourceFile(.{ - .file = b.addWriteFiles().add("a.cpp", bytes), + mod.addCSourceFile(.{ + .file = write_files.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), + mod.addCSourceFile(.{ + .file = write_files.add("a.c", bytes), .flags = overlay.c_source_flags, }); } if (overlay.asm_source_bytes) |bytes| { - compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes)); + mod.addAssemblyFile(write_files.add("a.s", bytes)); } - return compile_step; + + return mod; } pub fn addRunArtifact(comp: *Compile) *Run { diff --git a/test/link/static_libs_from_object_files/build.zig b/test/link/static_libs_from_object_files/build.zig index 8e4a6151be..461f26a374 100644 --- a/test/link/static_libs_from_object_files/build.zig +++ b/test/link/static_libs_from_object_files/build.zig @@ -57,13 +57,15 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built { const exe = b.addExecutable(.{ .name = "test1", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.graph.host, + }), }); for (files) |file| { - exe.addCSourceFile(.{ .file = file, .flags = &flags }); + exe.root_module.addCSourceFile(.{ .file = file, .flags = &flags }); } const run_cmd = b.addRunArtifact(exe); @@ -75,30 +77,33 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built // using static librairies { + const mod_a = b.createModule(.{ .target = b.graph.host, .optimize = optimize }); + const mod_b = b.createModule(.{ .target = b.graph.host, .optimize = optimize }); + + for (files, 1..) |file, i| { + const mod = if (i & 1 == 0) mod_a else mod_b; + mod.addCSourceFile(.{ .file = file, .flags = &flags }); + } + const lib_a = b.addStaticLibrary(.{ .name = "test2_a", - .target = b.graph.host, - .optimize = optimize, + .root_module = mod_a, }); const lib_b = b.addStaticLibrary(.{ .name = "test2_b", - .target = b.graph.host, - .optimize = optimize, + .root_module = mod_b, }); - for (files, 1..) |file, i| { - const lib = if (i & 1 == 0) lib_a else lib_b; - lib.addCSourceFile(.{ .file = file, .flags = &flags }); - } - const exe = b.addExecutable(.{ .name = "test2", - .root_source_file = b.path("main.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); - exe.linkLibrary(lib_a); - exe.linkLibrary(lib_b); + exe.root_module.linkLibrary(lib_a); + exe.root_module.linkLibrary(lib_b); const run_cmd = b.addRunArtifact(exe); run_cmd.skip_foreign_checks = true; @@ -109,37 +114,41 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built // using static librairies and object files { + const mod_a = b.createModule(.{ .target = b.graph.host, .optimize = optimize }); + const mod_b = b.createModule(.{ .target = b.graph.host, .optimize = optimize }); + + for (files, 1..) |file, i| { + const obj_mod = b.createModule(.{ .target = b.graph.host, .optimize = optimize }); + obj_mod.addCSourceFile(.{ .file = file, .flags = &flags }); + + const obj = b.addObject(.{ + .name = b.fmt("obj_{}", .{i}), + .root_module = obj_mod, + }); + + const lib_mod = if (i & 1 == 0) mod_a else mod_b; + lib_mod.addObject(obj); + } + const lib_a = b.addStaticLibrary(.{ .name = "test3_a", - .target = b.graph.host, - .optimize = optimize, + .root_module = mod_a, }); const lib_b = b.addStaticLibrary(.{ .name = "test3_b", - .target = b.graph.host, - .optimize = optimize, + .root_module = mod_b, }); - for (files, 1..) |file, i| { - const obj = b.addObject(.{ - .name = b.fmt("obj_{}", .{i}), - .target = b.graph.host, - .optimize = optimize, - }); - obj.addCSourceFile(.{ .file = file, .flags = &flags }); - - const lib = if (i & 1 == 0) lib_a else lib_b; - lib.addObject(obj); - } - const exe = b.addExecutable(.{ .name = "test3", - .root_source_file = b.path("main.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); - exe.linkLibrary(lib_a); - exe.linkLibrary(lib_b); + exe.root_module.linkLibrary(lib_a); + exe.root_module.linkLibrary(lib_b); const run_cmd = b.addRunArtifact(exe); run_cmd.skip_foreign_checks = true; diff --git a/test/link/wasm/archive/build.zig b/test/link/wasm/archive/build.zig index 34c5818ad8..e57eb25fc6 100644 --- a/test/link/wasm/archive/build.zig +++ b/test/link/wasm/archive/build.zig @@ -17,10 +17,12 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize // and therefore link with its archive file. const lib = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/basic-features/build.zig b/test/link/wasm/basic-features/build.zig index 87355a5c12..1eaeeb5196 100644 --- a/test/link/wasm/basic-features/build.zig +++ b/test/link/wasm/basic-features/build.zig @@ -6,13 +6,15 @@ pub fn build(b: *std.Build) void { // Library with explicitly set cpu features const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("main.zig"), - .optimize = .Debug, - .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, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = .Debug, + .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; diff --git a/test/link/wasm/bss/build.zig b/test/link/wasm/bss/build.zig index dc7d1bae4b..d73c7ed757 100644 --- a/test/link/wasm/bss/build.zig +++ b/test/link/wasm/bss/build.zig @@ -16,10 +16,12 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize_mode, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize_mode, + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; @@ -64,10 +66,12 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib2.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize_mode, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib2.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize_mode, + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/export-data/build.zig b/test/link/wasm/export-data/build.zig index 7e3c5e5841..726d6caba5 100644 --- a/test/link/wasm/export-data/build.zig +++ b/test/link/wasm/export-data/build.zig @@ -11,9 +11,11 @@ pub fn build(b: *std.Build) void { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .optimize = .ReleaseSafe, // to make the output deterministic in address positions - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .optimize = .ReleaseSafe, // to make the output deterministic in address positions + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + }), }); lib.entry = .disabled; lib.use_lld = false; diff --git a/test/link/wasm/export/build.zig b/test/link/wasm/export/build.zig index 368826843a..5c40612ca2 100644 --- a/test/link/wasm/export/build.zig +++ b/test/link/wasm/export/build.zig @@ -15,9 +15,11 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const no_export = b.addExecutable(.{ .name = "no-export", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + }), }); no_export.entry = .disabled; no_export.use_llvm = false; @@ -25,9 +27,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const dynamic_export = b.addExecutable(.{ .name = "dynamic", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + }), }); dynamic_export.entry = .disabled; dynamic_export.rdynamic = true; @@ -36,9 +40,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const force_export = b.addExecutable(.{ .name = "force", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + }), }); force_export.entry = .disabled; force_export.root_module.export_symbol_names = &.{"foo"}; diff --git a/test/link/wasm/extern-mangle/build.zig b/test/link/wasm/extern-mangle/build.zig index 5a4cbc1cda..c856611e97 100644 --- a/test/link/wasm/extern-mangle/build.zig +++ b/test/link/wasm/extern-mangle/build.zig @@ -13,9 +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 lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + }), }); lib.entry = .disabled; lib.import_symbols = true; // import `a` and `b` diff --git a/test/link/wasm/extern/build.zig b/test/link/wasm/extern/build.zig index 77dcbc47c5..236f01fd88 100644 --- a/test/link/wasm/extern/build.zig +++ b/test/link/wasm/extern/build.zig @@ -15,9 +15,11 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const exe = b.addExecutable(.{ .name = "extern", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }), + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }), + }), }); exe.addCSourceFile(.{ .file = b.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 3042ddf5d5..7fd306285c 100644 --- a/test/link/wasm/function-table/build.zig +++ b/test/link/wasm/function-table/build.zig @@ -15,9 +15,11 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const import_table = b.addExecutable(.{ .name = "import_table", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + }), }); import_table.entry = .disabled; import_table.use_llvm = false; @@ -27,9 +29,11 @@ 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 = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + }), }); export_table.entry = .disabled; export_table.use_llvm = false; @@ -39,9 +43,11 @@ 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 = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + }), }); regular_table.entry = .disabled; regular_table.use_llvm = false; diff --git a/test/link/wasm/infer-features/build.zig b/test/link/wasm/infer-features/build.zig index af40175da0..83aab77841 100644 --- a/test/link/wasm/infer-features/build.zig +++ b/test/link/wasm/infer-features/build.zig @@ -6,31 +6,36 @@ pub fn build(b: *std.Build) void { // Wasm Object file which we will use to infer the features from const c_obj = b.addObject(.{ .name = "c_obj", - .optimize = .Debug, - .target = b.resolveTargetQuery(.{ - .cpu_arch = .wasm32, - .cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge }, - .os_tag = .freestanding, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = .Debug, + .target = b.resolveTargetQuery(.{ + .cpu_arch = .wasm32, + .cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge }, + .os_tag = .freestanding, + }), }), }); - c_obj.addCSourceFile(.{ .file = b.path("foo.c"), .flags = &.{} }); + c_obj.root_module.addCSourceFile(.{ .file = b.path("foo.c"), .flags = &.{} }); // Wasm library that doesn't have any features specified. This will // infer its featureset from other linked object files. const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("main.zig"), - .optimize = .Debug, - .target = b.resolveTargetQuery(.{ - .cpu_arch = .wasm32, - .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, - .os_tag = .freestanding, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = .Debug, + .target = b.resolveTargetQuery(.{ + .cpu_arch = .wasm32, + .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, + .os_tag = .freestanding, + }), }), }); lib.entry = .disabled; lib.use_llvm = false; lib.use_lld = false; - lib.addObject(c_obj); + lib.root_module.addObject(c_obj); // Verify the result contains the features from the C Object file. const check = lib.checkObject(); diff --git a/test/link/wasm/producers/build.zig b/test/link/wasm/producers/build.zig index 2dae6e3f9b..e31b07ce8b 100644 --- a/test/link/wasm/producers/build.zig +++ b/test/link/wasm/producers/build.zig @@ -16,10 +16,12 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/segments/build.zig b/test/link/wasm/segments/build.zig index 3c8bac3f07..c2c62a3b88 100644 --- a/test/link/wasm/segments/build.zig +++ b/test/link/wasm/segments/build.zig @@ -15,10 +15,12 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/shared-memory/build.zig b/test/link/wasm/shared-memory/build.zig index 7807a95a4f..7725454f3f 100644 --- a/test/link/wasm/shared-memory/build.zig +++ b/test/link/wasm/shared-memory/build.zig @@ -13,16 +13,18 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode) void { const exe = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ - .cpu_arch = .wasm32, - .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, - .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }), - .os_tag = .freestanding, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ + .cpu_arch = .wasm32, + .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp }, + .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }), + .os_tag = .freestanding, + }), + .optimize = optimize_mode, + .strip = false, + .single_threaded = false, }), - .optimize = optimize_mode, - .strip = false, - .single_threaded = false, }); exe.entry = .disabled; exe.use_lld = false; diff --git a/test/link/wasm/stack_pointer/build.zig b/test/link/wasm/stack_pointer/build.zig index e42e362880..57ce5ddefd 100644 --- a/test/link/wasm/stack_pointer/build.zig +++ b/test/link/wasm/stack_pointer/build.zig @@ -15,10 +15,12 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const lib = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + .strip = false, + }), }); lib.entry = .disabled; lib.use_llvm = false; diff --git a/test/link/wasm/type/build.zig b/test/link/wasm/type/build.zig index 46b80dbfe5..aa19d4d403 100644 --- a/test/link/wasm/type/build.zig +++ b/test/link/wasm/type/build.zig @@ -15,10 +15,12 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const exe = b.addExecutable(.{ .name = "lib", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), - .optimize = optimize, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }), + .optimize = optimize, + .strip = false, + }), }); exe.entry = .disabled; exe.use_llvm = false; diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 208e8a6ce1..360a0fda92 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -572,7 +572,10 @@ pub fn lowerToTranslateCSteps( }); translate_c.step.name = b.fmt("{s} translate-c", .{annotated_case_name}); - const run_exe = translate_c.addExecutable(.{}); + const run_exe = b.addExecutable(.{ + .name = "translated_c", + .root_module = translate_c.createModule(), + }); run_exe.step.name = b.fmt("{s} build-exe", .{annotated_case_name}); run_exe.linkLibC(); const run = b.addRunArtifact(run_exe); @@ -660,34 +663,37 @@ pub fn lowerToBuildSteps( file_sources.put(file.path, writefiles.add(file.path, file.src)) catch @panic("OOM"); } - const artifact = if (case.is_test) b.addTest(.{ + const mod = b.createModule(.{ .root_source_file = root_source_file, - .name = case.name, .target = case.target, .optimize = case.optimize_mode, + }); + if (case.link_libc) mod.link_libc = true; + if (case.pic) |pic| mod.pic = pic; + for (case.deps.items) |dep| { + mod.addAnonymousImport(dep.name, .{ + .root_source_file = file_sources.get(dep.path).?, + }); + } + + const artifact = if (case.is_test) b.addTest(.{ + .name = case.name, + .root_module = mod, }) else switch (case.output_mode) { .Obj => b.addObject(.{ - .root_source_file = root_source_file, .name = case.name, - .target = case.target, - .optimize = case.optimize_mode, + .root_module = mod, }), .Lib => b.addStaticLibrary(.{ - .root_source_file = root_source_file, .name = case.name, - .target = case.target, - .optimize = case.optimize_mode, + .root_module = mod, }), .Exe => b.addExecutable(.{ - .root_source_file = root_source_file, .name = case.name, - .target = case.target, - .optimize = case.optimize_mode, + .root_module = mod, }), }; - if (case.link_libc) artifact.linkLibC(); - if (case.pic) |pic| artifact.root_module.pic = pic; if (case.pie) |pie| artifact.pie = pie; switch (case.backend) { @@ -701,12 +707,6 @@ pub fn lowerToBuildSteps( }, } - for (case.deps.items) |dep| { - artifact.root_module.addAnonymousImport(dep.name, .{ - .root_source_file = file_sources.get(dep.path).?, - }); - } - switch (update.case) { .Compile => { // Force the binary to be emitted if requested. diff --git a/test/src/CompareOutput.zig b/test/src/CompareOutput.zig index 58c1238705..c491028333 100644 --- a/test/src/CompareOutput.zig +++ b/test/src/CompareOutput.zig @@ -89,19 +89,22 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { switch (case.special) { Special.Asm => { - const annotated_case_name = fmt.allocPrint(self.b.allocator, "run assemble-and-link {s}", .{ + const annotated_case_name = b.fmt("run assemble-and-link {s}", .{ case.name, - }) catch @panic("OOM"); + }); for (self.test_filters) |test_filter| { if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; } else if (self.test_filters.len > 0) return; const exe = b.addExecutable(.{ .name = "test", - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.graph.host, + .optimize = .Debug, + }), }); - exe.addAssemblyFile(first_file); + exe.root_module.addAssemblyFile(first_file); const run = b.addRunArtifact(exe); run.setName(annotated_case_name); @@ -112,22 +115,22 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { }, Special.None => { for (self.optimize_modes) |optimize| { - const annotated_case_name = fmt.allocPrint(self.b.allocator, "run compare-output {s} ({s})", .{ + const annotated_case_name = b.fmt("run compare-output {s} ({s})", .{ case.name, @tagName(optimize), - }) catch @panic("OOM"); + }); for (self.test_filters) |test_filter| { if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; } else if (self.test_filters.len > 0) return; const exe = b.addExecutable(.{ .name = "test", - .root_source_file = first_file, - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = first_file, + .optimize = optimize, + .target = b.graph.host, + }), }); - if (case.link_libc) { - exe.linkSystemLibrary("c"); - } + if (case.link_libc) exe.root_module.link_libc = true; const run = b.addRunArtifact(exe); run.setName(annotated_case_name); @@ -140,20 +143,20 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { Special.RuntimeSafety => { // TODO iterate over self.optimize_modes and test this in both // debug and release safe mode - const annotated_case_name = fmt.allocPrint(self.b.allocator, "run safety {s}", .{case.name}) catch @panic("OOM"); + const annotated_case_name = b.fmt("run safety {s}", .{case.name}); for (self.test_filters) |test_filter| { if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; } else if (self.test_filters.len > 0) return; const exe = b.addExecutable(.{ .name = "test", - .root_source_file = first_file, - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = first_file, + .target = b.graph.host, + .optimize = .Debug, + }), }); - if (case.link_libc) { - exe.linkSystemLibrary("c"); - } + if (case.link_libc) exe.root_module.link_libc = true; const run = b.addRunArtifact(exe); run.setName(annotated_case_name); @@ -168,7 +171,6 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void { const CompareOutput = @This(); const std = @import("std"); const ArrayList = std.ArrayList; -const fmt = std.fmt; const mem = std.mem; const fs = std.fs; const OptimizeMode = std.builtin.OptimizeMode; diff --git a/test/src/Debugger.zig b/test/src/Debugger.zig index d6fae4f2c9..e5fd8b20b3 100644 --- a/test/src/Debugger.zig +++ b/test/src/Debugger.zig @@ -2414,8 +2414,8 @@ fn addTest( } else return; } const files_wf = db.b.addWriteFiles(); - const exe = db.b.addExecutable(.{ - .name = name, + + const mod = db.b.createModule(.{ .target = target.resolved, .root_source_file = files_wf.add(files[0].path, files[0].source), .optimize = target.optimize_mode, @@ -2423,15 +2423,21 @@ fn addTest( .single_threaded = target.single_threaded, .pic = target.pic, .strip = false, - .use_llvm = false, - .use_lld = false, }); for (files[1..]) |file| { const path = files_wf.add(file.path, file.source); - if (file.import) |import| exe.root_module.addImport(import, db.b.createModule(.{ + if (file.import) |import| mod.addImport(import, db.b.createModule(.{ .root_source_file = path, })); } + + const exe = db.b.addExecutable(.{ + .name = name, + .root_module = mod, + .use_llvm = false, + .use_lld = false, + }); + const commands_wf = db.b.addWriteFiles(); const run = std.Build.Step.Run.create(db.b, db.b.fmt("run {s} {s}", .{ name, target.test_name_suffix })); run.addArgs(db_argv1); diff --git a/test/src/RunTranslatedC.zig b/test/src/RunTranslatedC.zig index 59f87c6a82..528df69c4b 100644 --- a/test/src/RunTranslatedC.zig +++ b/test/src/RunTranslatedC.zig @@ -84,7 +84,10 @@ pub fn addCase(self: *RunTranslatedCContext, case: *const TestCase) void { }); translate_c.step.name = b.fmt("{s} translate-c", .{annotated_case_name}); - const exe = translate_c.addExecutable(.{}); + const exe = b.addExecutable(.{ + .name = "translated_c", + .root_module = translate_c.createModule(), + }); exe.step.name = b.fmt("{s} build-exe", .{annotated_case_name}); exe.linkLibC(); const run = b.addRunArtifact(exe); diff --git a/test/src/StackTrace.zig b/test/src/StackTrace.zig index 09af0005de..37e390c78d 100644 --- a/test/src/StackTrace.zig +++ b/test/src/StackTrace.zig @@ -44,9 +44,9 @@ fn addExpect( for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return; const b = self.b; - const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{ + const annotated_case_name = b.fmt("check {s} ({s})", .{ name, @tagName(optimize_mode), - }) catch @panic("OOM"); + }); for (self.test_filters) |test_filter| { if (mem.indexOf(u8, annotated_case_name, test_filter)) |_| break; } else if (self.test_filters.len > 0) return; @@ -55,10 +55,12 @@ fn addExpect( const source_zig = write_files.add("source.zig", source); const exe = b.addExecutable(.{ .name = "test", - .root_source_file = source_zig, - .optimize = optimize_mode, - .target = b.graph.host, - .error_tracing = mode_config.error_tracing, + .root_module = b.createModule(.{ + .root_source_file = source_zig, + .optimize = optimize_mode, + .target = b.graph.host, + .error_tracing = mode_config.error_tracing, + }), }); const run = b.addRunArtifact(exe); @@ -83,5 +85,4 @@ const std = @import("std"); const builtin = @import("builtin"); const Step = std.Build.Step; const OptimizeMode = std.builtin.OptimizeMode; -const fmt = std.fmt; const mem = std.mem; diff --git a/test/standalone/build.zig b/test/standalone/build.zig index fee8c03161..f89ccd2a18 100644 --- a/test/standalone/build.zig +++ b/test/standalone/build.zig @@ -47,9 +47,11 @@ pub fn build(b: *std.Build) void { }) |tool_src_path| { const tool = b.addTest(.{ .name = std.fs.path.stem(tool_src_path), - .root_source_file = b.path(tool_src_path), - .optimize = .Debug, - .target = tools_target, + .root_module = b.createModule(.{ + .root_source_file = b.path(tool_src_path), + .optimize = .Debug, + .target = tools_target, + }), }); const run = b.addRunArtifact(tool); tools_tests_step.dependOn(&run.step); diff --git a/test/standalone/c_compiler/build.zig b/test/standalone/c_compiler/build.zig index 5328d6e01d..af9d8b492a 100644 --- a/test/standalone/c_compiler/build.zig +++ b/test/standalone/c_compiler/build.zig @@ -20,22 +20,25 @@ fn add( ) void { const target = b.graph.host; - const exe_c = b.addExecutable(.{ - .name = c_name, + const c_mod = b.createModule(.{ .optimize = optimize, .target = target, }); - exe_c.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[0][]const u8{} }); - exe_c.linkLibC(); + c_mod.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[0][]const u8{} }); + c_mod.link_libc = true; - const exe_cpp = b.addExecutable(.{ - .name = cpp_name, + const exe_c = b.addExecutable(.{ .name = c_name, .root_module = c_mod }); + + const cpp_mod = b.createModule(.{ .optimize = optimize, .target = target, }); + cpp_mod.addCSourceFile(.{ .file = b.path("test.cpp"), .flags = &[0][]const u8{} }); + cpp_mod.link_libcpp = true; + + const exe_cpp = b.addExecutable(.{ .name = cpp_name, .root_module = cpp_mod }); + b.default_step.dependOn(&exe_cpp.step); - exe_cpp.addCSourceFile(.{ .file = b.path("test.cpp"), .flags = &[0][]const u8{} }); - exe_cpp.linkLibCpp(); switch (target.result.os.tag) { .windows => { diff --git a/test/standalone/child_process/build.zig b/test/standalone/child_process/build.zig index 0180fb8a83..81b40835f3 100644 --- a/test/standalone/child_process/build.zig +++ b/test/standalone/child_process/build.zig @@ -12,16 +12,20 @@ pub fn build(b: *std.Build) void { const child = b.addExecutable(.{ .name = "child", - .root_source_file = b.path("child.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("child.zig"), + .optimize = optimize, + .target = target, + }), }); const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const run = b.addRunArtifact(main); run.addArtifactArg(child); diff --git a/test/standalone/coff_dwarf/build.zig b/test/standalone/coff_dwarf/build.zig index bb9879d089..b95ebed80d 100644 --- a/test/standalone/coff_dwarf/build.zig +++ b/test/standalone/coff_dwarf/build.zig @@ -14,19 +14,24 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const lib = b.addSharedLibrary(.{ .name = "shared_lib", - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = target, + .link_libc = true, + }), }); - lib.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} }); - lib.linkLibC(); - exe.linkLibrary(lib); + lib.root_module.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-gdwarf"} }); + exe.root_module.linkLibrary(lib); const run = b.addRunArtifact(exe); run.expectExitCode(0); diff --git a/test/standalone/compiler_rt_panic/build.zig b/test/standalone/compiler_rt_panic/build.zig index 93331a0282..e25fe0eff7 100644 --- a/test/standalone/compiler_rt_panic/build.zig +++ b/test/standalone/compiler_rt_panic/build.zig @@ -12,11 +12,14 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "main", - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = target, + .link_libc = true, + }), }); - exe.linkLibC(); - exe.addCSourceFile(.{ + exe.root_module.addCSourceFile(.{ .file = b.path("main.c"), .flags = &.{}, }); diff --git a/test/standalone/dep_diamond/build.zig b/test/standalone/dep_diamond/build.zig index 44338b36d4..ba437c310a 100644 --- a/test/standalone/dep_diamond/build.zig +++ b/test/standalone/dep_diamond/build.zig @@ -6,23 +6,23 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const shared = b.createModule(.{ - .root_source_file = b.path("shared.zig"), - }); - - const exe = b.addExecutable(.{ - .name = "test", + const main_mod = b.createModule(.{ .root_source_file = b.path("test.zig"), .target = b.graph.host, .optimize = optimize, }); - exe.root_module.addAnonymousImport("foo", .{ - .root_source_file = b.path("foo.zig"), - .imports = &.{.{ .name = "shared", .module = shared }}, - }); - exe.root_module.addAnonymousImport("bar", .{ - .root_source_file = b.path("bar.zig"), - .imports = &.{.{ .name = "shared", .module = shared }}, + const shared_mod = b.createModule(.{ .root_source_file = b.path("shared.zig") }); + const foo_mod = b.createModule(.{ .root_source_file = b.path("foo.zig") }); + const bar_mod = b.createModule(.{ .root_source_file = b.path("bar.zig") }); + + main_mod.addImport("foo", foo_mod); + main_mod.addImport("bar", bar_mod); + foo_mod.addImport("shared", shared_mod); + bar_mod.addImport("shared", shared_mod); + + const exe = b.addExecutable(.{ + .name = "test", + .root_module = main_mod, }); const run = b.addRunArtifact(exe); diff --git a/test/standalone/dep_duplicate_module/build.zig b/test/standalone/dep_duplicate_module/build.zig index 733d49b91c..5974ba9968 100644 --- a/test/standalone/dep_duplicate_module/build.zig +++ b/test/standalone/dep_duplicate_module/build.zig @@ -4,29 +4,36 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const mod = b.addModule("mod", .{ + const shared_mod = b.createModule(.{ .root_source_file = b.path("mod.zig"), .target = target, .optimize = optimize, }); - - const lib = b.addStaticLibrary(.{ - .name = "lib", + const lib_mod = b.createModule(.{ .root_source_file = b.path("lib.zig"), .target = target, .optimize = optimize, }); - lib.root_module.addImport("mod", mod); - - const exe = b.addExecutable(.{ - .name = "app", + const exe_mod = b.createModule(.{ .root_source_file = b.path("main.zig"), .target = target, .optimize = optimize, }); - exe.root_module.addImport("mod", mod); - exe.root_module.linkLibrary(lib); + lib_mod.addImport("mod", shared_mod); + exe_mod.addImport("mod", shared_mod); + + const lib = b.addStaticLibrary(.{ + .name = "lib", + .root_module = lib_mod, + }); + + exe_mod.linkLibrary(lib); + + const exe = b.addExecutable(.{ + .name = "app", + .root_module = exe_mod, + }); b.installArtifact(exe); } diff --git a/test/standalone/dep_lazypath/build.zig b/test/standalone/dep_lazypath/build.zig index f309487981..01b4be8fd4 100644 --- a/test/standalone/dep_lazypath/build.zig +++ b/test/standalone/dep_lazypath/build.zig @@ -11,10 +11,13 @@ pub fn build(b: *std.Build) void { const generated_main_c = write_files.add("main.c", ""); const exe = b.addExecutable(.{ .name = "test", - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.graph.host, + .optimize = optimize, + }), }); - exe.addCSourceFiles(.{ + exe.root_module.addCSourceFiles(.{ .root = generated_main_c.dirname(), .files = &.{"main.c"}, }); @@ -26,11 +29,13 @@ pub fn build(b: *std.Build) void { const dir = write_files.addCopyDirectory(b.path("inc"), "", .{}); const exe = b.addExecutable(.{ .name = "test", - .root_source_file = b.path("inctest.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("inctest.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); - exe.addIncludePath(dir); + exe.root_module.addIncludePath(dir); b.step("copydir", "").dependOn(&exe.step); test_step.dependOn(&exe.step); } diff --git a/test/standalone/dep_mutually_recursive/build.zig b/test/standalone/dep_mutually_recursive/build.zig index 0dc739b7af..f333c1917a 100644 --- a/test/standalone/dep_mutually_recursive/build.zig +++ b/test/standalone/dep_mutually_recursive/build.zig @@ -6,22 +6,26 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const foo = b.createModule(.{ - .root_source_file = b.path("foo.zig"), - }); - const bar = b.createModule(.{ - .root_source_file = b.path("bar.zig"), - }); - foo.addImport("bar", bar); - bar.addImport("foo", foo); - - const exe = b.addExecutable(.{ - .name = "test", + const main_mod = b.createModule(.{ .root_source_file = b.path("test.zig"), .target = b.graph.host, .optimize = optimize, }); - exe.root_module.addImport("foo", foo); + const foo_mod = b.createModule(.{ + .root_source_file = b.path("foo.zig"), + }); + const bar_mod = b.createModule(.{ + .root_source_file = b.path("bar.zig"), + }); + + main_mod.addImport("foo", foo_mod); + foo_mod.addImport("bar", bar_mod); + bar_mod.addImport("foo", foo_mod); + + const exe = b.addExecutable(.{ + .name = "test", + .root_module = main_mod, + }); 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 bc1b7a55bb..133b7706b0 100644 --- a/test/standalone/dep_recursive/build.zig +++ b/test/standalone/dep_recursive/build.zig @@ -6,18 +6,22 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const foo = b.createModule(.{ - .root_source_file = b.path("foo.zig"), - }); - foo.addImport("foo", foo); - - const exe = b.addExecutable(.{ - .name = "test", + const main_mod = b.createModule(.{ .root_source_file = b.path("test.zig"), .target = b.graph.host, .optimize = optimize, }); - exe.root_module.addImport("foo", foo); + const foo_mod = b.createModule(.{ + .root_source_file = b.path("foo.zig"), + }); + + main_mod.addImport("foo", foo_mod); + foo_mod.addImport("foo", foo_mod); + + const exe = b.addExecutable(.{ + .name = "test", + .root_module = main_mod, + }); 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 85a58da95a..eb8457e494 100644 --- a/test/standalone/dep_shared_builtin/build.zig +++ b/test/standalone/dep_shared_builtin/build.zig @@ -6,16 +6,22 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const exe = b.addExecutable(.{ - .name = "test", + const main_mod = b.createModule(.{ .root_source_file = b.path("test.zig"), .target = b.graph.host, .optimize = optimize, }); - exe.root_module.addAnonymousImport("foo", .{ + const foo_mod = b.createModule(.{ .root_source_file = b.path("foo.zig"), }); + main_mod.addImport("foo", foo_mod); + + const exe = b.addExecutable(.{ + .name = "test", + .root_module = main_mod, + }); + const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); } diff --git a/test/standalone/dep_triangle/build.zig b/test/standalone/dep_triangle/build.zig index c8562fd716..70f64dc334 100644 --- a/test/standalone/dep_triangle/build.zig +++ b/test/standalone/dep_triangle/build.zig @@ -6,21 +6,26 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const shared = b.createModule(.{ - .root_source_file = b.path("shared.zig"), - }); - - const exe = b.addExecutable(.{ - .name = "test", + const main_mod = b.createModule(.{ .root_source_file = b.path("test.zig"), .target = b.graph.host, .optimize = optimize, }); - exe.root_module.addAnonymousImport("foo", .{ + const foo_mod = b.createModule(.{ .root_source_file = b.path("foo.zig"), - .imports = &.{.{ .name = "shared", .module = shared }}, }); - exe.root_module.addImport("shared", shared); + const shared_mod = b.createModule(.{ + .root_source_file = b.path("shared.zig"), + }); + + main_mod.addImport("foo", foo_mod); + main_mod.addImport("shared", shared_mod); + foo_mod.addImport("shared", shared_mod); + + const exe = b.addExecutable(.{ + .name = "test", + .root_module = main_mod, + }); const run = b.addRunArtifact(exe); test_step.dependOn(&run.step); diff --git a/test/standalone/depend_on_main_mod/build.zig b/test/standalone/depend_on_main_mod/build.zig index 42e96e0aa0..4dc08ba1bb 100644 --- a/test/standalone/depend_on_main_mod/build.zig +++ b/test/standalone/depend_on_main_mod/build.zig @@ -7,19 +7,22 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const exe = b.addExecutable(.{ - .name = "depend_on_main_mod", + const main_mod = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }); - - const foo_module = b.addModule("foo", .{ + const foo_mod = b.createModule(.{ .root_source_file = b.path("src/foo.zig"), }); - foo_module.addImport("root2", &exe.root_module); - exe.root_module.addImport("foo", foo_module); + foo_mod.addImport("root2", main_mod); + main_mod.addImport("foo", foo_mod); + + const exe = b.addExecutable(.{ + .name = "depend_on_main_mod", + .root_module = main_mod, + }); const run_cmd = b.addRunArtifact(exe); run_cmd.expectExitCode(0); diff --git a/test/standalone/dirname/build.zig b/test/standalone/dirname/build.zig index 2562c677c3..0da85e2923 100644 --- a/test/standalone/dirname/build.zig +++ b/test/standalone/dirname/build.zig @@ -10,24 +10,30 @@ pub fn build(b: *std.Build) void { const touch = b.addExecutable(.{ .name = "touch", - .root_source_file = touch_src, - .optimize = .Debug, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = touch_src, + .optimize = .Debug, + .target = target, + }), }); const generated = b.addRunArtifact(touch).addOutputFileArg("subdir" ++ std.fs.path.sep_str ++ "generated.txt"); const exists_in = b.addExecutable(.{ .name = "exists_in", - .root_source_file = b.path("exists_in.zig"), - .optimize = .Debug, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("exists_in.zig"), + .optimize = .Debug, + .target = target, + }), }); const has_basename = b.addExecutable(.{ .name = "has_basename", - .root_source_file = b.path("has_basename.zig"), - .optimize = .Debug, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("has_basename.zig"), + .optimize = .Debug, + .target = target, + }), }); // Known path: diff --git a/test/standalone/embed_generated_file/build.zig b/test/standalone/embed_generated_file/build.zig index f7430b7716..75670f6ba0 100644 --- a/test/standalone/embed_generated_file/build.zig +++ b/test/standalone/embed_generated_file/build.zig @@ -6,18 +6,21 @@ pub fn build(b: *std.Build) void { const bootloader = b.addExecutable(.{ .name = "bootloader", - .root_source_file = b.path("bootloader.zig"), - .target = b.resolveTargetQuery(.{ - .cpu_arch = .x86, - .os_tag = .freestanding, + .root_module = b.createModule(.{ + .root_source_file = b.path("bootloader.zig"), + .target = b.resolveTargetQuery(.{ + .cpu_arch = .x86, + .os_tag = .freestanding, + }), + .optimize = .ReleaseSmall, }), - .optimize = .ReleaseSmall, }); - const exe = b.addTest(.{ + const exe = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("main.zig"), + .target = b.graph.host, .optimize = .Debug, - }); + }) }); exe.root_module.addAnonymousImport("bootloader.elf", .{ .root_source_file = bootloader.getEmittedBin(), }); diff --git a/test/standalone/emit_asm_and_bin/build.zig b/test/standalone/emit_asm_and_bin/build.zig index 51b4066e6a..cc38a87ddc 100644 --- a/test/standalone/emit_asm_and_bin/build.zig +++ b/test/standalone/emit_asm_and_bin/build.zig @@ -4,10 +4,11 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const main = b.addTest(.{ + const main = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("main.zig"), + .target = b.graph.host, .optimize = b.standardOptimizeOption(.{}), - }); + }) }); // TODO: actually check these two artifacts for correctness _ = main.getEmittedBin(); _ = main.getEmittedAsm(); diff --git a/test/standalone/emit_asm_no_bin/build.zig b/test/standalone/emit_asm_no_bin/build.zig index f2f2391bc1..cd5b670146 100644 --- a/test/standalone/emit_asm_no_bin/build.zig +++ b/test/standalone/emit_asm_no_bin/build.zig @@ -8,9 +8,11 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.graph.host, + }), }); _ = obj.getEmittedAsm(); b.default_step.dependOn(&obj.step); diff --git a/test/standalone/emit_llvm_no_bin/build.zig b/test/standalone/emit_llvm_no_bin/build.zig index f82dd51930..04946e47b6 100644 --- a/test/standalone/emit_llvm_no_bin/build.zig +++ b/test/standalone/emit_llvm_no_bin/build.zig @@ -8,9 +8,11 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = b.graph.host, + }), }); _ = obj.getEmittedLlvmIr(); _ = obj.getEmittedLlvmBc(); diff --git a/test/standalone/empty_env/build.zig b/test/standalone/empty_env/build.zig index dcbb0ad052..592566d62c 100644 --- a/test/standalone/empty_env/build.zig +++ b/test/standalone/empty_env/build.zig @@ -21,9 +21,11 @@ pub fn build(b: *std.Build) void { const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); const run = b.addRunArtifact(main); diff --git a/test/standalone/extern/build.zig b/test/standalone/extern/build.zig index ff8701bf40..a3907e20db 100644 --- a/test/standalone/extern/build.zig +++ b/test/standalone/extern/build.zig @@ -8,22 +8,28 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "exports", - .root_source_file = b.path("exports.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("exports.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); const shared = b.addSharedLibrary(.{ .name = "shared", + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.graph.host, + .optimize = optimize, + .link_libc = true, + }), + }); + if (b.graph.host.result.abi == .msvc) shared.root_module.addCMacro("API", "__declspec(dllexport)"); + shared.root_module.addCSourceFile(.{ .file = b.path("shared.c"), .flags = &.{} }); + const test_exe = b.addTest(.{ .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), .target = b.graph.host, .optimize = optimize, - .link_libc = true, - }); - if (b.graph.host.result.abi == .msvc) shared.defineCMacro("API", "__declspec(dllexport)"); - shared.addCSourceFile(.{ .file = b.path("shared.c"), .flags = &.{} }); - const test_exe = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, - }); + }) }); test_exe.addObject(obj); test_exe.linkLibrary(shared); diff --git a/test/standalone/global_linkage/build.zig b/test/standalone/global_linkage/build.zig index 50e270d1c3..795bf008b3 100644 --- a/test/standalone/global_linkage/build.zig +++ b/test/standalone/global_linkage/build.zig @@ -9,24 +9,30 @@ pub fn build(b: *std.Build) void { const obj1 = b.addStaticLibrary(.{ .name = "obj1", - .root_source_file = b.path("obj1.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("obj1.zig"), + .optimize = optimize, + .target = target, + }), }); const obj2 = b.addStaticLibrary(.{ .name = "obj2", - .root_source_file = b.path("obj2.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("obj2.zig"), + .optimize = optimize, + .target = target, + }), }); - const main = b.addTest(.{ + const main_mod = b.createModule(.{ .root_source_file = b.path("main.zig"), + .target = b.graph.host, .optimize = optimize, }); - main.linkLibrary(obj1); - main.linkLibrary(obj2); + main_mod.linkLibrary(obj1); + main_mod.linkLibrary(obj2); + const main = b.addTest(.{ .root_module = main_mod }); test_step.dependOn(&b.addRunArtifact(main).step); } diff --git a/test/standalone/install_headers/build.zig b/test/standalone/install_headers/build.zig index 889ee717d6..9f725c0c81 100644 --- a/test/standalone/install_headers/build.zig +++ b/test/standalone/install_headers/build.zig @@ -8,18 +8,24 @@ pub fn build(b: *std.Build) void { const libfoo = b.addStaticLibrary(.{ .name = "foo", - .target = b.resolveTargetQuery(.{}), - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(.{}), + .optimize = .Debug, + }), }); - libfoo.addCSourceFile(.{ .file = empty_c }); + libfoo.root_module.addCSourceFile(.{ .file = empty_c }); const exe = b.addExecutable(.{ .name = "exe", - .target = b.resolveTargetQuery(.{}), - .optimize = .Debug, - .link_libc = true, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(.{}), + .optimize = .Debug, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.addWriteFiles().add("main.c", + exe.root_module.addCSourceFile(.{ .file = b.addWriteFiles().add("main.c", \\#include \\#include \\#include @@ -40,9 +46,10 @@ pub fn build(b: *std.Build) void { if (libfoo.installed_headers_include_tree != null) std.debug.panic("include tree step was created before linking", .{}); - // Link before we have registered all headers for installation, + // Link (and get the include tree) before we have registered all headers for installation, // to verify that the lazily created write files step is properly taken into account. - exe.linkLibrary(libfoo); + exe.root_module.linkLibrary(libfoo); + _ = libfoo.getEmittedIncludeTree(); if (libfoo.installed_headers_include_tree == null) std.debug.panic("include tree step was not created after linking", .{}); @@ -56,10 +63,13 @@ pub fn build(b: *std.Build) void { const libbar = b.addStaticLibrary(.{ .name = "bar", - .target = b.resolveTargetQuery(.{}), - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(.{}), + .optimize = .Debug, + }), }); - libbar.addCSourceFile(.{ .file = empty_c }); + libbar.root_module.addCSourceFile(.{ .file = empty_c }); libbar.installHeader(b.addWriteFiles().add("bar.h", \\#define BAR_X "X" \\ @@ -78,9 +88,11 @@ pub fn build(b: *std.Build) void { }); const check_exists = b.addExecutable(.{ .name = "check_exists", - .root_source_file = b.path("check_exists.zig"), - .target = b.resolveTargetQuery(.{}), - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("check_exists.zig"), + .target = b.resolveTargetQuery(.{}), + .optimize = .Debug, + }), }); const run_check_exists = b.addRunArtifact(check_exists); run_check_exists.addArgs(&.{ diff --git a/test/standalone/install_raw_hex/build.zig b/test/standalone/install_raw_hex/build.zig index 515528534e..c12949a9ce 100644 --- a/test/standalone/install_raw_hex/build.zig +++ b/test/standalone/install_raw_hex/build.zig @@ -16,9 +16,11 @@ pub fn build(b: *std.Build) void { const elf = b.addExecutable(.{ .name = "zig-nrf52-blink.elf", - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = optimize, + }), }); const hex_step = elf.addObjCopy(.{ diff --git a/test/standalone/ios/build.zig b/test/standalone/ios/build.zig index c4ae240bd6..6148920b54 100644 --- a/test/standalone/ios/build.zig +++ b/test/standalone/ios/build.zig @@ -18,16 +18,19 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "main", - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = target, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.path("main.m"), .flags = &.{} }); - exe.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/include" }) }); - exe.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/Frameworks" }) }); - exe.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/lib" }) }); - exe.linkFramework("Foundation"); - exe.linkFramework("UIKit"); - exe.linkLibC(); + exe.root_module.addCSourceFile(.{ .file = b.path("main.m"), .flags = &.{} }); + exe.root_module.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/include" }) }); + exe.root_module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/Frameworks" }) }); + exe.root_module.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/lib" }) }); + exe.root_module.linkFramework("Foundation", .{}); + exe.root_module.linkFramework("UIKit", .{}); const check = exe.checkObject(); check.checkInHeaders(); diff --git a/test/standalone/issue_11595/build.zig b/test/standalone/issue_11595/build.zig index d0592b546b..88b7af06a5 100644 --- a/test/standalone/issue_11595/build.zig +++ b/test/standalone/issue_11595/build.zig @@ -15,9 +15,11 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "zigtest", - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = optimize, + }), }); b.installArtifact(exe); @@ -25,21 +27,21 @@ pub fn build(b: *std.Build) void { "test.c", }; - exe.addCSourceFiles(.{ .files = &c_sources }); - exe.linkLibC(); + exe.root_module.addCSourceFiles(.{ .files = &c_sources }); + exe.root_module.link_libc = true; var i: i32 = 0; while (i < 1000) : (i += 1) { - exe.defineCMacro("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + exe.root_module.addCMacro("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); } - exe.defineCMacro("FOO", "42"); - exe.defineCMacro("BAR", "\"BAR\""); - exe.defineCMacro("BAZ", + exe.root_module.addCMacro("FOO", "42"); + exe.root_module.addCMacro("BAR", "\"BAR\""); + exe.root_module.addCMacro("BAZ", \\"\"BAZ\"" ); - exe.defineCMacro("QUX", "\"Q\" \"UX\""); - exe.defineCMacro("QUUX", "\"QU\\\"UX\""); + exe.root_module.addCMacro("QUX", "\"Q\" \"UX\""); + exe.root_module.addCMacro("QUUX", "\"QU\\\"UX\""); b.default_step.dependOn(&exe.step); diff --git a/test/standalone/issue_12706/build.zig b/test/standalone/issue_12706/build.zig index 9cb858d019..cace3c7d2d 100644 --- a/test/standalone/issue_12706/build.zig +++ b/test/standalone/issue_12706/build.zig @@ -10,16 +10,18 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const c_sources = [_][]const u8{ "test.c", }; - exe.addCSourceFiles(.{ .files = &c_sources }); - exe.linkLibC(); + exe.root_module.addCSourceFiles(.{ .files = &c_sources }); + exe.root_module.link_libc = true; const run_cmd = b.addRunArtifact(exe); run_cmd.expectExitCode(0); diff --git a/test/standalone/issue_13970/build.zig b/test/standalone/issue_13970/build.zig index e7d3a82431..bad94161af 100644 --- a/test/standalone/issue_13970/build.zig +++ b/test/standalone/issue_13970/build.zig @@ -5,15 +5,24 @@ pub fn build(b: *std.Build) void { b.default_step = test_step; const test1 = b.addTest(.{ - .root_source_file = b.path("test_root/empty.zig"), + .root_module = b.createModule(.{ + .root_source_file = b.path("test_root/empty.zig"), + .target = b.graph.host, + }), .test_runner = "src/main.zig", }); const test2 = b.addTest(.{ - .root_source_file = b.path("src/empty.zig"), + .root_module = b.createModule(.{ + .root_source_file = b.path("src/empty.zig"), + .target = b.graph.host, + }), .test_runner = "src/main.zig", }); const test3 = b.addTest(.{ - .root_source_file = b.path("empty.zig"), + .root_module = b.createModule(.{ + .root_source_file = b.path("empty.zig"), + .target = b.graph.host, + }), .test_runner = "src/main.zig", }); diff --git a/test/standalone/issue_339/build.zig b/test/standalone/issue_339/build.zig index 321a635254..364dc0e81b 100644 --- a/test/standalone/issue_339/build.zig +++ b/test/standalone/issue_339/build.zig @@ -9,9 +9,11 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "test", - .root_source_file = b.path("test.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("test.zig"), + .target = target, + .optimize = optimize, + }), }); // TODO: actually check the output diff --git a/test/standalone/issue_5825/build.zig b/test/standalone/issue_5825/build.zig index d4462bb5a1..3b4bb33def 100644 --- a/test/standalone/issue_5825/build.zig +++ b/test/standalone/issue_5825/build.zig @@ -16,20 +16,25 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const obj = b.addObject(.{ .name = "issue_5825", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const exe = b.addExecutable(.{ .name = "issue_5825", - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = target, + }), }); exe.subsystem = .Console; - exe.linkSystemLibrary("kernel32"); - exe.linkSystemLibrary("ntdll"); - exe.addObject(obj); + exe.root_module.linkSystemLibrary("kernel32", .{}); + exe.root_module.linkSystemLibrary("ntdll", .{}); + exe.root_module.addObject(obj); // TODO: actually check the output _ = exe.getEmittedBin(); diff --git a/test/standalone/issue_794/build.zig b/test/standalone/issue_794/build.zig index d42ff1f304..4b0c089f97 100644 --- a/test/standalone/issue_794/build.zig +++ b/test/standalone/issue_794/build.zig @@ -4,9 +4,10 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const test_artifact = b.addTest(.{ + const test_artifact = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("main.zig"), - }); + .target = b.graph.host, + }) }); test_artifact.addIncludePath(b.path("a_directory")); // TODO: actually check the output diff --git a/test/standalone/issue_8550/build.zig b/test/standalone/issue_8550/build.zig index a0dea518d6..ee82332973 100644 --- a/test/standalone/issue_8550/build.zig +++ b/test/standalone/issue_8550/build.zig @@ -15,11 +15,13 @@ pub fn build(b: *std.Build) !void { const kernel = b.addExecutable(.{ .name = "kernel", - .root_source_file = b.path("./main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("./main.zig"), + .optimize = optimize, + .target = target, + }), }); - kernel.addObjectFile(b.path("./boot.S")); + kernel.root_module.addObjectFile(b.path("./boot.S")); kernel.setLinkerScript(b.path("./linker.ld")); b.installArtifact(kernel); diff --git a/test/standalone/libcxx/build.zig b/test/standalone/libcxx/build.zig index 3989bda9bc..aaa62abdb4 100644 --- a/test/standalone/libcxx/build.zig +++ b/test/standalone/libcxx/build.zig @@ -11,12 +11,14 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "mt", - .root_source_file = b.path("mt.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("mt.zig"), + .target = target, + .optimize = optimize, + .link_libcpp = true, + }), }); - exe.linkLibCpp(); - exe.addCSourceFile(.{ .file = b.path("mt_doit.cpp") }); + exe.root_module.addCSourceFile(.{ .file = b.path("mt_doit.cpp") }); link_step.dependOn(&exe.step); b.installArtifact(exe); run_step.dependOn(&b.addRunArtifact(exe).step); @@ -24,13 +26,15 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "st", - .root_source_file = b.path("st.zig"), - .target = target, - .optimize = optimize, - .single_threaded = true, + .root_module = b.createModule(.{ + .root_source_file = b.path("st.zig"), + .target = target, + .optimize = optimize, + .link_libcpp = true, + .single_threaded = true, + }), }); - exe.linkLibCpp(); - exe.addCSourceFile(.{ .file = b.path("st_doit.cpp") }); + exe.root_module.addCSourceFile(.{ .file = b.path("st_doit.cpp") }); link_step.dependOn(&exe.step); b.installArtifact(exe); run_step.dependOn(&b.addRunArtifact(exe).step); diff --git a/test/standalone/load_dynamic_library/build.zig b/test/standalone/load_dynamic_library/build.zig index f484d2a6e6..ec05c45c21 100644 --- a/test/standalone/load_dynamic_library/build.zig +++ b/test/standalone/load_dynamic_library/build.zig @@ -12,17 +12,21 @@ pub fn build(b: *std.Build) void { const lib = b.addSharedLibrary(.{ .name = "add", - .root_source_file = b.path("add.zig"), .version = .{ .major = 1, .minor = 0, .patch = 0 }, - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("add.zig"), + .optimize = optimize, + .target = target, + }), }); const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const run = b.addRunArtifact(main); diff --git a/test/standalone/mix_c_files/build.zig b/test/standalone/mix_c_files/build.zig index 0b626ba0fa..32b1d57b5c 100644 --- a/test/standalone/mix_c_files/build.zig +++ b/test/standalone/mix_c_files/build.zig @@ -18,12 +18,14 @@ pub fn build(b: *std.Build) void { fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void { const exe = b.addExecutable(.{ .name = "test", - .root_source_file = b.path("main.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[_][]const u8{"-std=c11"} }); - exe.linkLibC(); + exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[_][]const u8{"-std=c11"} }); const run_cmd = b.addRunArtifact(exe); run_cmd.skip_foreign_checks = true; diff --git a/test/standalone/mix_o_files/build.zig b/test/standalone/mix_o_files/build.zig index 7be4ff5090..12b90f3624 100644 --- a/test/standalone/mix_o_files/build.zig +++ b/test/standalone/mix_o_files/build.zig @@ -9,22 +9,27 @@ pub fn build(b: *std.Build) void { const obj = b.addObject(.{ .name = "base64", - .root_source_file = b.path("base64.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("base64.zig"), + .optimize = optimize, + .target = target, + }), }); const exe = b.addExecutable(.{ .name = "test", - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = target, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ + exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[_][]const u8{"-std=c99"}, }); - exe.addObject(obj); - exe.linkSystemLibrary("c"); + exe.root_module.addObject(obj); b.default_step.dependOn(&exe.step); diff --git a/test/standalone/options/build.zig b/test/standalone/options/build.zig index 1c17e30d6a..07efea2a7b 100644 --- a/test/standalone/options/build.zig +++ b/test/standalone/options/build.zig @@ -1,11 +1,11 @@ const std = @import("std"); pub fn build(b: *std.Build) void { - const main = b.addTest(.{ + const main = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = b.graph.host, .optimize = .Debug, - }); + }) }); const options = b.addOptions(); main.addOptions("build_options", options); diff --git a/test/standalone/pie/build.zig b/test/standalone/pie/build.zig index 25ed330abc..79d078a9eb 100644 --- a/test/standalone/pie/build.zig +++ b/test/standalone/pie/build.zig @@ -11,9 +11,11 @@ pub fn build(b: *std.Build) void { }); const main = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); main.pie = true; diff --git a/test/standalone/pkg_import/build.zig b/test/standalone/pkg_import/build.zig index b0d0c035dd..3d94930ef3 100644 --- a/test/standalone/pkg_import/build.zig +++ b/test/standalone/pkg_import/build.zig @@ -8,9 +8,11 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "test", - .root_source_file = b.path("test.zig"), - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = b.path("test.zig"), + .optimize = optimize, + .target = b.graph.host, + }), }); exe.root_module.addAnonymousImport("my_pkg", .{ .root_source_file = b.path("pkg.zig") }); diff --git a/test/standalone/run_output_caching/build.zig b/test/standalone/run_output_caching/build.zig index 3842f097d1..98f5a63dd5 100644 --- a/test/standalone/run_output_caching/build.zig +++ b/test/standalone/run_output_caching/build.zig @@ -9,9 +9,11 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "create-file", - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = optimize, + }), }); { diff --git a/test/standalone/run_output_paths/build.zig b/test/standalone/run_output_paths/build.zig index f4c7254d8f..78b75e147d 100644 --- a/test/standalone/run_output_paths/build.zig +++ b/test/standalone/run_output_paths/build.zig @@ -9,9 +9,11 @@ pub fn build(b: *std.Build) void { const create_file_exe = b.addExecutable(.{ .name = "create_file", - .root_source_file = b.path("create_file.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("create_file.zig"), + .target = target, + .optimize = optimize, + }), }); const create_first = b.addRunArtifact(create_file_exe); diff --git a/test/standalone/self_exe_symlink/build.zig b/test/standalone/self_exe_symlink/build.zig index 2b7b3d423c..651740c04b 100644 --- a/test/standalone/self_exe_symlink/build.zig +++ b/test/standalone/self_exe_symlink/build.zig @@ -15,16 +15,20 @@ pub fn build(b: *std.Build) void { const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const create_symlink_exe = b.addExecutable(.{ .name = "create-symlink", - .root_source_file = b.path("create-symlink.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("create-symlink.zig"), + .optimize = optimize, + .target = target, + }), }); var run_create_symlink = b.addRunArtifact(create_symlink_exe); diff --git a/test/standalone/shared_library/build.zig b/test/standalone/shared_library/build.zig index 28c1bdb13e..ab90c129b9 100644 --- a/test/standalone/shared_library/build.zig +++ b/test/standalone/shared_library/build.zig @@ -8,23 +8,28 @@ pub fn build(b: *std.Build) void { const target = b.graph.host; const lib = b.addSharedLibrary(.{ .name = "mathtest", - .root_source_file = b.path("mathtest.zig"), .version = .{ .major = 1, .minor = 0, .patch = 0 }, - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("mathtest.zig"), + .target = target, + .optimize = optimize, + }), }); const exe = b.addExecutable(.{ .name = "test", - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = optimize, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ + exe.root_module.addCSourceFile(.{ .file = b.path("test.c"), .flags = &[_][]const u8{"-std=c99"}, }); - exe.linkLibrary(lib); - exe.linkSystemLibrary("c"); + exe.root_module.linkLibrary(lib); const run_cmd = b.addRunArtifact(exe); test_step.dependOn(&run_cmd.step); diff --git a/test/standalone/simple/build.zig b/test/standalone/simple/build.zig index c623780fa5..ba4464cefc 100644 --- a/test/standalone/simple/build.zig +++ b/test/standalone/simple/build.zig @@ -42,11 +42,13 @@ pub fn build(b: *std.Build) void { if (case.is_exe) { const exe = b.addExecutable(.{ .name = std.fs.path.stem(case.src_path), - .root_source_file = b.path(case.src_path), - .optimize = optimize, - .target = resolved_target, + .root_module = b.createModule(.{ + .root_source_file = b.path(case.src_path), + .optimize = optimize, + .target = resolved_target, + }), }); - if (case.link_libc) exe.linkLibC(); + if (case.link_libc) exe.root_module.link_libc = true; _ = exe.getEmittedBin(); @@ -56,11 +58,13 @@ pub fn build(b: *std.Build) void { if (case.is_test) { const exe = b.addTest(.{ .name = std.fs.path.stem(case.src_path), - .root_source_file = b.path(case.src_path), - .optimize = optimize, - .target = resolved_target, + .root_module = b.createModule(.{ + .root_source_file = b.path(case.src_path), + .optimize = optimize, + .target = resolved_target, + }), }); - if (case.link_libc) exe.linkLibC(); + if (case.link_libc) exe.root_module.link_libc = true; const run = b.addRunArtifact(exe); step.dependOn(&run.step); diff --git a/test/standalone/stack_iterator/build.zig b/test/standalone/stack_iterator/build.zig index 38f66edd9f..9d660b5c57 100644 --- a/test/standalone/stack_iterator/build.zig +++ b/test/standalone/stack_iterator/build.zig @@ -20,11 +20,13 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "unwind_fp", - .root_source_file = b.path("unwind.zig"), - .target = target, - .optimize = optimize, - .unwind_tables = if (target.result.isDarwin()) .@"async" else null, - .omit_frame_pointer = false, + .root_module = b.createModule(.{ + .root_source_file = b.path("unwind.zig"), + .target = target, + .optimize = optimize, + .unwind_tables = if (target.result.isDarwin()) .@"async" else null, + .omit_frame_pointer = false, + }), }); const run_cmd = b.addRunArtifact(exe); @@ -43,11 +45,13 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "unwind_nofp", - .root_source_file = b.path("unwind.zig"), - .target = target, - .optimize = optimize, - .unwind_tables = .@"async", - .omit_frame_pointer = true, + .root_module = b.createModule(.{ + .root_source_file = b.path("unwind.zig"), + .target = target, + .optimize = optimize, + .unwind_tables = .@"async", + .omit_frame_pointer = true, + }), }); const run_cmd = b.addRunArtifact(exe); @@ -66,27 +70,32 @@ pub fn build(b: *std.Build) void { { const c_shared_lib = b.addSharedLibrary(.{ .name = "c_shared_lib", - .target = target, - .optimize = optimize, - .strip = false, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = optimize, + .link_libc = true, + .strip = false, + }), }); if (target.result.os.tag == .windows) - c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)"); + c_shared_lib.root_module.addCMacro("LIB_API", "__declspec(dllexport)"); - c_shared_lib.addCSourceFile(.{ + c_shared_lib.root_module.addCSourceFile(.{ .file = b.path("shared_lib.c"), .flags = &.{"-fomit-frame-pointer"}, }); - c_shared_lib.linkLibC(); const exe = b.addExecutable(.{ .name = "shared_lib_unwind", - .root_source_file = b.path("shared_lib_unwind.zig"), - .target = target, - .optimize = optimize, - .unwind_tables = if (target.result.isDarwin()) .@"async" else null, - .omit_frame_pointer = true, + .root_module = b.createModule(.{ + .root_source_file = b.path("shared_lib_unwind.zig"), + .target = target, + .optimize = optimize, + .unwind_tables = if (target.result.isDarwin()) .@"async" else null, + .omit_frame_pointer = true, + }), }); exe.linkLibrary(c_shared_lib); @@ -117,14 +126,16 @@ pub fn build(b: *std.Build) void { inline for (no_os_targets) |os_tag| { const exe = b.addExecutable(.{ .name = "unwind_freestanding", - .root_source_file = b.path("unwind_freestanding.zig"), - .target = b.resolveTargetQuery(.{ - .cpu_arch = .x86_64, - .os_tag = os_tag, + .root_module = b.createModule(.{ + .root_source_file = b.path("unwind_freestanding.zig"), + .target = b.resolveTargetQuery(.{ + .cpu_arch = .x86_64, + .os_tag = os_tag, + }), + .optimize = optimize, + .unwind_tables = null, + .omit_frame_pointer = false, }), - .optimize = optimize, - .unwind_tables = null, - .omit_frame_pointer = false, }); // This "freestanding" binary is runnable because it invokes the diff --git a/test/standalone/static_c_lib/build.zig b/test/standalone/static_c_lib/build.zig index c952e9b250..98b417aaf7 100644 --- a/test/standalone/static_c_lib/build.zig +++ b/test/standalone/static_c_lib/build.zig @@ -8,18 +8,22 @@ pub fn build(b: *std.Build) void { const foo = b.addStaticLibrary(.{ .name = "foo", - .optimize = optimize, - .target = b.graph.host, + .root_module = b.createModule(.{ + .root_source_file = null, + .optimize = optimize, + .target = b.graph.host, + }), }); - foo.addCSourceFile(.{ .file = b.path("foo.c"), .flags = &[_][]const u8{} }); - foo.addIncludePath(b.path(".")); + foo.root_module.addCSourceFile(.{ .file = b.path("foo.c"), .flags = &[_][]const u8{} }); + foo.root_module.addIncludePath(b.path(".")); - const test_exe = b.addTest(.{ + const test_exe = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("foo.zig"), + .target = b.graph.host, .optimize = optimize, - }); - test_exe.linkLibrary(foo); - test_exe.addIncludePath(b.path(".")); + }) }); + test_exe.root_module.linkLibrary(foo); + test_exe.root_module.addIncludePath(b.path(".")); test_step.dependOn(&b.addRunArtifact(test_exe).step); } diff --git a/test/standalone/strip_empty_loop/build.zig b/test/standalone/strip_empty_loop/build.zig index d34120ed06..9f268d4cb8 100644 --- a/test/standalone/strip_empty_loop/build.zig +++ b/test/standalone/strip_empty_loop/build.zig @@ -9,10 +9,12 @@ pub fn build(b: *std.Build) void { const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, - .strip = true, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + .strip = true, + }), }); // TODO: actually check the output diff --git a/test/standalone/strip_struct_init/build.zig b/test/standalone/strip_struct_init/build.zig index ef7960d130..175724df63 100644 --- a/test/standalone/strip_struct_init/build.zig +++ b/test/standalone/strip_struct_init/build.zig @@ -7,9 +7,12 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; const main = b.addTest(.{ - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .strip = true, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = b.graph.host, + .optimize = optimize, + .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 cad3b05e08..6b24ef7124 100644 --- a/test/standalone/test_runner_module_imports/build.zig +++ b/test/standalone/test_runner_module_imports/build.zig @@ -1,19 +1,21 @@ const std = @import("std"); pub fn build(b: *std.Build) void { - const t = b.addTest(.{ + const test_mod = b.createModule(.{ .root_source_file = b.path("src/main.zig"), + .target = b.graph.host, + }); + const module1 = b.createModule(.{ .root_source_file = b.path("module1/main.zig") }); + const module2 = b.createModule(.{ .root_source_file = b.path("module2/main.zig") }); + + module2.addImport("module1", module1); + test_mod.addImport("module2", module2); + + const t = b.addTest(.{ + .root_module = test_mod, .test_runner = b.path("test_runner/main.zig"), }); - const module1 = b.createModule(.{ .root_source_file = b.path("module1/main.zig") }); - const module2 = b.createModule(.{ - .root_source_file = b.path("module2/main.zig"), - .imports = &.{.{ .name = "module1", .module = module1 }}, - }); - - t.root_module.addImport("module2", module2); - const test_step = b.step("test", "Run unit tests"); test_step.dependOn(&b.addRunArtifact(t).step); b.default_step = test_step; diff --git a/test/standalone/test_runner_path/build.zig b/test/standalone/test_runner_path/build.zig index 48ca3c19db..a7b8eaf321 100644 --- a/test/standalone/test_runner_path/build.zig +++ b/test/standalone/test_runner_path/build.zig @@ -6,9 +6,10 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test the program"); b.default_step = test_step; - const test_exe = b.addTest(.{ + const test_exe = b.addTest(.{ .root_module = b.createModule(.{ + .target = b.graph.host, .root_source_file = b.path("test.zig"), - }); + }) }); test_exe.test_runner = b.path("test_runner.zig"); const test_run = b.addRunArtifact(test_exe); diff --git a/test/standalone/use_alias/build.zig b/test/standalone/use_alias/build.zig index 7ee501713c..399a23d924 100644 --- a/test/standalone/use_alias/build.zig +++ b/test/standalone/use_alias/build.zig @@ -6,11 +6,12 @@ pub fn build(b: *std.Build) void { const optimize: std.builtin.OptimizeMode = .Debug; - const main = b.addTest(.{ + const main = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("main.zig"), + .target = b.graph.host, .optimize = optimize, - }); - main.addIncludePath(b.path(".")); + }) }); + main.root_module.addIncludePath(b.path(".")); test_step.dependOn(&b.addRunArtifact(main).step); } diff --git a/test/standalone/windows_argv/build.zig b/test/standalone/windows_argv/build.zig index 4e41a8716e..ea4b26cc22 100644 --- a/test/standalone/windows_argv/build.zig +++ b/test/standalone/windows_argv/build.zig @@ -11,32 +11,39 @@ pub fn build(b: *std.Build) !void { const lib_gnu = b.addStaticLibrary(.{ .name = "toargv-gnu", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ - .abi = .gnu, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ + .abi = .gnu, + }), + .optimize = optimize, }), - .optimize = optimize, }); const verify_gnu = b.addExecutable(.{ .name = "verify-gnu", - .target = b.resolveTargetQuery(.{ - .abi = .gnu, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(.{ + .abi = .gnu, + }), + .optimize = optimize, }), - .optimize = optimize, }); - verify_gnu.addCSourceFile(.{ + verify_gnu.root_module.addCSourceFile(.{ .file = b.path("verify.c"), .flags = &.{ "-DUNICODE", "-D_UNICODE" }, }); verify_gnu.mingw_unicode_entry_point = true; - verify_gnu.linkLibrary(lib_gnu); - verify_gnu.linkLibC(); + verify_gnu.root_module.linkLibrary(lib_gnu); + verify_gnu.root_module.link_libc = true; const fuzz = b.addExecutable(.{ .name = "fuzz", - .root_source_file = b.path("fuzz.zig"), - .target = b.graph.host, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("fuzz.zig"), + .target = b.graph.host, + .optimize = optimize, + }), }); const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100; @@ -69,25 +76,30 @@ pub fn build(b: *std.Build) !void { if (has_msvc) { const lib_msvc = b.addStaticLibrary(.{ .name = "toargv-msvc", - .root_source_file = b.path("lib.zig"), - .target = b.resolveTargetQuery(.{ - .abi = .msvc, + .root_module = b.createModule(.{ + .root_source_file = b.path("lib.zig"), + .target = b.resolveTargetQuery(.{ + .abi = .msvc, + }), + .optimize = optimize, }), - .optimize = optimize, }); const verify_msvc = b.addExecutable(.{ .name = "verify-msvc", - .target = b.resolveTargetQuery(.{ - .abi = .msvc, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = b.resolveTargetQuery(.{ + .abi = .msvc, + }), + .optimize = optimize, }), - .optimize = optimize, }); - verify_msvc.addCSourceFile(.{ + verify_msvc.root_module.addCSourceFile(.{ .file = b.path("verify.c"), .flags = &.{ "-DUNICODE", "-D_UNICODE" }, }); - verify_msvc.linkLibrary(lib_msvc); - verify_msvc.linkLibC(); + verify_msvc.root_module.linkLibrary(lib_msvc); + verify_msvc.root_module.link_libc = true; const run_msvc = b.addRunArtifact(fuzz); run_msvc.setName("fuzz-msvc"); diff --git a/test/standalone/windows_bat_args/build.zig b/test/standalone/windows_bat_args/build.zig index 7c35cf2b76..b91b4fb3bb 100644 --- a/test/standalone/windows_bat_args/build.zig +++ b/test/standalone/windows_bat_args/build.zig @@ -12,16 +12,20 @@ pub fn build(b: *std.Build) !void { const echo_args = b.addExecutable(.{ .name = "echo-args", - .root_source_file = b.path("echo-args.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("echo-args.zig"), + .optimize = optimize, + .target = target, + }), }); const test_exe = b.addExecutable(.{ .name = "test", - .root_source_file = b.path("test.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("test.zig"), + .optimize = optimize, + .target = target, + }), }); const run = b.addRunArtifact(test_exe); @@ -33,9 +37,11 @@ pub fn build(b: *std.Build) !void { const fuzz = b.addExecutable(.{ .name = "fuzz", - .root_source_file = b.path("fuzz.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("fuzz.zig"), + .optimize = optimize, + .target = target, + }), }); const fuzz_max_iterations = b.option(u64, "iterations", "The max fuzz iterations (default: 100)") orelse 100; diff --git a/test/standalone/windows_entry_points/build.zig b/test/standalone/windows_entry_points/build.zig index c3d9c49940..1889b0c843 100644 --- a/test/standalone/windows_entry_points/build.zig +++ b/test/standalone/windows_entry_points/build.zig @@ -13,11 +13,14 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "main", - .target = target, - .optimize = .Debug, - .link_libc = true, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = .Debug, + .link_libc = true, + }), }); - exe.addCSourceFile(.{ .file = b.path("main.c") }); + exe.root_module.addCSourceFile(.{ .file = b.path("main.c") }); _ = exe.getEmittedBin(); test_step.dependOn(&exe.step); @@ -26,12 +29,15 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "wmain", - .target = target, - .optimize = .Debug, - .link_libc = true, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = .Debug, + .link_libc = true, + }), }); exe.mingw_unicode_entry_point = true; - exe.addCSourceFile(.{ .file = b.path("wmain.c") }); + exe.root_module.addCSourceFile(.{ .file = b.path("wmain.c") }); _ = exe.getEmittedBin(); test_step.dependOn(&exe.step); @@ -40,12 +46,15 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "winmain", - .target = target, - .optimize = .Debug, - .link_libc = true, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = .Debug, + .link_libc = true, + }), }); // Note: `exe.subsystem = .Windows;` is not necessary - exe.addCSourceFile(.{ .file = b.path("winmain.c") }); + exe.root_module.addCSourceFile(.{ .file = b.path("winmain.c") }); _ = exe.getEmittedBin(); test_step.dependOn(&exe.step); @@ -54,13 +63,16 @@ pub fn build(b: *std.Build) void { { const exe = b.addExecutable(.{ .name = "wwinmain", - .target = target, - .optimize = .Debug, - .link_libc = true, + .root_module = b.createModule(.{ + .root_source_file = null, + .target = target, + .optimize = .Debug, + .link_libc = true, + }), }); exe.mingw_unicode_entry_point = true; // Note: `exe.subsystem = .Windows;` is not necessary - exe.addCSourceFile(.{ .file = b.path("wwinmain.c") }); + exe.root_module.addCSourceFile(.{ .file = b.path("wwinmain.c") }); _ = exe.getEmittedBin(); test_step.dependOn(&exe.step); diff --git a/test/standalone/windows_resources/build.zig b/test/standalone/windows_resources/build.zig index 27f4fa919e..d3afadb60d 100644 --- a/test/standalone/windows_resources/build.zig +++ b/test/standalone/windows_resources/build.zig @@ -28,11 +28,13 @@ fn add( ) void { const exe = b.addExecutable(.{ .name = "zig_resource_test", - .root_source_file = b.path("main.zig"), - .target = target, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .target = target, + .optimize = .Debug, + }), }); - exe.addWin32ResourceFile(.{ + exe.root_module.addWin32ResourceFile(.{ .file = b.path("res/zig.rc"), .flags = &.{"/c65001"}, // UTF-8 code page .include_paths = &.{ diff --git a/test/standalone/windows_spawn/build.zig b/test/standalone/windows_spawn/build.zig index 7f59ff1da4..2b967b16d5 100644 --- a/test/standalone/windows_spawn/build.zig +++ b/test/standalone/windows_spawn/build.zig @@ -12,16 +12,20 @@ pub fn build(b: *std.Build) void { const hello = b.addExecutable(.{ .name = "hello", - .root_source_file = b.path("hello.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("hello.zig"), + .optimize = optimize, + .target = target, + }), }); const main = b.addExecutable(.{ .name = "main", - .root_source_file = b.path("main.zig"), - .optimize = optimize, - .target = target, + .root_module = b.createModule(.{ + .root_source_file = b.path("main.zig"), + .optimize = optimize, + .target = target, + }), }); const run = b.addRunArtifact(main); diff --git a/test/standalone/zerolength_check/build.zig b/test/standalone/zerolength_check/build.zig index 8118c6e172..7edc55932c 100644 --- a/test/standalone/zerolength_check/build.zig +++ b/test/standalone/zerolength_check/build.zig @@ -11,7 +11,7 @@ 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(.{ + const unit_tests = b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = b.resolveTargetQuery(.{ .os_tag = .wasi, @@ -19,7 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize .cpu_features_add = std.Target.wasm.featureSet(&.{.bulk_memory}), }), .optimize = optimize, - }); + }) }); const run_unit_tests = b.addRunArtifact(unit_tests); run_unit_tests.skip_foreign_checks = true; diff --git a/test/tests.zig b/test/tests.zig index 572838a2ea..5e037b1c59 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1106,9 +1106,11 @@ pub fn addStackTraceTests( ) *Step { const check_exe = b.addExecutable(.{ .name = "check-stack-trace", - .root_source_file = b.path("test/src/check-stack-trace.zig"), - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("test/src/check-stack-trace.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), }); const cases = b.allocator.create(StackTracesContext) catch @panic("OOM"); @@ -1330,7 +1332,7 @@ pub fn addCliTests(b: *std.Build) *Step { run5.step.dependOn(&run4.step); const unformatted_code_utf16 = "\xff\xfe \x00 \x00 \x00 \x00/\x00/\x00 \x00n\x00o\x00 \x00r\x00e\x00a\x00s\x00o\x00n\x00"; - const fmt6_path = std.fs.path.join(b.allocator, &.{ tmp_path, "fmt6.zig" }) catch @panic("OOM"); + const fmt6_path = b.pathJoin(&.{ tmp_path, "fmt6.zig" }); const write6 = b.addUpdateSourceFiles(); write6.addBytesToSource(unformatted_code_utf16, fmt6_path); write6.step.dependOn(&run5.step); @@ -1514,18 +1516,20 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { options.max_rss; const these_tests = b.addTest(.{ - .root_source_file = b.path(options.root_src), - .optimize = test_target.optimize_mode, - .target = resolved_target, + .root_module = b.createModule(.{ + .root_source_file = b.path(options.root_src), + .optimize = test_target.optimize_mode, + .target = resolved_target, + .link_libc = test_target.link_libc, + .pic = test_target.pic, + .strip = test_target.strip, + .single_threaded = test_target.single_threaded, + }), .max_rss = max_rss, .filters = options.test_filters, - .link_libc = test_target.link_libc, - .single_threaded = test_target.single_threaded, .use_llvm = test_target.use_llvm, .use_lld = test_target.use_lld, .zig_lib_dir = b.path("lib"), - .pic = test_target.pic, - .strip = test_target.strip, }); if (options.no_builtin) these_tests.no_builtin = true; if (options.build_options) |build_options| { @@ -1561,12 +1565,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { var altered_query = test_target.target; altered_query.ofmt = null; - const compile_c = b.addExecutable(.{ - .name = qualified_name, + const compile_c = b.createModule(.{ + .root_source_file = null, .link_libc = test_target.link_libc, .target = b.resolveTargetQuery(altered_query), + }); + const compile_c_exe = b.addExecutable(.{ + .name = qualified_name, + .root_module = compile_c, .zig_lib_dir = b.path("lib"), }); + compile_c.addCSourceFile(.{ .file = these_tests.getEmittedBin(), .flags = &.{ @@ -1611,22 +1620,22 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { continue; } if (test_target.link_libc == false) { - compile_c.subsystem = .Console; - compile_c.linkSystemLibrary("kernel32"); - compile_c.linkSystemLibrary("ntdll"); + compile_c_exe.subsystem = .Console; + compile_c.linkSystemLibrary("kernel32", .{}); + compile_c.linkSystemLibrary("ntdll", .{}); } if (mem.eql(u8, options.name, "std")) { if (test_target.link_libc == false) { - compile_c.linkSystemLibrary("shell32"); - compile_c.linkSystemLibrary("advapi32"); + compile_c.linkSystemLibrary("shell32", .{}); + compile_c.linkSystemLibrary("advapi32", .{}); } - compile_c.linkSystemLibrary("crypt32"); - compile_c.linkSystemLibrary("ws2_32"); - compile_c.linkSystemLibrary("ole32"); + compile_c.linkSystemLibrary("crypt32", .{}); + compile_c.linkSystemLibrary("ws2_32", .{}); + compile_c.linkSystemLibrary("ole32", .{}); } } - const run = b.addRunArtifact(compile_c); + const run = b.addRunArtifact(compile_c_exe); run.skip_foreign_checks = true; run.enableTestRunnerMode(); run.setName(b.fmt("run test {s}", .{qualified_name})); @@ -1675,6 +1684,20 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step { continue; } + const test_mod = b.createModule(.{ + .root_source_file = b.path("test/c_abi/main.zig"), + .target = resolved_target, + .optimize = optimize_mode, + .link_libc = true, + .pic = c_abi_target.pic, + .strip = c_abi_target.strip, + }); + test_mod.addCSourceFile(.{ + .file = b.path("test/c_abi/cfuncs.c"), + .flags = &.{"-std=c99"}, + }); + for (c_abi_target.c_defines) |define| test_mod.addCMacro(define, "1"); + const test_step = b.addTest(.{ .name = b.fmt("test-c-abi-{s}-{s}-{s}{s}{s}{s}", .{ triple_txt, @@ -1691,20 +1714,10 @@ pub fn addCAbiTests(b: *std.Build, options: CAbiTestOptions) *Step { if (c_abi_target.use_lld == false) "-no-lld" else "", if (c_abi_target.pic == true) "-pic" else "", }), - .root_source_file = b.path("test/c_abi/main.zig"), - .target = resolved_target, - .optimize = optimize_mode, - .link_libc = true, + .root_module = test_mod, .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.addCSourceFile(.{ - .file = b.path("test/c_abi/cfuncs.c"), - .flags = &.{"-std=c99"}, - }); - for (c_abi_target.c_defines) |define| test_step.defineCMacro(define, null); // This test is intentionally trying to check if the external ABI is // done properly. LTO would be a hindrance to this. @@ -1784,9 +1797,11 @@ pub fn addDebuggerTests(b: *std.Build, options: DebuggerContext.Options) ?*Step pub fn addIncrementalTests(b: *std.Build, test_step: *Step) !void { const incr_check = b.addExecutable(.{ .name = "incr-check", - .root_source_file = b.path("tools/incr-check.zig"), - .target = b.graph.host, - .optimize = .Debug, + .root_module = b.createModule(.{ + .root_source_file = b.path("tools/incr-check.zig"), + .target = b.graph.host, + .optimize = .Debug, + }), }); var dir = try b.build_root.handle.openDir("test/incremental", .{ .iterate = true });