Skip to content

Commit 42afe20

Browse files
committed
introduce std.Build.Module and extract some logic into it
This moves many settings from `std.Build.Step.Compile` and into `std.Build.Module`, and then makes them transitive. In other words, it adds support for exposing Zig modules in packages, which are configured in various ways, such as depending on other link objects, include paths, or even a different optimization mode. Now, transitive dependencies will be included in the compilation, so you can, for example, make a Zig module depend on some C source code, and expose that Zig module in a package. Currently, the compiler frontend autogenerates only one `@import("builtin")` module for the entire compilation, however, a future enhancement will be to make it honor the differences in modules, so that modules can be compiled with different optimization modes, code model, valgrind integration, or even target CPU feature set. closes #14719
1 parent 79038ca commit 42afe20

File tree

4 files changed

+991
-950
lines changed

4 files changed

+991
-950
lines changed

lib/std/Build.zig

Lines changed: 44 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -29,36 +29,7 @@ pub const Builder = Build;
2929
pub const InstallDirectoryOptions = Step.InstallDir.Options;
3030

3131
pub const Step = @import("Build/Step.zig");
32-
/// deprecated: use `Step.CheckFile`.
33-
pub const CheckFileStep = @import("Build/Step/CheckFile.zig");
34-
/// deprecated: use `Step.CheckObject`.
35-
pub const CheckObjectStep = @import("Build/Step/CheckObject.zig");
36-
/// deprecated: use `Step.ConfigHeader`.
37-
pub const ConfigHeaderStep = @import("Build/Step/ConfigHeader.zig");
38-
/// deprecated: use `Step.Fmt`.
39-
pub const FmtStep = @import("Build/Step/Fmt.zig");
40-
/// deprecated: use `Step.InstallArtifact`.
41-
pub const InstallArtifactStep = @import("Build/Step/InstallArtifact.zig");
42-
/// deprecated: use `Step.InstallDir`.
43-
pub const InstallDirStep = @import("Build/Step/InstallDir.zig");
44-
/// deprecated: use `Step.InstallFile`.
45-
pub const InstallFileStep = @import("Build/Step/InstallFile.zig");
46-
/// deprecated: use `Step.ObjCopy`.
47-
pub const ObjCopyStep = @import("Build/Step/ObjCopy.zig");
48-
/// deprecated: use `Step.Compile`.
49-
pub const CompileStep = @import("Build/Step/Compile.zig");
50-
/// deprecated: use `Step.Options`.
51-
pub const OptionsStep = @import("Build/Step/Options.zig");
52-
/// deprecated: use `Step.RemoveDir`.
53-
pub const RemoveDirStep = @import("Build/Step/RemoveDir.zig");
54-
/// deprecated: use `Step.Run`.
55-
pub const RunStep = @import("Build/Step/Run.zig");
56-
/// deprecated: use `Step.TranslateC`.
57-
pub const TranslateCStep = @import("Build/Step/TranslateC.zig");
58-
/// deprecated: use `Step.WriteFile`.
59-
pub const WriteFileStep = @import("Build/Step/WriteFile.zig");
60-
/// deprecated: use `LazyPath`.
61-
pub const FileSource = LazyPath;
32+
pub const Module = @import("Build/Module.zig");
6233

6334
install_tls: TopLevelStep,
6435
uninstall_tls: TopLevelStep,
@@ -634,34 +605,31 @@ pub const ExecutableOptions = struct {
634605
use_llvm: ?bool = null,
635606
use_lld: ?bool = null,
636607
zig_lib_dir: ?LazyPath = null,
637-
main_mod_path: ?LazyPath = null,
638608
/// Embed a `.manifest` file in the compilation if the object format supports it.
639609
/// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference
640610
/// Manifest files must have the extension `.manifest`.
641611
/// Can be set regardless of target. The `.manifest` file will be ignored
642612
/// if the target object format does not support embedded manifests.
643613
win32_manifest: ?LazyPath = null,
644-
645-
/// Deprecated; use `main_mod_path`.
646-
main_pkg_path: ?LazyPath = null,
647614
};
648615

649616
pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
650617
return Step.Compile.create(b, .{
651618
.name = options.name,
652-
.root_source_file = options.root_source_file,
619+
.root_module = .{
620+
.root_source_file = options.root_source_file,
621+
.target = options.target,
622+
.optimize = options.optimize,
623+
.link_libc = options.link_libc,
624+
.single_threaded = options.single_threaded,
625+
},
653626
.version = options.version,
654-
.target = options.target,
655-
.optimize = options.optimize,
656627
.kind = .exe,
657628
.linkage = options.linkage,
658629
.max_rss = options.max_rss,
659-
.link_libc = options.link_libc,
660-
.single_threaded = options.single_threaded,
661630
.use_llvm = options.use_llvm,
662631
.use_lld = options.use_lld,
663632
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
664-
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
665633
.win32_manifest = options.win32_manifest,
666634
});
667635
}
@@ -677,26 +645,23 @@ pub const ObjectOptions = struct {
677645
use_llvm: ?bool = null,
678646
use_lld: ?bool = null,
679647
zig_lib_dir: ?LazyPath = null,
680-
main_mod_path: ?LazyPath = null,
681-
682-
/// Deprecated; use `main_mod_path`.
683-
main_pkg_path: ?LazyPath = null,
684648
};
685649

686650
pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
687651
return Step.Compile.create(b, .{
688652
.name = options.name,
689-
.root_source_file = options.root_source_file,
690-
.target = options.target,
691-
.optimize = options.optimize,
653+
.root_module = .{
654+
.root_source_file = options.root_source_file,
655+
.target = options.target,
656+
.optimize = options.optimize,
657+
.link_libc = options.link_libc,
658+
.single_threaded = options.single_threaded,
659+
},
692660
.kind = .obj,
693661
.max_rss = options.max_rss,
694-
.link_libc = options.link_libc,
695-
.single_threaded = options.single_threaded,
696662
.use_llvm = options.use_llvm,
697663
.use_lld = options.use_lld,
698664
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
699-
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
700665
});
701666
}
702667

@@ -712,34 +677,31 @@ pub const SharedLibraryOptions = struct {
712677
use_llvm: ?bool = null,
713678
use_lld: ?bool = null,
714679
zig_lib_dir: ?LazyPath = null,
715-
main_mod_path: ?LazyPath = null,
716680
/// Embed a `.manifest` file in the compilation if the object format supports it.
717681
/// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference
718682
/// Manifest files must have the extension `.manifest`.
719683
/// Can be set regardless of target. The `.manifest` file will be ignored
720684
/// if the target object format does not support embedded manifests.
721685
win32_manifest: ?LazyPath = null,
722-
723-
/// Deprecated; use `main_mod_path`.
724-
main_pkg_path: ?LazyPath = null,
725686
};
726687

727688
pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile {
728689
return Step.Compile.create(b, .{
729690
.name = options.name,
730-
.root_source_file = options.root_source_file,
691+
.root_module = .{
692+
.target = options.target,
693+
.optimize = options.optimize,
694+
.root_source_file = options.root_source_file,
695+
.link_libc = options.link_libc,
696+
.single_threaded = options.single_threaded,
697+
},
731698
.kind = .lib,
732699
.linkage = .dynamic,
733700
.version = options.version,
734-
.target = options.target,
735-
.optimize = options.optimize,
736701
.max_rss = options.max_rss,
737-
.link_libc = options.link_libc,
738-
.single_threaded = options.single_threaded,
739702
.use_llvm = options.use_llvm,
740703
.use_lld = options.use_lld,
741704
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
742-
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
743705
.win32_manifest = options.win32_manifest,
744706
});
745707
}
@@ -756,28 +718,25 @@ pub const StaticLibraryOptions = struct {
756718
use_llvm: ?bool = null,
757719
use_lld: ?bool = null,
758720
zig_lib_dir: ?LazyPath = null,
759-
main_mod_path: ?LazyPath = null,
760-
761-
/// Deprecated; use `main_mod_path`.
762-
main_pkg_path: ?LazyPath = null,
763721
};
764722

765723
pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile {
766724
return Step.Compile.create(b, .{
767725
.name = options.name,
768-
.root_source_file = options.root_source_file,
726+
.root_module = .{
727+
.target = options.target,
728+
.optimize = options.optimize,
729+
.root_source_file = options.root_source_file,
730+
.link_libc = options.link_libc,
731+
.single_threaded = options.single_threaded,
732+
},
769733
.kind = .lib,
770734
.linkage = .static,
771735
.version = options.version,
772-
.target = options.target,
773-
.optimize = options.optimize,
774736
.max_rss = options.max_rss,
775-
.link_libc = options.link_libc,
776-
.single_threaded = options.single_threaded,
777737
.use_llvm = options.use_llvm,
778738
.use_lld = options.use_lld,
779739
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
780-
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
781740
});
782741
}
783742

@@ -795,28 +754,25 @@ pub const TestOptions = struct {
795754
use_llvm: ?bool = null,
796755
use_lld: ?bool = null,
797756
zig_lib_dir: ?LazyPath = null,
798-
main_mod_path: ?LazyPath = null,
799-
800-
/// Deprecated; use `main_mod_path`.
801-
main_pkg_path: ?LazyPath = null,
802757
};
803758

804759
pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
805760
return Step.Compile.create(b, .{
806761
.name = options.name,
807762
.kind = .@"test",
808-
.root_source_file = options.root_source_file,
809-
.target = options.target,
810-
.optimize = options.optimize,
763+
.root_module = .{
764+
.root_source_file = options.root_source_file,
765+
.target = options.target,
766+
.optimize = options.optimize,
767+
.link_libc = options.link_libc,
768+
.single_threaded = options.single_threaded,
769+
},
811770
.max_rss = options.max_rss,
812771
.filter = options.filter,
813772
.test_runner = options.test_runner,
814-
.link_libc = options.link_libc,
815-
.single_threaded = options.single_threaded,
816773
.use_llvm = options.use_llvm,
817774
.use_lld = options.use_lld,
818775
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
819-
.main_mod_path = options.main_mod_path orelse options.main_pkg_path,
820776
});
821777
}
822778

@@ -833,9 +789,10 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
833789
const obj_step = Step.Compile.create(b, .{
834790
.name = options.name,
835791
.kind = .obj,
836-
.root_source_file = null,
837-
.target = options.target,
838-
.optimize = options.optimize,
792+
.root_module = .{
793+
.target = options.target,
794+
.optimize = options.optimize,
795+
},
839796
.max_rss = options.max_rss,
840797
.zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
841798
});
@@ -846,41 +803,17 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
846803
/// This function creates a module and adds it to the package's module set, making
847804
/// it available to other packages which depend on this one.
848805
/// `createModule` can be used instead to create a private module.
849-
pub fn addModule(b: *Build, name: []const u8, options: CreateModuleOptions) *Module {
850-
const module = b.createModule(options);
806+
pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module {
807+
const module = Module.create(b, options);
851808
b.modules.put(b.dupe(name), module) catch @panic("OOM");
852809
return module;
853810
}
854811

855-
pub const ModuleDependency = struct {
856-
name: []const u8,
857-
module: *Module,
858-
};
859-
860-
pub const CreateModuleOptions = struct {
861-
source_file: LazyPath,
862-
dependencies: []const ModuleDependency = &.{},
863-
};
864-
865812
/// This function creates a private module, to be used by the current package,
866813
/// but not exposed to other packages depending on this one.
867814
/// `addModule` can be used instead to create a public module.
868-
pub fn createModule(b: *Build, options: CreateModuleOptions) *Module {
869-
const module = b.allocator.create(Module) catch @panic("OOM");
870-
module.* = .{
871-
.builder = b,
872-
.source_file = options.source_file.dupe(b),
873-
.dependencies = moduleDependenciesToArrayHashMap(b.allocator, options.dependencies),
874-
};
875-
return module;
876-
}
877-
878-
fn moduleDependenciesToArrayHashMap(arena: Allocator, deps: []const ModuleDependency) std.StringArrayHashMap(*Module) {
879-
var result = std.StringArrayHashMap(*Module).init(arena);
880-
for (deps) |dep| {
881-
result.put(dep.name, dep.module) catch @panic("OOM");
882-
}
883-
return result;
815+
pub fn createModule(b: *Build, options: Module.CreateOptions) *Module {
816+
return Module.create(b, options);
884817
}
885818

886819
/// Initializes a `Step.Run` with argv, which must at least have the path to the
@@ -1885,15 +1818,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void {
18851818
}
18861819
}
18871820

1888-
pub const Module = struct {
1889-
builder: *Build,
1890-
/// This could either be a generated file, in which case the module
1891-
/// contains exactly one file, or it could be a path to the root source
1892-
/// file of directory of files which constitute the module.
1893-
source_file: LazyPath,
1894-
dependencies: std.StringArrayHashMap(*Module),
1895-
};
1896-
18971821
/// A file that is generated by a build step.
18981822
/// This struct is an interface that is meant to be used with `@fieldParentPtr` to implement the actual path logic.
18991823
pub const GeneratedFile = struct {

0 commit comments

Comments
 (0)