authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-06-18 23:49:21+05:00
committergravatar for bratishkaerik@landless-city.netEric Joldasov <bratishkaerik@landless-city.net> 2024-12-18 01:48:54+05:00
log6168b8ef86e2ca262585387d12166123842773d1
tree52d0003c1350df2ab579d3a58ddbb3c57f9f80d6
parent0bb93ca053f9520a396a652e929d2cc6358ec5be
signaturelock-open Commit is signed but in an unrecognized format.

std.Build: add API to create Compile steps from existing module

This commit amends `std.Build.ExecutableOptions` etc to have a new field, `root_module`, which allows artifacts to be created whose root module is an existing `*Module` rather than a freshly constructed one. This API can be far more versatile, allowing construction of complex module graphs before creating any compile steps, and therefore also allowing easy reuse of modules. The fields which correspond to module options, such as `root_source_file`, are all considered deprecated. They may not be populated at the same time as the `root_module` field. In the next release cycle, these deprecated fields will be removed, and the `root_module` field made non-optional.

2 files changed, 176 insertions(+), 77 deletions(-)

lib/std/Build.zig+175-77
......@@ -687,24 +687,9 @@ pub fn addOptions(b: *Build) *Step.Options {
687687
688688pub const ExecutableOptions = struct {
689689 name: []const u8,
690 /// If you want the executable to run on the same computer as the one
691 /// building the package, pass the `host` field of the package's `Build`
692 /// instance.
693 target: ResolvedTarget,
694 root_source_file: ?LazyPath = null,
695690 version: ?std.SemanticVersion = null,
696 optimize: std.builtin.OptimizeMode = .Debug,
697 code_model: std.builtin.CodeModel = .default,
698691 linkage: ?std.builtin.LinkMode = null,
699692 max_rss: usize = 0,
700 link_libc: ?bool = null,
701 single_threaded: ?bool = null,
702 pic: ?bool = null,
703 strip: ?bool = null,
704 unwind_tables: ?std.builtin.UnwindTables = null,
705 omit_frame_pointer: ?bool = null,
706 sanitize_thread: ?bool = null,
707 error_tracing: ?bool = null,
708693 use_llvm: ?bool = null,
709694 use_lld: ?bool = null,
710695 zig_lib_dir: ?LazyPath = null,
......@@ -714,14 +699,47 @@ pub const ExecutableOptions = struct {
714699 /// Can be set regardless of target. The `.manifest` file will be ignored
715700 /// if the target object format does not support embedded manifests.
716701 win32_manifest: ?LazyPath = null,
702
703 /// Prefer populating this field (using e.g. `createModule`) instead of populating
704 /// the following fields (`root_source_file` etc). In a future release, those fields
705 /// will be removed, and this field will become non-optional.
706 root_module: ?*Module = null,
707
708 /// Deprecated; prefer populating `root_module`.
709 root_source_file: ?LazyPath = null,
710 /// Deprecated; prefer populating `root_module`.
711 target: ?ResolvedTarget = null,
712 /// Deprecated; prefer populating `root_module`.
713 optimize: std.builtin.OptimizeMode = .Debug,
714 /// Deprecated; prefer populating `root_module`.
715 code_model: std.builtin.CodeModel = .default,
716 /// Deprecated; prefer populating `root_module`.
717 link_libc: ?bool = null,
718 /// Deprecated; prefer populating `root_module`.
719 single_threaded: ?bool = null,
720 /// Deprecated; prefer populating `root_module`.
721 pic: ?bool = null,
722 /// Deprecated; prefer populating `root_module`.
723 strip: ?bool = null,
724 /// Deprecated; prefer populating `root_module`.
725 unwind_tables: ?std.builtin.UnwindTables = null,
726 /// Deprecated; prefer populating `root_module`.
727 omit_frame_pointer: ?bool = null,
728 /// Deprecated; prefer populating `root_module`.
729 sanitize_thread: ?bool = null,
730 /// Deprecated; prefer populating `root_module`.
731 error_tracing: ?bool = null,
717732};
718733
719734pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
720 return Step.Compile.create(b, .{
735 if (options.root_module != null and options.target != null) {
736 @panic("`root_module` and `target` cannot both be populated");
737 }
738 return .create(b, .{
721739 .name = options.name,
722 .root_module = b.createModule(.{
740 .root_module = options.root_module orelse b.createModule(.{
723741 .root_source_file = options.root_source_file,
724 .target = options.target,
742 .target = options.target orelse @panic("`root_module` and `target` cannot both be null"),
725743 .optimize = options.optimize,
726744 .link_libc = options.link_libc,
727745 .single_threaded = options.single_threaded,
......@@ -746,32 +764,51 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
746764
747765pub const ObjectOptions = struct {
748766 name: []const u8,
767 max_rss: usize = 0,
768 use_llvm: ?bool = null,
769 use_lld: ?bool = null,
770 zig_lib_dir: ?LazyPath = null,
771
772 /// Prefer populating this field (using e.g. `createModule`) instead of populating
773 /// the following fields (`root_source_file` etc). In a future release, those fields
774 /// will be removed, and this field will become non-optional.
775 root_module: ?*Module = null,
776
777 /// Deprecated; prefer populating `root_module`.
749778 root_source_file: ?LazyPath = null,
750 /// To choose the same computer as the one building the package, pass the
751 /// `host` field of the package's `Build` instance.
752 target: ResolvedTarget,
779 /// Deprecated; prefer populating `root_module`.
780 target: ?ResolvedTarget = null,
781 /// Deprecated; prefer populating `root_module`.
782 optimize: std.builtin.OptimizeMode = .Debug,
783 /// Deprecated; prefer populating `root_module`.
753784 code_model: std.builtin.CodeModel = .default,
754 optimize: std.builtin.OptimizeMode,
755 max_rss: usize = 0,
785 /// Deprecated; prefer populating `root_module`.
756786 link_libc: ?bool = null,
787 /// Deprecated; prefer populating `root_module`.
757788 single_threaded: ?bool = null,
789 /// Deprecated; prefer populating `root_module`.
758790 pic: ?bool = null,
791 /// Deprecated; prefer populating `root_module`.
759792 strip: ?bool = null,
793 /// Deprecated; prefer populating `root_module`.
760794 unwind_tables: ?std.builtin.UnwindTables = null,
795 /// Deprecated; prefer populating `root_module`.
761796 omit_frame_pointer: ?bool = null,
797 /// Deprecated; prefer populating `root_module`.
762798 sanitize_thread: ?bool = null,
799 /// Deprecated; prefer populating `root_module`.
763800 error_tracing: ?bool = null,
764 use_llvm: ?bool = null,
765 use_lld: ?bool = null,
766 zig_lib_dir: ?LazyPath = null,
767801};
768802
769803pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
770 return Step.Compile.create(b, .{
804 if (options.root_module != null and options.target != null) {
805 @panic("`root_module` and `target` cannot both be populated");
806 }
807 return .create(b, .{
771808 .name = options.name,
772 .root_module = b.createModule(.{
809 .root_module = options.root_module orelse b.createModule(.{
773810 .root_source_file = options.root_source_file,
774 .target = options.target,
811 .target = options.target orelse @panic("`root_module` and `target` cannot both be null"),
775812 .optimize = options.optimize,
776813 .link_libc = options.link_libc,
777814 .single_threaded = options.single_threaded,
......@@ -793,22 +830,8 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
793830
794831pub const SharedLibraryOptions = struct {
795832 name: []const u8,
796 /// To choose the same computer as the one building the package, pass the
797 /// `host` field of the package's `Build` instance.
798 target: ResolvedTarget,
799 optimize: std.builtin.OptimizeMode,
800 code_model: std.builtin.CodeModel = .default,
801 root_source_file: ?LazyPath = null,
802833 version: ?std.SemanticVersion = null,
803834 max_rss: usize = 0,
804 link_libc: ?bool = null,
805 single_threaded: ?bool = null,
806 pic: ?bool = null,
807 strip: ?bool = null,
808 unwind_tables: ?std.builtin.UnwindTables = null,
809 omit_frame_pointer: ?bool = null,
810 sanitize_thread: ?bool = null,
811 error_tracing: ?bool = null,
812835 use_llvm: ?bool = null,
813836 use_lld: ?bool = null,
814837 zig_lib_dir: ?LazyPath = null,
......@@ -818,13 +841,46 @@ pub const SharedLibraryOptions = struct {
818841 /// Can be set regardless of target. The `.manifest` file will be ignored
819842 /// if the target object format does not support embedded manifests.
820843 win32_manifest: ?LazyPath = null,
844
845 /// Prefer populating this field (using e.g. `createModule`) instead of populating
846 /// the following fields (`root_source_file` etc). In a future release, those fields
847 /// will be removed, and this field will become non-optional.
848 root_module: ?*Module = null,
849
850 /// Deprecated; prefer populating `root_module`.
851 root_source_file: ?LazyPath = null,
852 /// Deprecated; prefer populating `root_module`.
853 target: ?ResolvedTarget = null,
854 /// Deprecated; prefer populating `root_module`.
855 optimize: std.builtin.OptimizeMode = .Debug,
856 /// Deprecated; prefer populating `root_module`.
857 code_model: std.builtin.CodeModel = .default,
858 /// Deprecated; prefer populating `root_module`.
859 link_libc: ?bool = null,
860 /// Deprecated; prefer populating `root_module`.
861 single_threaded: ?bool = null,
862 /// Deprecated; prefer populating `root_module`.
863 pic: ?bool = null,
864 /// Deprecated; prefer populating `root_module`.
865 strip: ?bool = null,
866 /// Deprecated; prefer populating `root_module`.
867 unwind_tables: ?std.builtin.UnwindTables = null,
868 /// Deprecated; prefer populating `root_module`.
869 omit_frame_pointer: ?bool = null,
870 /// Deprecated; prefer populating `root_module`.
871 sanitize_thread: ?bool = null,
872 /// Deprecated; prefer populating `root_module`.
873 error_tracing: ?bool = null,
821874};
822875
823876pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile {
824 return Step.Compile.create(b, .{
877 if (options.root_module != null and options.target != null) {
878 @panic("`root_module` and `target` cannot both be populated");
879 }
880 return .create(b, .{
825881 .name = options.name,
826 .root_module = b.createModule(.{
827 .target = options.target,
882 .root_module = options.root_module orelse b.createModule(.{
883 .target = options.target orelse @panic("`root_module` and `target` cannot both be null"),
828884 .optimize = options.optimize,
829885 .root_source_file = options.root_source_file,
830886 .link_libc = options.link_libc,
......@@ -850,32 +906,51 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
850906
851907pub const StaticLibraryOptions = struct {
852908 name: []const u8,
853 root_source_file: ?LazyPath = null,
854 /// To choose the same computer as the one building the package, pass the
855 /// `host` field of the package's `Build` instance.
856 target: ResolvedTarget,
857 optimize: std.builtin.OptimizeMode,
858 code_model: std.builtin.CodeModel = .default,
859909 version: ?std.SemanticVersion = null,
860910 max_rss: usize = 0,
911 use_llvm: ?bool = null,
912 use_lld: ?bool = null,
913 zig_lib_dir: ?LazyPath = null,
914
915 /// Prefer populating this field (using e.g. `createModule`) instead of populating
916 /// the following fields (`root_source_file` etc). In a future release, those fields
917 /// will be removed, and this field will become non-optional.
918 root_module: ?*Module = null,
919
920 /// Deprecated; prefer populating `root_module`.
921 root_source_file: ?LazyPath = null,
922 /// Deprecated; prefer populating `root_module`.
923 target: ?ResolvedTarget = null,
924 /// Deprecated; prefer populating `root_module`.
925 optimize: std.builtin.OptimizeMode = .Debug,
926 /// Deprecated; prefer populating `root_module`.
927 code_model: std.builtin.CodeModel = .default,
928 /// Deprecated; prefer populating `root_module`.
861929 link_libc: ?bool = null,
930 /// Deprecated; prefer populating `root_module`.
862931 single_threaded: ?bool = null,
932 /// Deprecated; prefer populating `root_module`.
863933 pic: ?bool = null,
934 /// Deprecated; prefer populating `root_module`.
864935 strip: ?bool = null,
936 /// Deprecated; prefer populating `root_module`.
865937 unwind_tables: ?std.builtin.UnwindTables = null,
938 /// Deprecated; prefer populating `root_module`.
866939 omit_frame_pointer: ?bool = null,
940 /// Deprecated; prefer populating `root_module`.
867941 sanitize_thread: ?bool = null,
942 /// Deprecated; prefer populating `root_module`.
868943 error_tracing: ?bool = null,
869 use_llvm: ?bool = null,
870 use_lld: ?bool = null,
871 zig_lib_dir: ?LazyPath = null,
872944};
873945
874946pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile {
875 return Step.Compile.create(b, .{
947 if (options.root_module != null and options.target != null) {
948 @panic("`root_module` and `target` cannot both be populated");
949 }
950 return .create(b, .{
876951 .name = options.name,
877 .root_module = b.createModule(.{
878 .target = options.target,
952 .root_module = options.root_module orelse b.createModule(.{
953 .target = options.target orelse @panic("`root_module` and `target` cannot both be null"),
879954 .optimize = options.optimize,
880955 .root_source_file = options.root_source_file,
881956 .link_libc = options.link_libc,
......@@ -900,27 +975,46 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
900975
901976pub const TestOptions = struct {
902977 name: []const u8 = "test",
903 root_source_file: LazyPath,
904 target: ?ResolvedTarget = null,
905 optimize: std.builtin.OptimizeMode = .Debug,
906 version: ?std.SemanticVersion = null,
907978 max_rss: usize = 0,
908 /// deprecated: use `.filters = &.{filter}` instead of `.filter = filter`.
979 /// Deprecated; use `.filters = &.{filter}` instead of `.filter = filter`.
909980 filter: ?[]const u8 = null,
910981 filters: []const []const u8 = &.{},
911982 test_runner: ?LazyPath = null,
983 use_llvm: ?bool = null,
984 use_lld: ?bool = null,
985 zig_lib_dir: ?LazyPath = null,
986
987 /// Prefer populating this field (using e.g. `createModule`) instead of populating
988 /// the following fields (`root_source_file` etc). In a future release, those fields
989 /// will be removed, and this field will become non-optional.
990 root_module: ?*Module = null,
991
992 /// Deprecated; prefer populating `root_module`.
993 root_source_file: ?LazyPath = null,
994 /// Deprecated; prefer populating `root_module`.
995 target: ?ResolvedTarget = null,
996 /// Deprecated; prefer populating `root_module`.
997 optimize: std.builtin.OptimizeMode = .Debug,
998 /// Deprecated; prefer populating `root_module`.
999 version: ?std.SemanticVersion = null,
1000 /// Deprecated; prefer populating `root_module`.
9121001 link_libc: ?bool = null,
1002 /// Deprecated; prefer populating `root_module`.
9131003 link_libcpp: ?bool = null,
1004 /// Deprecated; prefer populating `root_module`.
9141005 single_threaded: ?bool = null,
1006 /// Deprecated; prefer populating `root_module`.
9151007 pic: ?bool = null,
1008 /// Deprecated; prefer populating `root_module`.
9161009 strip: ?bool = null,
1010 /// Deprecated; prefer populating `root_module`.
9171011 unwind_tables: ?std.builtin.UnwindTables = null,
1012 /// Deprecated; prefer populating `root_module`.
9181013 omit_frame_pointer: ?bool = null,
1014 /// Deprecated; prefer populating `root_module`.
9191015 sanitize_thread: ?bool = null,
1016 /// Deprecated; prefer populating `root_module`.
9201017 error_tracing: ?bool = null,
921 use_llvm: ?bool = null,
922 use_lld: ?bool = null,
923 zig_lib_dir: ?LazyPath = null,
9241018};
9251019
9261020/// Creates an executable containing unit tests.
......@@ -932,11 +1026,14 @@ pub const TestOptions = struct {
9321026/// two steps are separated because they are independently configured and
9331027/// cached.
9341028pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
935 return Step.Compile.create(b, .{
1029 if (options.root_module != null and options.root_source_file != null) {
1030 @panic("`root_module` and `root_source_file` cannot both be populated");
1031 }
1032 return .create(b, .{
9361033 .name = options.name,
9371034 .kind = .@"test",
938 .root_module = b.createModule(.{
939 .root_source_file = options.root_source_file,
1035 .root_module = options.root_module orelse b.createModule(.{
1036 .root_source_file = options.root_source_file orelse @panic("`root_module` and `root_source_file` cannot both be null"),
9401037 .target = options.target orelse b.graph.host,
9411038 .optimize = options.optimize,
9421039 .link_libc = options.link_libc,
......@@ -974,19 +1071,20 @@ pub const AssemblyOptions = struct {
9741071 zig_lib_dir: ?LazyPath = null,
9751072};
9761073
1074/// Deprecated; prefer using `addObject` where the `root_module` has an empty
1075/// `root_source_file` and contains an assembly file via `Module.addAssemblyFile`.
9771076pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
978 const obj_step = Step.Compile.create(b, .{
1077 const root_module = b.createModule(.{
1078 .target = options.target,
1079 .optimize = options.optimize,
1080 });
1081 root_module.addAssemblyFile(options.source_file);
1082 return b.addObject(.{
9791083 .name = options.name,
980 .kind = .obj,
981 .root_module = b.createModule(.{
982 .target = options.target,
983 .optimize = options.optimize,
984 }),
9851084 .max_rss = options.max_rss,
9861085 .zig_lib_dir = options.zig_lib_dir,
1086 .root_module = root_module,
9871087 });
988 obj_step.addAssemblyFile(options.source_file);
989 return obj_step;
9901088}
9911089
9921090/// This function creates a module and adds it to the package's module set, making
lib/std/Build/Step/TranslateC.zig+1
......@@ -63,6 +63,7 @@ pub fn getOutput(translate_c: *TranslateC) std.Build.LazyPath {
6363 return .{ .generated = .{ .file = &translate_c.output_file } };
6464}
6565
66/// Deprecated: use `createModule` or `addModule` with `std.Build.addExecutable` instead.
6667/// Creates a step to build an executable from the translated source.
6768pub fn addExecutable(translate_c: *TranslateC, options: AddExecutableOptions) *Step.Compile {
6869 return translate_c.step.owner.addExecutable(.{