| ... | ... | @@ -31,6 +31,7 @@ pub const Builder = struct { |
| 31 | 31 | verbose_tokenize: bool, |
| 32 | 32 | verbose_ast: bool, |
| 33 | 33 | verbose_link: bool, |
| 34 | verbose_cc: bool, |
| 34 | 35 | verbose_ir: bool, |
| 35 | 36 | verbose_llvm_ir: bool, |
| 36 | 37 | verbose_cimport: bool, |
| ... | ... | @@ -99,6 +100,7 @@ pub const Builder = struct { |
| 99 | 100 | .verbose_tokenize = false, |
| 100 | 101 | .verbose_ast = false, |
| 101 | 102 | .verbose_link = false, |
| 103 | .verbose_cc = false, |
| 102 | 104 | .verbose_ir = false, |
| 103 | 105 | .verbose_llvm_ir = false, |
| 104 | 106 | .verbose_cimport = false, |
| ... | ... | @@ -157,7 +159,7 @@ pub const Builder = struct { |
| 157 | 159 | return LibExeObjStep.createExecutable(self, name, root_src, true); |
| 158 | 160 | } |
| 159 | 161 | |
| 160 | | pub fn addObject(self: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep { |
| 162 | pub fn addObject(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 161 | 163 | return LibExeObjStep.createObject(self, name, root_src); |
| 162 | 164 | } |
| 163 | 165 | |
| ... | ... | @@ -169,10 +171,8 @@ pub const Builder = struct { |
| 169 | 171 | return LibExeObjStep.createStaticLibrary(self, name, root_src); |
| 170 | 172 | } |
| 171 | 173 | |
| 172 | | pub fn addTest(self: *Builder, root_src: []const u8) *TestStep { |
| 173 | | const test_step = self.allocator.create(TestStep) catch unreachable; |
| 174 | | test_step.* = TestStep.init(self, root_src); |
| 175 | | return test_step; |
| 174 | pub fn addTest(self: *Builder, root_src: []const u8) *LibExeObjStep { |
| 175 | return LibExeObjStep.createTest(self, "test", root_src); |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | 178 | pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| ... | ... | @@ -181,22 +181,6 @@ pub const Builder = struct { |
| 181 | 181 | return obj_step; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | | pub fn addCStaticLibrary(self: *Builder, name: []const u8) *LibExeObjStep { |
| 185 | | return LibExeObjStep.createCStaticLibrary(self, name); |
| 186 | | } |
| 187 | | |
| 188 | | pub fn addCSharedLibrary(self: *Builder, name: []const u8, ver: Version) *LibExeObjStep { |
| 189 | | return LibExeObjStep.createCSharedLibrary(self, name, ver); |
| 190 | | } |
| 191 | | |
| 192 | | pub fn addCExecutable(self: *Builder, name: []const u8) *LibExeObjStep { |
| 193 | | return LibExeObjStep.createCExecutable(self, name); |
| 194 | | } |
| 195 | | |
| 196 | | pub fn addCObject(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| 197 | | return LibExeObjStep.createCObject(self, name, src); |
| 198 | | } |
| 199 | | |
| 200 | 184 | /// ::argv is copied. |
| 201 | 185 | pub fn addCommand(self: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep { |
| 202 | 186 | return CommandStep.create(self, cwd, env_map, argv); |
| ... | ... | @@ -663,14 +647,6 @@ pub const Builder = struct { |
| 663 | 647 | return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable; |
| 664 | 648 | } |
| 665 | 649 | |
| 666 | | fn getCCExe(self: *Builder) []const u8 { |
| 667 | | if (builtin.environ == builtin.Environ.msvc) { |
| 668 | | return "cl.exe"; |
| 669 | | } else { |
| 670 | | return os.getEnvVarOwned(self.allocator, "CC") catch |err| if (err == error.EnvironmentVariableNotFound) ([]const u8)("cc") else debug.panic("Unable to get environment variable: {}", err); |
| 671 | | } |
| 672 | | } |
| 673 | | |
| 674 | 650 | pub fn findProgram(self: *Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 { |
| 675 | 651 | // TODO report error for ambiguous situations |
| 676 | 652 | const exe_extension = (Target{ .Native = {} }).exeFileExt(); |
| ... | ... | @@ -825,6 +801,11 @@ const Pkg = struct { |
| 825 | 801 | path: []const u8, |
| 826 | 802 | }; |
| 827 | 803 | |
| 804 | const CSourceFile = struct { |
| 805 | source_path: []const u8, |
| 806 | args: []const []const u8, |
| 807 | }; |
| 808 | |
| 828 | 809 | pub const LibExeObjStep = struct { |
| 829 | 810 | step: Step, |
| 830 | 811 | builder: *Builder, |
| ... | ... | @@ -844,16 +825,17 @@ pub const LibExeObjStep = struct { |
| 844 | 825 | strip: bool, |
| 845 | 826 | full_path_libs: ArrayList([]const u8), |
| 846 | 827 | need_flat_namespace_hack: bool, |
| 847 | | is_zig: bool, |
| 848 | | cflags: ArrayList([]const u8), |
| 849 | 828 | include_dirs: ArrayList([]const u8), |
| 850 | 829 | lib_paths: ArrayList([]const u8), |
| 851 | | disable_libc: bool, |
| 852 | 830 | frameworks: BufSet, |
| 853 | 831 | verbose_link: bool, |
| 832 | verbose_cc: bool, |
| 854 | 833 | c_std: Builder.CStd, |
| 834 | override_std_dir: ?[]const u8, |
| 835 | exec_cmd_args: ?[]const ?[]const u8, |
| 836 | name_prefix: []const u8, |
| 837 | filter: ?[]const u8, |
| 855 | 838 | |
| 856 | | // zig only stuff |
| 857 | 839 | root_src: ?[]const u8, |
| 858 | 840 | output_h_path: ?[]const u8, |
| 859 | 841 | out_h_filename: []const u8, |
| ... | ... | @@ -862,14 +844,14 @@ pub const LibExeObjStep = struct { |
| 862 | 844 | build_options_contents: std.Buffer, |
| 863 | 845 | system_linker_hack: bool, |
| 864 | 846 | |
| 865 | | // C only stuff |
| 866 | | source_files: ArrayList([]const u8), |
| 847 | c_source_files: ArrayList(*CSourceFile), |
| 867 | 848 | object_src: []const u8, |
| 868 | 849 | |
| 869 | 850 | const Kind = enum { |
| 870 | 851 | Exe, |
| 871 | 852 | Lib, |
| 872 | 853 | Obj, |
| 854 | Test, |
| 873 | 855 | }; |
| 874 | 856 | |
| 875 | 857 | pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep { |
| ... | ... | @@ -878,46 +860,27 @@ pub const LibExeObjStep = struct { |
| 878 | 860 | return self; |
| 879 | 861 | } |
| 880 | 862 | |
| 881 | | pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep { |
| 882 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 883 | | self.* = initC(builder, name, Kind.Lib, version, false); |
| 884 | | return self; |
| 885 | | } |
| 886 | | |
| 887 | 863 | pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 888 | 864 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 889 | 865 | self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0)); |
| 890 | 866 | return self; |
| 891 | 867 | } |
| 892 | 868 | |
| 893 | | pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep { |
| 894 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 895 | | self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true); |
| 896 | | return self; |
| 897 | | } |
| 898 | | |
| 899 | | pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep { |
| 869 | pub fn createObject(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 900 | 870 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 901 | 871 | self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0)); |
| 902 | 872 | return self; |
| 903 | 873 | } |
| 904 | 874 | |
| 905 | | pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| 906 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 907 | | self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false); |
| 908 | | self.object_src = src; |
| 909 | | return self; |
| 910 | | } |
| 911 | | |
| 912 | 875 | pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep { |
| 913 | 876 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 914 | 877 | self.* = initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0)); |
| 915 | 878 | return self; |
| 916 | 879 | } |
| 917 | 880 | |
| 918 | | pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep { |
| 881 | pub fn createTest(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep { |
| 919 | 882 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 920 | | self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false); |
| 883 | self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, builder.version(0, 0, 0)); |
| 921 | 884 | return self; |
| 922 | 885 | } |
| 923 | 886 | |
| ... | ... | @@ -926,6 +889,7 @@ pub const LibExeObjStep = struct { |
| 926 | 889 | .strip = false, |
| 927 | 890 | .builder = builder, |
| 928 | 891 | .verbose_link = false, |
| 892 | .verbose_cc = false, |
| 929 | 893 | .build_mode = builtin.Mode.Debug, |
| 930 | 894 | .static = static, |
| 931 | 895 | .kind = kind, |
| ... | ... | @@ -946,61 +910,19 @@ pub const LibExeObjStep = struct { |
| 946 | 910 | .object_files = ArrayList([]const u8).init(builder.allocator), |
| 947 | 911 | .assembly_files = ArrayList([]const u8).init(builder.allocator), |
| 948 | 912 | .packages = ArrayList(Pkg).init(builder.allocator), |
| 949 | | .is_zig = true, |
| 950 | 913 | .full_path_libs = ArrayList([]const u8).init(builder.allocator), |
| 951 | 914 | .need_flat_namespace_hack = false, |
| 952 | | .cflags = ArrayList([]const u8).init(builder.allocator), |
| 953 | | .source_files = undefined, |
| 915 | .c_source_files = ArrayList(*CSourceFile).init(builder.allocator), |
| 954 | 916 | .include_dirs = ArrayList([]const u8).init(builder.allocator), |
| 955 | 917 | .lib_paths = ArrayList([]const u8).init(builder.allocator), |
| 956 | 918 | .object_src = undefined, |
| 957 | | .disable_libc = true, |
| 958 | 919 | .build_options_contents = std.Buffer.initSize(builder.allocator, 0) catch unreachable, |
| 959 | 920 | .c_std = Builder.CStd.C99, |
| 960 | 921 | .system_linker_hack = false, |
| 961 | | }; |
| 962 | | self.computeOutFileNames(); |
| 963 | | return self; |
| 964 | | } |
| 965 | | |
| 966 | | fn initC(builder: *Builder, name: []const u8, kind: Kind, version: Version, static: bool) LibExeObjStep { |
| 967 | | var self = LibExeObjStep{ |
| 968 | | .builder = builder, |
| 969 | | .name = name, |
| 970 | | .kind = kind, |
| 971 | | .version = version, |
| 972 | | .static = static, |
| 973 | | .target = Target.Native, |
| 974 | | .cflags = ArrayList([]const u8).init(builder.allocator), |
| 975 | | .source_files = ArrayList([]const u8).init(builder.allocator), |
| 976 | | .object_files = ArrayList([]const u8).init(builder.allocator), |
| 977 | | .step = Step.init(name, builder.allocator, make), |
| 978 | | .link_libs = BufSet.init(builder.allocator), |
| 979 | | .frameworks = BufSet.init(builder.allocator), |
| 980 | | .full_path_libs = ArrayList([]const u8).init(builder.allocator), |
| 981 | | .include_dirs = ArrayList([]const u8).init(builder.allocator), |
| 982 | | .lib_paths = ArrayList([]const u8).init(builder.allocator), |
| 983 | | .output_path = null, |
| 984 | | .out_filename = undefined, |
| 985 | | .major_only_filename = undefined, |
| 986 | | .name_only_filename = undefined, |
| 987 | | .object_src = undefined, |
| 988 | | .build_mode = builtin.Mode.Debug, |
| 989 | | .strip = false, |
| 990 | | .need_flat_namespace_hack = false, |
| 991 | | .disable_libc = false, |
| 992 | | .is_zig = false, |
| 993 | | .linker_script = null, |
| 994 | | .c_std = Builder.CStd.C99, |
| 995 | | .system_linker_hack = false, |
| 996 | | |
| 997 | | .root_src = undefined, |
| 998 | | .verbose_link = false, |
| 999 | | .output_h_path = undefined, |
| 1000 | | .out_h_filename = undefined, |
| 1001 | | .assembly_files = undefined, |
| 1002 | | .packages = undefined, |
| 1003 | | .build_options_contents = undefined, |
| 922 | .override_std_dir = null, |
| 923 | .exec_cmd_args = null, |
| 924 | .name_prefix = "", |
| 925 | .filter = null, |
| 1004 | 926 | }; |
| 1005 | 927 | self.computeOutFileNames(); |
| 1006 | 928 | return self; |
| ... | ... | @@ -1014,6 +936,9 @@ pub const LibExeObjStep = struct { |
| 1014 | 936 | Kind.Exe => { |
| 1015 | 937 | self.out_filename = self.builder.fmt("{}{}", self.name, self.target.exeFileExt()); |
| 1016 | 938 | }, |
| 939 | Kind.Test => { |
| 940 | self.out_filename = self.builder.fmt("test{}", self.target.exeFileExt()); |
| 941 | }, |
| 1017 | 942 | Kind.Lib => { |
| 1018 | 943 | if (self.static) { |
| 1019 | 944 | self.out_filename = self.builder.fmt("lib{}.a", self.name); |
| ... | ... | @@ -1081,24 +1006,44 @@ pub const LibExeObjStep = struct { |
| 1081 | 1006 | } |
| 1082 | 1007 | |
| 1083 | 1008 | pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void { |
| 1084 | | assert(self.kind != Kind.Obj); |
| 1085 | 1009 | self.link_libs.put(name) catch unreachable; |
| 1086 | 1010 | } |
| 1087 | 1011 | |
| 1088 | | pub fn addSourceFile(self: *LibExeObjStep, file: []const u8) void { |
| 1089 | | assert(self.kind != Kind.Obj); |
| 1090 | | assert(!self.is_zig); |
| 1091 | | self.source_files.append(file) catch unreachable; |
| 1012 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| 1013 | assert(self.kind == Kind.Test); |
| 1014 | self.name_prefix = text; |
| 1015 | } |
| 1016 | |
| 1017 | pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { |
| 1018 | assert(self.kind == Kind.Test); |
| 1019 | self.filter = text; |
| 1020 | } |
| 1021 | |
| 1022 | pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, args: []const []const u8) void { |
| 1023 | const c_source_file = self.builder.allocator.create(CSourceFile) catch unreachable; |
| 1024 | c_source_file.* = CSourceFile{ |
| 1025 | .source_path = file, |
| 1026 | .args = args, |
| 1027 | }; |
| 1028 | self.c_source_files.append(c_source_file) catch unreachable; |
| 1092 | 1029 | } |
| 1093 | 1030 | |
| 1094 | 1031 | pub fn setVerboseLink(self: *LibExeObjStep, value: bool) void { |
| 1095 | 1032 | self.verbose_link = value; |
| 1096 | 1033 | } |
| 1097 | 1034 | |
| 1035 | pub fn setVerboseCC(self: *LibExeObjStep, value: bool) void { |
| 1036 | self.verbose_cc = value; |
| 1037 | } |
| 1038 | |
| 1098 | 1039 | pub fn setBuildMode(self: *LibExeObjStep, mode: builtin.Mode) void { |
| 1099 | 1040 | self.build_mode = mode; |
| 1100 | 1041 | } |
| 1101 | 1042 | |
| 1043 | pub fn overrideStdDir(self: *LibExeObjStep, dir_path: []const u8) void { |
| 1044 | self.override_std_dir = dir_path; |
| 1045 | } |
| 1046 | |
| 1102 | 1047 | pub fn setOutputPath(self: *LibExeObjStep, file_path: []const u8) void { |
| 1103 | 1048 | self.output_path = file_path; |
| 1104 | 1049 | |
| ... | ... | @@ -1149,17 +1094,15 @@ pub const LibExeObjStep = struct { |
| 1149 | 1094 | |
| 1150 | 1095 | self.object_files.append(obj.getOutputPath()) catch unreachable; |
| 1151 | 1096 | |
| 1152 | | // TODO make this lazy instead of stateful |
| 1153 | | if (!obj.disable_libc) { |
| 1154 | | self.disable_libc = false; |
| 1155 | | } |
| 1156 | | |
| 1157 | 1097 | // TODO should be some kind of isolated directory that only has this header in it |
| 1158 | 1098 | self.include_dirs.append(self.builder.cache_root) catch unreachable; |
| 1099 | |
| 1100 | if (obj.link_libs.exists("c")) { |
| 1101 | self.link_libs.put("c") catch unreachable; |
| 1102 | } |
| 1159 | 1103 | } |
| 1160 | 1104 | |
| 1161 | 1105 | pub fn addBuildOption(self: *LibExeObjStep, comptime T: type, name: []const u8, value: T) void { |
| 1162 | | assert(self.is_zig); |
| 1163 | 1106 | const out = &std.io.BufferOutStream.init(&self.build_options_contents).stream; |
| 1164 | 1107 | out.print("pub const {} = {};\n", name, value) catch unreachable; |
| 1165 | 1108 | } |
| ... | ... | @@ -1173,23 +1116,15 @@ pub const LibExeObjStep = struct { |
| 1173 | 1116 | } |
| 1174 | 1117 | |
| 1175 | 1118 | pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void { |
| 1176 | | assert(self.is_zig); |
| 1177 | | |
| 1178 | 1119 | self.packages.append(Pkg{ |
| 1179 | 1120 | .name = name, |
| 1180 | 1121 | .path = pkg_index_path, |
| 1181 | 1122 | }) catch unreachable; |
| 1182 | 1123 | } |
| 1183 | 1124 | |
| 1184 | | pub fn addCompileFlags(self: *LibExeObjStep, flags: []const []const u8) void { |
| 1185 | | for (flags) |flag| { |
| 1186 | | self.cflags.append(flag) catch unreachable; |
| 1187 | | } |
| 1188 | | } |
| 1189 | | |
| 1190 | | pub fn setNoStdLib(self: *LibExeObjStep, disable: bool) void { |
| 1191 | | assert(!self.is_zig); |
| 1192 | | self.disable_libc = disable; |
| 1125 | pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void { |
| 1126 | assert(self.kind == Kind.Test); |
| 1127 | self.exec_cmd_args = args; |
| 1193 | 1128 | } |
| 1194 | 1129 | |
| 1195 | 1130 | pub fn enableSystemLinkerHack(self: *LibExeObjStep) void { |
| ... | ... | @@ -1198,15 +1133,11 @@ pub const LibExeObjStep = struct { |
| 1198 | 1133 | |
| 1199 | 1134 | fn make(step: *Step) !void { |
| 1200 | 1135 | const self = @fieldParentPtr(LibExeObjStep, "step", step); |
| 1201 | | return if (self.is_zig) self.makeZig() else self.makeC(); |
| 1202 | | } |
| 1203 | | |
| 1204 | | fn makeZig(self: *LibExeObjStep) !void { |
| 1205 | 1136 | const builder = self.builder; |
| 1206 | 1137 | |
| 1207 | | assert(self.is_zig); |
| 1208 | | |
| 1209 | | if (self.root_src == null and self.object_files.len == 0 and self.assembly_files.len == 0) { |
| 1138 | if (self.root_src == null and self.object_files.len == 0 and |
| 1139 | self.assembly_files.len == 0 and self.c_source_files.len == 0) |
| 1140 | { |
| 1210 | 1141 | warn("{}: linker needs 1 or more objects to link\n", self.step.name); |
| 1211 | 1142 | return error.NeedAnObject; |
| 1212 | 1143 | } |
| ... | ... | @@ -1220,6 +1151,7 @@ pub const LibExeObjStep = struct { |
| 1220 | 1151 | Kind.Lib => "build-lib", |
| 1221 | 1152 | Kind.Exe => "build-exe", |
| 1222 | 1153 | Kind.Obj => "build-obj", |
| 1154 | Kind.Test => "test", |
| 1223 | 1155 | }; |
| 1224 | 1156 | zig_args.append(cmd) catch unreachable; |
| 1225 | 1157 | |
| ... | ... | @@ -1227,6 +1159,14 @@ pub const LibExeObjStep = struct { |
| 1227 | 1159 | zig_args.append(builder.pathFromRoot(root_src)) catch unreachable; |
| 1228 | 1160 | } |
| 1229 | 1161 | |
| 1162 | for (self.c_source_files.toSliceConst()) |c_source_file| { |
| 1163 | try zig_args.append("--c-source"); |
| 1164 | for (c_source_file.args) |arg| { |
| 1165 | try zig_args.append(arg); |
| 1166 | } |
| 1167 | try zig_args.append(self.builder.pathFromRoot(c_source_file.source_path)); |
| 1168 | } |
| 1169 | |
| 1230 | 1170 | if (self.build_options_contents.len() > 0) { |
| 1231 | 1171 | const build_options_file = try os.path.join( |
| 1232 | 1172 | builder.allocator, |
| ... | ... | @@ -1239,6 +1179,16 @@ pub const LibExeObjStep = struct { |
| 1239 | 1179 | try zig_args.append("--pkg-end"); |
| 1240 | 1180 | } |
| 1241 | 1181 | |
| 1182 | if (self.filter) |filter| { |
| 1183 | try zig_args.append("--test-filter"); |
| 1184 | try zig_args.append(filter); |
| 1185 | } |
| 1186 | |
| 1187 | if (self.name_prefix.len != 0) { |
| 1188 | try zig_args.append("--test-name-prefix"); |
| 1189 | try zig_args.append(self.name_prefix); |
| 1190 | } |
| 1191 | |
| 1242 | 1192 | for (self.object_files.toSliceConst()) |object_file| { |
| 1243 | 1193 | zig_args.append("--object") catch unreachable; |
| 1244 | 1194 | zig_args.append(builder.pathFromRoot(object_file)) catch unreachable; |
| ... | ... | @@ -1255,6 +1205,7 @@ pub const LibExeObjStep = struct { |
| 1255 | 1205 | if (builder.verbose_ir) zig_args.append("--verbose-ir") catch unreachable; |
| 1256 | 1206 | if (builder.verbose_llvm_ir) zig_args.append("--verbose-llvm-ir") catch unreachable; |
| 1257 | 1207 | if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable; |
| 1208 | if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable; |
| 1258 | 1209 | |
| 1259 | 1210 | if (self.strip) { |
| 1260 | 1211 | zig_args.append("--strip") catch unreachable; |
| ... | ... | @@ -1293,7 +1244,7 @@ pub const LibExeObjStep = struct { |
| 1293 | 1244 | zig_args.append("--ver-patch") catch unreachable; |
| 1294 | 1245 | zig_args.append(builder.fmt("{}", self.version.patch)) catch unreachable; |
| 1295 | 1246 | } |
| 1296 | | if (self.kind == Kind.Exe and self.static) { |
| 1247 | if ((self.kind == Kind.Exe or self.kind == Kind.Test) and self.static) { |
| 1297 | 1248 | zig_args.append("--static") catch unreachable; |
| 1298 | 1249 | } |
| 1299 | 1250 | |
| ... | ... | @@ -1325,11 +1276,16 @@ pub const LibExeObjStep = struct { |
| 1325 | 1276 | } |
| 1326 | 1277 | } |
| 1327 | 1278 | |
| 1328 | | if (!self.disable_libc) { |
| 1329 | | zig_args.append("--library") catch unreachable; |
| 1330 | | zig_args.append("c") catch unreachable; |
| 1279 | if (self.exec_cmd_args) |exec_cmd_args| { |
| 1280 | for (exec_cmd_args) |cmd_arg| { |
| 1281 | if (cmd_arg) |arg| { |
| 1282 | try zig_args.append("--test-cmd"); |
| 1283 | try zig_args.append(arg); |
| 1284 | } else { |
| 1285 | try zig_args.append("--test-cmd-bin"); |
| 1286 | } |
| 1287 | } |
| 1331 | 1288 | } |
| 1332 | | |
| 1333 | 1289 | for (self.packages.toSliceConst()) |pkg| { |
| 1334 | 1290 | zig_args.append("--pkg-begin") catch unreachable; |
| 1335 | 1291 | zig_args.append(pkg.name) catch unreachable; |
| ... | ... | @@ -1363,8 +1319,14 @@ pub const LibExeObjStep = struct { |
| 1363 | 1319 | } |
| 1364 | 1320 | |
| 1365 | 1321 | for (self.full_path_libs.toSliceConst()) |full_path_lib| { |
| 1366 | | zig_args.append("--library") catch unreachable; |
| 1367 | | zig_args.append(builder.pathFromRoot(full_path_lib)) catch unreachable; |
| 1322 | try zig_args.append("--library"); |
| 1323 | try zig_args.append(builder.pathFromRoot(full_path_lib)); |
| 1324 | |
| 1325 | const full_path_lib_abs = builder.pathFromRoot(full_path_lib); |
| 1326 | if (os.path.dirname(full_path_lib_abs)) |dirname| { |
| 1327 | try zig_args.append("-rpath"); |
| 1328 | try zig_args.append(dirname); |
| 1329 | } |
| 1368 | 1330 | } |
| 1369 | 1331 | |
| 1370 | 1332 | if (self.target.isDarwin()) { |
| ... | ... | @@ -1379,558 +1341,16 @@ pub const LibExeObjStep = struct { |
| 1379 | 1341 | try zig_args.append("--system-linker-hack"); |
| 1380 | 1342 | } |
| 1381 | 1343 | |
| 1382 | | try builder.spawnChild(zig_args.toSliceConst()); |
| 1383 | | |
| 1384 | | if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { |
| 1385 | | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename); |
| 1386 | | } |
| 1387 | | } |
| 1388 | | |
| 1389 | | fn appendCompileFlags(self: *LibExeObjStep, args: *ArrayList([]const u8)) void { |
| 1390 | | if (!self.strip) { |
| 1391 | | args.append("-g") catch unreachable; |
| 1392 | | } |
| 1393 | | switch (self.build_mode) { |
| 1394 | | builtin.Mode.Debug => { |
| 1395 | | if (self.disable_libc) { |
| 1396 | | args.append("-fno-stack-protector") catch unreachable; |
| 1397 | | } else { |
| 1398 | | args.append("-fstack-protector-strong") catch unreachable; |
| 1399 | | args.append("--param") catch unreachable; |
| 1400 | | args.append("ssp-buffer-size=4") catch unreachable; |
| 1401 | | } |
| 1402 | | }, |
| 1403 | | builtin.Mode.ReleaseSafe => { |
| 1404 | | args.append("-O2") catch unreachable; |
| 1405 | | if (self.disable_libc) { |
| 1406 | | args.append("-fno-stack-protector") catch unreachable; |
| 1407 | | } else { |
| 1408 | | args.append("-D_FORTIFY_SOURCE=2") catch unreachable; |
| 1409 | | args.append("-fstack-protector-strong") catch unreachable; |
| 1410 | | args.append("--param") catch unreachable; |
| 1411 | | args.append("ssp-buffer-size=4") catch unreachable; |
| 1412 | | } |
| 1413 | | }, |
| 1414 | | builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => { |
| 1415 | | args.append("-O2") catch unreachable; |
| 1416 | | args.append("-fno-stack-protector") catch unreachable; |
| 1417 | | }, |
| 1418 | | } |
| 1419 | | |
| 1420 | | for (self.include_dirs.toSliceConst()) |dir| { |
| 1421 | | args.append("-I") catch unreachable; |
| 1422 | | args.append(self.builder.pathFromRoot(dir)) catch unreachable; |
| 1423 | | } |
| 1424 | | |
| 1425 | | for (self.cflags.toSliceConst()) |cflag| { |
| 1426 | | args.append(cflag) catch unreachable; |
| 1427 | | } |
| 1428 | | |
| 1429 | | if (self.disable_libc) { |
| 1430 | | args.append("-nostdlib") catch unreachable; |
| 1431 | | } |
| 1432 | | } |
| 1433 | | |
| 1434 | | fn makeC(self: *LibExeObjStep) !void { |
| 1435 | | const builder = self.builder; |
| 1436 | | |
| 1437 | | const cc = builder.getCCExe(); |
| 1438 | | |
| 1439 | | assert(!self.is_zig); |
| 1440 | | |
| 1441 | | var cc_args = ArrayList([]const u8).init(builder.allocator); |
| 1442 | | defer cc_args.deinit(); |
| 1443 | | |
| 1444 | | cc_args.append(cc) catch unreachable; |
| 1445 | | |
| 1446 | | const is_darwin = self.target.isDarwin(); |
| 1447 | | |
| 1448 | | const c_std_arg = switch (self.c_std) { |
| 1449 | | Builder.CStd.C89 => "-std=c89", |
| 1450 | | Builder.CStd.C99 => "-std=c99", |
| 1451 | | Builder.CStd.C11 => "-std=c11", |
| 1452 | | }; |
| 1453 | | try cc_args.append(c_std_arg); |
| 1454 | | |
| 1455 | | switch (self.kind) { |
| 1456 | | Kind.Obj => { |
| 1457 | | cc_args.append("-c") catch unreachable; |
| 1458 | | cc_args.append(builder.pathFromRoot(self.object_src)) catch unreachable; |
| 1459 | | |
| 1460 | | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 1461 | | cc_args.append("-o") catch unreachable; |
| 1462 | | cc_args.append(output_path) catch unreachable; |
| 1463 | | |
| 1464 | | self.appendCompileFlags(&cc_args); |
| 1465 | | |
| 1466 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1467 | | }, |
| 1468 | | Kind.Lib => { |
| 1469 | | for (self.source_files.toSliceConst()) |source_file| { |
| 1470 | | cc_args.resize(0) catch unreachable; |
| 1471 | | cc_args.append(cc) catch unreachable; |
| 1472 | | |
| 1473 | | if (!self.static) { |
| 1474 | | cc_args.append("-fPIC") catch unreachable; |
| 1475 | | } |
| 1476 | | |
| 1477 | | const abs_source_file = builder.pathFromRoot(source_file); |
| 1478 | | cc_args.append("-c") catch unreachable; |
| 1479 | | cc_args.append(abs_source_file) catch unreachable; |
| 1480 | | |
| 1481 | | const cache_o_src = os.path.join( |
| 1482 | | builder.allocator, |
| 1483 | | [][]const u8{ builder.cache_root, source_file }, |
| 1484 | | ) catch unreachable; |
| 1485 | | if (os.path.dirname(cache_o_src)) |cache_o_dir| { |
| 1486 | | try builder.makePath(cache_o_dir); |
| 1487 | | } |
| 1488 | | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1489 | | cc_args.append("-o") catch unreachable; |
| 1490 | | cc_args.append(builder.pathFromRoot(cache_o_file)) catch unreachable; |
| 1491 | | |
| 1492 | | self.appendCompileFlags(&cc_args); |
| 1493 | | |
| 1494 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1495 | | |
| 1496 | | self.object_files.append(cache_o_file) catch unreachable; |
| 1497 | | } |
| 1498 | | |
| 1499 | | if (self.static) { |
| 1500 | | // ar |
| 1501 | | cc_args.resize(0) catch unreachable; |
| 1502 | | cc_args.append("ar") catch unreachable; |
| 1503 | | |
| 1504 | | cc_args.append("qc") catch unreachable; |
| 1505 | | |
| 1506 | | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 1507 | | cc_args.append(output_path) catch unreachable; |
| 1508 | | |
| 1509 | | for (self.object_files.toSliceConst()) |object_file| { |
| 1510 | | cc_args.append(builder.pathFromRoot(object_file)) catch unreachable; |
| 1511 | | } |
| 1512 | | |
| 1513 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1514 | | |
| 1515 | | // ranlib |
| 1516 | | cc_args.resize(0) catch unreachable; |
| 1517 | | cc_args.append("ranlib") catch unreachable; |
| 1518 | | cc_args.append(output_path) catch unreachable; |
| 1519 | | |
| 1520 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1521 | | } else { |
| 1522 | | cc_args.resize(0) catch unreachable; |
| 1523 | | cc_args.append(cc) catch unreachable; |
| 1524 | | |
| 1525 | | if (is_darwin) { |
| 1526 | | cc_args.append("-dynamiclib") catch unreachable; |
| 1527 | | |
| 1528 | | cc_args.append("-Wl,-headerpad_max_install_names") catch unreachable; |
| 1529 | | |
| 1530 | | cc_args.append("-compatibility_version") catch unreachable; |
| 1531 | | cc_args.append(builder.fmt("{}.0.0", self.version.major)) catch unreachable; |
| 1532 | | |
| 1533 | | cc_args.append("-current_version") catch unreachable; |
| 1534 | | cc_args.append(builder.fmt("{}.{}.{}", self.version.major, self.version.minor, self.version.patch)) catch unreachable; |
| 1535 | | |
| 1536 | | const install_name = builder.pathFromRoot(os.path.join( |
| 1537 | | builder.allocator, |
| 1538 | | [][]const u8{ builder.cache_root, self.major_only_filename }, |
| 1539 | | ) catch unreachable); |
| 1540 | | cc_args.append("-install_name") catch unreachable; |
| 1541 | | cc_args.append(install_name) catch unreachable; |
| 1542 | | } else { |
| 1543 | | cc_args.append("-fPIC") catch unreachable; |
| 1544 | | cc_args.append("-shared") catch unreachable; |
| 1545 | | |
| 1546 | | const soname_arg = builder.fmt("-Wl,-soname,lib{}.so.{d}", self.name, self.version.major); |
| 1547 | | defer builder.allocator.free(soname_arg); |
| 1548 | | cc_args.append(soname_arg) catch unreachable; |
| 1549 | | } |
| 1550 | | |
| 1551 | | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 1552 | | cc_args.append("-o") catch unreachable; |
| 1553 | | cc_args.append(output_path) catch unreachable; |
| 1554 | | |
| 1555 | | for (self.object_files.toSliceConst()) |object_file| { |
| 1556 | | cc_args.append(builder.pathFromRoot(object_file)) catch unreachable; |
| 1557 | | } |
| 1558 | | |
| 1559 | | if (!is_darwin) { |
| 1560 | | const rpath_arg = builder.fmt("-Wl,-rpath,{}", try os.path.realAlloc( |
| 1561 | | builder.allocator, |
| 1562 | | builder.pathFromRoot(builder.cache_root), |
| 1563 | | )); |
| 1564 | | defer builder.allocator.free(rpath_arg); |
| 1565 | | try cc_args.append(rpath_arg); |
| 1566 | | |
| 1567 | | try cc_args.append("-rdynamic"); |
| 1568 | | } |
| 1569 | | |
| 1570 | | for (self.full_path_libs.toSliceConst()) |full_path_lib| { |
| 1571 | | cc_args.append(builder.pathFromRoot(full_path_lib)) catch unreachable; |
| 1572 | | } |
| 1573 | | |
| 1574 | | { |
| 1575 | | var it = self.link_libs.iterator(); |
| 1576 | | while (it.next()) |entry| { |
| 1577 | | cc_args.append(builder.fmt("-l{}", entry.key)) catch unreachable; |
| 1578 | | } |
| 1579 | | } |
| 1580 | | |
| 1581 | | if (is_darwin and !self.static) { |
| 1582 | | var it = self.frameworks.iterator(); |
| 1583 | | while (it.next()) |entry| { |
| 1584 | | cc_args.append("-framework") catch unreachable; |
| 1585 | | cc_args.append(entry.key) catch unreachable; |
| 1586 | | } |
| 1587 | | } |
| 1588 | | |
| 1589 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1590 | | |
| 1591 | | if (self.target.wantSharedLibSymLinks()) { |
| 1592 | | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename); |
| 1593 | | } |
| 1594 | | } |
| 1595 | | }, |
| 1596 | | Kind.Exe => { |
| 1597 | | for (self.source_files.toSliceConst()) |source_file| { |
| 1598 | | cc_args.resize(0) catch unreachable; |
| 1599 | | cc_args.append(cc) catch unreachable; |
| 1600 | | |
| 1601 | | const abs_source_file = builder.pathFromRoot(source_file); |
| 1602 | | cc_args.append("-c") catch unreachable; |
| 1603 | | cc_args.append(abs_source_file) catch unreachable; |
| 1604 | | |
| 1605 | | const cache_o_src = os.path.join( |
| 1606 | | builder.allocator, |
| 1607 | | [][]const u8{ builder.cache_root, source_file }, |
| 1608 | | ) catch unreachable; |
| 1609 | | if (os.path.dirname(cache_o_src)) |cache_o_dir| { |
| 1610 | | try builder.makePath(cache_o_dir); |
| 1611 | | } |
| 1612 | | const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt()); |
| 1613 | | cc_args.append("-o") catch unreachable; |
| 1614 | | cc_args.append(builder.pathFromRoot(cache_o_file)) catch unreachable; |
| 1615 | | |
| 1616 | | for (self.cflags.toSliceConst()) |cflag| { |
| 1617 | | cc_args.append(cflag) catch unreachable; |
| 1618 | | } |
| 1619 | | |
| 1620 | | for (self.include_dirs.toSliceConst()) |dir| { |
| 1621 | | cc_args.append("-I") catch unreachable; |
| 1622 | | cc_args.append(builder.pathFromRoot(dir)) catch unreachable; |
| 1623 | | } |
| 1624 | | |
| 1625 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1626 | | |
| 1627 | | self.object_files.append(cache_o_file) catch unreachable; |
| 1628 | | } |
| 1629 | | |
| 1630 | | cc_args.resize(0) catch unreachable; |
| 1631 | | cc_args.append(cc) catch unreachable; |
| 1632 | | |
| 1633 | | for (self.object_files.toSliceConst()) |object_file| { |
| 1634 | | cc_args.append(builder.pathFromRoot(object_file)) catch unreachable; |
| 1635 | | } |
| 1636 | | |
| 1637 | | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 1638 | | cc_args.append("-o") catch unreachable; |
| 1639 | | cc_args.append(output_path) catch unreachable; |
| 1640 | | |
| 1641 | | const rpath_arg = builder.fmt("-Wl,-rpath,{}", try os.path.realAlloc( |
| 1642 | | builder.allocator, |
| 1643 | | builder.pathFromRoot(builder.cache_root), |
| 1644 | | )); |
| 1645 | | defer builder.allocator.free(rpath_arg); |
| 1646 | | try cc_args.append(rpath_arg); |
| 1647 | | |
| 1648 | | try cc_args.append("-rdynamic"); |
| 1649 | | |
| 1650 | | { |
| 1651 | | var it = self.link_libs.iterator(); |
| 1652 | | while (it.next()) |entry| { |
| 1653 | | cc_args.append(builder.fmt("-l{}", entry.key)) catch unreachable; |
| 1654 | | } |
| 1655 | | } |
| 1656 | | |
| 1657 | | if (is_darwin) { |
| 1658 | | if (self.need_flat_namespace_hack) { |
| 1659 | | cc_args.append("-Wl,-flat_namespace") catch unreachable; |
| 1660 | | } |
| 1661 | | cc_args.append("-Wl,-search_paths_first") catch unreachable; |
| 1662 | | } |
| 1663 | | |
| 1664 | | for (self.full_path_libs.toSliceConst()) |full_path_lib| { |
| 1665 | | cc_args.append(builder.pathFromRoot(full_path_lib)) catch unreachable; |
| 1666 | | } |
| 1667 | | |
| 1668 | | if (is_darwin) { |
| 1669 | | var it = self.frameworks.iterator(); |
| 1670 | | while (it.next()) |entry| { |
| 1671 | | cc_args.append("-framework") catch unreachable; |
| 1672 | | cc_args.append(entry.key) catch unreachable; |
| 1673 | | } |
| 1674 | | } |
| 1675 | | |
| 1676 | | try builder.spawnChild(cc_args.toSliceConst()); |
| 1677 | | }, |
| 1678 | | } |
| 1679 | | } |
| 1680 | | }; |
| 1681 | | |
| 1682 | | pub const TestStep = struct { |
| 1683 | | step: Step, |
| 1684 | | builder: *Builder, |
| 1685 | | root_src: []const u8, |
| 1686 | | build_mode: builtin.Mode, |
| 1687 | | verbose: bool, |
| 1688 | | link_libs: BufSet, |
| 1689 | | name_prefix: []const u8, |
| 1690 | | filter: ?[]const u8, |
| 1691 | | target: Target, |
| 1692 | | exec_cmd_args: ?[]const ?[]const u8, |
| 1693 | | include_dirs: ArrayList([]const u8), |
| 1694 | | lib_paths: ArrayList([]const u8), |
| 1695 | | packages: ArrayList(Pkg), |
| 1696 | | object_files: ArrayList([]const u8), |
| 1697 | | output_path: ?[]const u8, |
| 1698 | | system_linker_hack: bool, |
| 1699 | | override_std_dir: ?[]const u8, |
| 1700 | | |
| 1701 | | pub fn init(builder: *Builder, root_src: []const u8) TestStep { |
| 1702 | | const step_name = builder.fmt("test {}", root_src); |
| 1703 | | return TestStep{ |
| 1704 | | .step = Step.init(step_name, builder.allocator, make), |
| 1705 | | .builder = builder, |
| 1706 | | .root_src = root_src, |
| 1707 | | .build_mode = builtin.Mode.Debug, |
| 1708 | | .verbose = false, |
| 1709 | | .name_prefix = "", |
| 1710 | | .filter = null, |
| 1711 | | .link_libs = BufSet.init(builder.allocator), |
| 1712 | | .target = Target{ .Native = {} }, |
| 1713 | | .exec_cmd_args = null, |
| 1714 | | .include_dirs = ArrayList([]const u8).init(builder.allocator), |
| 1715 | | .lib_paths = ArrayList([]const u8).init(builder.allocator), |
| 1716 | | .packages = ArrayList(Pkg).init(builder.allocator), |
| 1717 | | .object_files = ArrayList([]const u8).init(builder.allocator), |
| 1718 | | .output_path = null, |
| 1719 | | .system_linker_hack = false, |
| 1720 | | .override_std_dir = null, |
| 1721 | | }; |
| 1722 | | } |
| 1723 | | |
| 1724 | | pub fn addLibPath(self: *TestStep, path: []const u8) void { |
| 1725 | | self.lib_paths.append(path) catch unreachable; |
| 1726 | | } |
| 1727 | | |
| 1728 | | pub fn addPackagePath(self: *TestStep, name: []const u8, pkg_index_path: []const u8) void { |
| 1729 | | self.packages.append(Pkg{ |
| 1730 | | .name = name, |
| 1731 | | .path = pkg_index_path, |
| 1732 | | }) catch unreachable; |
| 1733 | | } |
| 1734 | | |
| 1735 | | pub fn setVerbose(self: *TestStep, value: bool) void { |
| 1736 | | self.verbose = value; |
| 1737 | | } |
| 1738 | | |
| 1739 | | pub fn addIncludeDir(self: *TestStep, path: []const u8) void { |
| 1740 | | self.include_dirs.append(path) catch unreachable; |
| 1741 | | } |
| 1742 | | |
| 1743 | | pub fn setBuildMode(self: *TestStep, mode: builtin.Mode) void { |
| 1744 | | self.build_mode = mode; |
| 1745 | | } |
| 1746 | | |
| 1747 | | pub fn overrideStdDir(self: *TestStep, dir_path: []const u8) void { |
| 1748 | | self.override_std_dir = dir_path; |
| 1749 | | } |
| 1750 | | |
| 1751 | | pub fn setOutputPath(self: *TestStep, file_path: []const u8) void { |
| 1752 | | self.output_path = file_path; |
| 1753 | | |
| 1754 | | // catch a common mistake |
| 1755 | | if (mem.eql(u8, self.builder.pathFromRoot(file_path), self.builder.pathFromRoot("."))) { |
| 1756 | | debug.panic("setOutputPath wants a file path, not a directory\n"); |
| 1757 | | } |
| 1758 | | } |
| 1759 | | |
| 1760 | | pub fn getOutputPath(self: *TestStep) []const u8 { |
| 1761 | | if (self.output_path) |output_path| { |
| 1762 | | return output_path; |
| 1763 | | } else { |
| 1764 | | const basename = self.builder.fmt("test{}", self.target.exeFileExt()); |
| 1765 | | return os.path.join( |
| 1766 | | self.builder.allocator, |
| 1767 | | [][]const u8{ self.builder.cache_root, basename }, |
| 1768 | | ) catch unreachable; |
| 1769 | | } |
| 1770 | | } |
| 1771 | | |
| 1772 | | pub fn linkSystemLibrary(self: *TestStep, name: []const u8) void { |
| 1773 | | self.link_libs.put(name) catch unreachable; |
| 1774 | | } |
| 1775 | | |
| 1776 | | pub fn setNamePrefix(self: *TestStep, text: []const u8) void { |
| 1777 | | self.name_prefix = text; |
| 1778 | | } |
| 1779 | | |
| 1780 | | pub fn setFilter(self: *TestStep, text: ?[]const u8) void { |
| 1781 | | self.filter = text; |
| 1782 | | } |
| 1783 | | |
| 1784 | | pub fn addObject(self: *TestStep, obj: *LibExeObjStep) void { |
| 1785 | | assert(obj.kind == LibExeObjStep.Kind.Obj); |
| 1786 | | |
| 1787 | | self.step.dependOn(&obj.step); |
| 1788 | | |
| 1789 | | self.object_files.append(obj.getOutputPath()) catch unreachable; |
| 1790 | | |
| 1791 | | // TODO should be some kind of isolated directory that only has this header in it |
| 1792 | | self.include_dirs.append(self.builder.cache_root) catch unreachable; |
| 1793 | | } |
| 1794 | | |
| 1795 | | pub fn addObjectFile(self: *TestStep, path: []const u8) void { |
| 1796 | | self.object_files.append(path) catch unreachable; |
| 1797 | | } |
| 1798 | | |
| 1799 | | pub fn setTarget(self: *TestStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void { |
| 1800 | | self.target = Target{ |
| 1801 | | .Cross = CrossTarget{ |
| 1802 | | .arch = target_arch, |
| 1803 | | .os = target_os, |
| 1804 | | .environ = target_environ, |
| 1805 | | }, |
| 1806 | | }; |
| 1807 | | } |
| 1808 | | |
| 1809 | | pub fn setExecCmd(self: *TestStep, args: []const ?[]const u8) void { |
| 1810 | | self.exec_cmd_args = args; |
| 1811 | | } |
| 1812 | | |
| 1813 | | pub fn enableSystemLinkerHack(self: *TestStep) void { |
| 1814 | | self.system_linker_hack = true; |
| 1815 | | } |
| 1816 | | |
| 1817 | | fn make(step: *Step) !void { |
| 1818 | | const self = @fieldParentPtr(TestStep, "step", step); |
| 1819 | | const builder = self.builder; |
| 1820 | | |
| 1821 | | var zig_args = ArrayList([]const u8).init(builder.allocator); |
| 1822 | | defer zig_args.deinit(); |
| 1823 | | |
| 1824 | | try zig_args.append(builder.zig_exe); |
| 1825 | | |
| 1826 | | try zig_args.append("test"); |
| 1827 | | try zig_args.append(builder.pathFromRoot(self.root_src)); |
| 1828 | | |
| 1829 | | if (self.verbose) { |
| 1830 | | try zig_args.append("--verbose"); |
| 1831 | | } |
| 1832 | | |
| 1833 | | switch (self.build_mode) { |
| 1834 | | builtin.Mode.Debug => {}, |
| 1835 | | builtin.Mode.ReleaseSafe => try zig_args.append("--release-safe"), |
| 1836 | | builtin.Mode.ReleaseFast => try zig_args.append("--release-fast"), |
| 1837 | | builtin.Mode.ReleaseSmall => try zig_args.append("--release-small"), |
| 1838 | | } |
| 1839 | | |
| 1840 | | const output_path = builder.pathFromRoot(self.getOutputPath()); |
| 1841 | | try zig_args.append("--output"); |
| 1842 | | try zig_args.append(output_path); |
| 1843 | | |
| 1844 | | switch (self.target) { |
| 1845 | | Target.Native => {}, |
| 1846 | | Target.Cross => |cross_target| { |
| 1847 | | try zig_args.append("--target-arch"); |
| 1848 | | try zig_args.append(@tagName(cross_target.arch)); |
| 1849 | | |
| 1850 | | try zig_args.append("--target-os"); |
| 1851 | | try zig_args.append(@tagName(cross_target.os)); |
| 1852 | | |
| 1853 | | try zig_args.append("--target-environ"); |
| 1854 | | try zig_args.append(@tagName(cross_target.environ)); |
| 1855 | | }, |
| 1856 | | } |
| 1857 | | |
| 1858 | | if (self.filter) |filter| { |
| 1859 | | try zig_args.append("--test-filter"); |
| 1860 | | try zig_args.append(filter); |
| 1861 | | } |
| 1862 | | |
| 1863 | | if (self.name_prefix.len != 0) { |
| 1864 | | try zig_args.append("--test-name-prefix"); |
| 1865 | | try zig_args.append(self.name_prefix); |
| 1866 | | } |
| 1867 | | |
| 1868 | | for (self.object_files.toSliceConst()) |object_file| { |
| 1869 | | try zig_args.append("--object"); |
| 1870 | | try zig_args.append(builder.pathFromRoot(object_file)); |
| 1871 | | } |
| 1872 | | |
| 1873 | | { |
| 1874 | | var it = self.link_libs.iterator(); |
| 1875 | | while (true) { |
| 1876 | | const entry = it.next() orelse break; |
| 1877 | | try zig_args.append("--library"); |
| 1878 | | try zig_args.append(entry.key); |
| 1879 | | } |
| 1880 | | } |
| 1881 | | |
| 1882 | | if (self.exec_cmd_args) |exec_cmd_args| { |
| 1883 | | for (exec_cmd_args) |cmd_arg| { |
| 1884 | | if (cmd_arg) |arg| { |
| 1885 | | try zig_args.append("--test-cmd"); |
| 1886 | | try zig_args.append(arg); |
| 1887 | | } else { |
| 1888 | | try zig_args.append("--test-cmd-bin"); |
| 1889 | | } |
| 1890 | | } |
| 1891 | | } |
| 1892 | | |
| 1893 | | for (self.include_dirs.toSliceConst()) |include_path| { |
| 1894 | | try zig_args.append("-isystem"); |
| 1895 | | try zig_args.append(builder.pathFromRoot(include_path)); |
| 1896 | | } |
| 1897 | | |
| 1898 | | for (builder.include_paths.toSliceConst()) |include_path| { |
| 1899 | | try zig_args.append("-isystem"); |
| 1900 | | try zig_args.append(builder.pathFromRoot(include_path)); |
| 1901 | | } |
| 1902 | | |
| 1903 | | for (builder.rpaths.toSliceConst()) |rpath| { |
| 1904 | | try zig_args.append("-rpath"); |
| 1905 | | try zig_args.append(rpath); |
| 1906 | | } |
| 1907 | | |
| 1908 | | for (self.lib_paths.toSliceConst()) |lib_path| { |
| 1909 | | try zig_args.append("--library-path"); |
| 1910 | | try zig_args.append(lib_path); |
| 1911 | | } |
| 1912 | | |
| 1913 | | for (builder.lib_paths.toSliceConst()) |lib_path| { |
| 1914 | | try zig_args.append("--library-path"); |
| 1915 | | try zig_args.append(lib_path); |
| 1916 | | } |
| 1917 | | |
| 1918 | | for (self.packages.toSliceConst()) |pkg| { |
| 1919 | | zig_args.append("--pkg-begin") catch unreachable; |
| 1920 | | zig_args.append(pkg.name) catch unreachable; |
| 1921 | | zig_args.append(builder.pathFromRoot(pkg.path)) catch unreachable; |
| 1922 | | zig_args.append("--pkg-end") catch unreachable; |
| 1923 | | } |
| 1924 | | |
| 1925 | | if (self.system_linker_hack) { |
| 1926 | | try zig_args.append("--system-linker-hack"); |
| 1927 | | } |
| 1928 | 1344 | if (self.override_std_dir) |dir| { |
| 1929 | 1345 | try zig_args.append("--override-std-dir"); |
| 1930 | 1346 | try zig_args.append(builder.pathFromRoot(dir)); |
| 1931 | 1347 | } |
| 1932 | 1348 | |
| 1933 | 1349 | try builder.spawnChild(zig_args.toSliceConst()); |
| 1350 | |
| 1351 | if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) { |
| 1352 | try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename); |
| 1353 | } |
| 1934 | 1354 | } |
| 1935 | 1355 | }; |
| 1936 | 1356 | |
| ... | ... | @@ -1976,6 +1396,7 @@ const InstallArtifactStep = struct { |
| 1976 | 1396 | pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self { |
| 1977 | 1397 | const dest_dir = switch (artifact.kind) { |
| 1978 | 1398 | LibExeObjStep.Kind.Obj => unreachable, |
| 1399 | LibExeObjStep.Kind.Test => unreachable, |
| 1979 | 1400 | LibExeObjStep.Kind.Exe => builder.exe_dir, |
| 1980 | 1401 | LibExeObjStep.Kind.Lib => builder.lib_dir, |
| 1981 | 1402 | }; |
| ... | ... | @@ -2012,6 +1433,7 @@ const InstallArtifactStep = struct { |
| 2012 | 1433 | builtin.Os.windows => {}, |
| 2013 | 1434 | else => switch (self.artifact.kind) { |
| 2014 | 1435 | LibExeObjStep.Kind.Obj => unreachable, |
| 1436 | LibExeObjStep.Kind.Test => unreachable, |
| 2015 | 1437 | LibExeObjStep.Kind.Exe => u32(0o755), |
| 2016 | 1438 | LibExeObjStep.Kind.Lib => if (self.artifact.static) u32(0o666) else u32(0o755), |
| 2017 | 1439 | }, |