| ... | ... | @@ -22,12 +22,12 @@ const fmt_lib = std.fmt; |
| 22 | 22 | const File = std.fs.File; |
| 23 | 23 | const CrossTarget = std.zig.CrossTarget; |
| 24 | 24 | |
| 25 | | pub const FmtStep = @import("build/fmt.zig").FmtStep; |
| 26 | | pub const TranslateCStep = @import("build/translate_c.zig").TranslateCStep; |
| 27 | | pub const WriteFileStep = @import("build/write_file.zig").WriteFileStep; |
| 28 | | pub const RunStep = @import("build/run.zig").RunStep; |
| 29 | | pub const CheckFileStep = @import("build/check_file.zig").CheckFileStep; |
| 30 | | pub const InstallRawStep = @import("build/emit_raw.zig").InstallRawStep; |
| 25 | pub const FmtStep = @import("build/FmtStep.zig"); |
| 26 | pub const TranslateCStep = @import("build/TranslateCStep.zig"); |
| 27 | pub const WriteFileStep = @import("build/WriteFileStep.zig"); |
| 28 | pub const RunStep = @import("build/RunStep.zig"); |
| 29 | pub const CheckFileStep = @import("build/CheckFileStep.zig"); |
| 30 | pub const InstallRawStep = @import("build/InstallRawStep.zig"); |
| 31 | 31 | |
| 32 | 32 | pub const Builder = struct { |
| 33 | 33 | install_tls: TopLevelStep, |
| ... | ... | @@ -103,21 +103,23 @@ pub const Builder = struct { |
| 103 | 103 | }; |
| 104 | 104 | |
| 105 | 105 | const UserValue = union(enum) { |
| 106 | | Flag: void, |
| 107 | | Scalar: []const u8, |
| 108 | | List: ArrayList([]const u8), |
| 106 | flag: void, |
| 107 | scalar: []const u8, |
| 108 | list: ArrayList([]const u8), |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | 111 | const TypeId = enum { |
| 112 | | Bool, |
| 113 | | Int, |
| 114 | | Float, |
| 115 | | Enum, |
| 116 | | String, |
| 117 | | List, |
| 112 | bool, |
| 113 | int, |
| 114 | float, |
| 115 | @"enum", |
| 116 | string, |
| 117 | list, |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | 120 | const TopLevelStep = struct { |
| 121 | pub const base_id = .top_level; |
| 122 | |
| 121 | 123 | step: Step, |
| 122 | 124 | description: []const u8, |
| 123 | 125 | }; |
| ... | ... | @@ -163,18 +165,18 @@ pub const Builder = struct { |
| 163 | 165 | .dest_dir = env_map.get("DESTDIR"), |
| 164 | 166 | .installed_files = ArrayList(InstalledFile).init(allocator), |
| 165 | 167 | .install_tls = TopLevelStep{ |
| 166 | | .step = Step.initNoOp(.TopLevel, "install", allocator), |
| 168 | .step = Step.initNoOp(.top_level, "install", allocator), |
| 167 | 169 | .description = "Copy build artifacts to prefix path", |
| 168 | 170 | }, |
| 169 | 171 | .uninstall_tls = TopLevelStep{ |
| 170 | | .step = Step.init(.TopLevel, "uninstall", allocator, makeUninstall), |
| 172 | .step = Step.init(.top_level, "uninstall", allocator, makeUninstall), |
| 171 | 173 | .description = "Remove build artifacts from prefix path", |
| 172 | 174 | }, |
| 173 | 175 | .release_mode = null, |
| 174 | 176 | .is_release = false, |
| 175 | 177 | .override_lib_dir = null, |
| 176 | 178 | .install_path = undefined, |
| 177 | | .vcpkg_root = VcpkgRoot{ .Unattempted = {} }, |
| 179 | .vcpkg_root = VcpkgRoot{ .unattempted = {} }, |
| 178 | 180 | .args = null, |
| 179 | 181 | }; |
| 180 | 182 | try self.top_level_steps.append(&self.install_tls); |
| ... | ... | @@ -204,54 +206,27 @@ pub const Builder = struct { |
| 204 | 206 | self.h_dir = fs.path.join(self.allocator, &[_][]const u8{ self.install_path, "include" }) catch unreachable; |
| 205 | 207 | } |
| 206 | 208 | |
| 207 | | pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 208 | | return LibExeObjStep.createExecutable( |
| 209 | | self, |
| 210 | | name, |
| 211 | | if (root_src) |p| FileSource{ .path = p } else null, |
| 212 | | false, |
| 213 | | ); |
| 209 | fn convertOptionalPathToFileSource(path: ?[]const u8) ?FileSource { |
| 210 | return if (path) |p| |
| 211 | FileSource{ .path = p } |
| 212 | else |
| 213 | null; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | | pub fn addExecutableFromWriteFileStep( |
| 217 | | self: *Builder, |
| 218 | | name: []const u8, |
| 219 | | wfs: *WriteFileStep, |
| 220 | | basename: []const u8, |
| 221 | | ) *LibExeObjStep { |
| 222 | | return LibExeObjStep.createExecutable(self, name, @as(FileSource, .{ |
| 223 | | .write_file = .{ |
| 224 | | .step = wfs, |
| 225 | | .basename = basename, |
| 226 | | }, |
| 227 | | }), false); |
| 216 | pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 217 | return addExecutableSource(self, name, convertOptionalPathToFileSource(root_src), .static); |
| 228 | 218 | } |
| 229 | 219 | |
| 230 | | pub fn addExecutableSource( |
| 231 | | self: *Builder, |
| 232 | | name: []const u8, |
| 233 | | root_src: ?FileSource, |
| 234 | | ) *LibExeObjStep { |
| 235 | | return LibExeObjStep.createExecutable(self, name, root_src, false); |
| 220 | pub fn addExecutableSource(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: LibExeObjStep.Linkage) *LibExeObjStep { |
| 221 | return LibExeObjStep.createExecutable(builder, name, root_src, linkage); |
| 236 | 222 | } |
| 237 | 223 | |
| 238 | 224 | pub fn addObject(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 239 | | const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null; |
| 240 | | return LibExeObjStep.createObject(self, name, root_src_param); |
| 225 | return addObjectSource(self, name, convertOptionalPathToFileSource(root_src)); |
| 241 | 226 | } |
| 242 | 227 | |
| 243 | | pub fn addObjectFromWriteFileStep( |
| 244 | | self: *Builder, |
| 245 | | name: []const u8, |
| 246 | | wfs: *WriteFileStep, |
| 247 | | basename: []const u8, |
| 248 | | ) *LibExeObjStep { |
| 249 | | return LibExeObjStep.createObject(self, name, @as(FileSource, .{ |
| 250 | | .write_file = .{ |
| 251 | | .step = wfs, |
| 252 | | .basename = basename, |
| 253 | | }, |
| 254 | | })); |
| 228 | pub fn addObjectSource(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 229 | return LibExeObjStep.createObject(builder, name, root_src); |
| 255 | 230 | } |
| 256 | 231 | |
| 257 | 232 | pub fn addSharedLibrary( |
| ... | ... | @@ -260,64 +235,41 @@ pub const Builder = struct { |
| 260 | 235 | root_src: ?[]const u8, |
| 261 | 236 | kind: LibExeObjStep.SharedLibKind, |
| 262 | 237 | ) *LibExeObjStep { |
| 263 | | const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null; |
| 264 | | return LibExeObjStep.createSharedLibrary(self, name, root_src_param, kind); |
| 238 | return addSharedLibrarySource(self, name, convertOptionalPathToFileSource(root_src), kind); |
| 265 | 239 | } |
| 266 | 240 | |
| 267 | | pub fn addSharedLibraryFromWriteFileStep( |
| 241 | pub fn addSharedLibrarySource( |
| 268 | 242 | self: *Builder, |
| 269 | 243 | name: []const u8, |
| 270 | | wfs: *WriteFileStep, |
| 271 | | basename: []const u8, |
| 244 | root_src: ?FileSource, |
| 272 | 245 | kind: LibExeObjStep.SharedLibKind, |
| 273 | 246 | ) *LibExeObjStep { |
| 274 | | return LibExeObjStep.createSharedLibrary(self, name, @as(FileSource, .{ |
| 275 | | .write_file = .{ |
| 276 | | .step = wfs, |
| 277 | | .basename = basename, |
| 278 | | }, |
| 279 | | }), kind); |
| 247 | return LibExeObjStep.createSharedLibrary(self, name, root_src, kind); |
| 280 | 248 | } |
| 281 | 249 | |
| 282 | 250 | pub fn addStaticLibrary(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| 283 | | const root_src_param = if (root_src) |p| @as(FileSource, .{ .path = p }) else null; |
| 284 | | return LibExeObjStep.createStaticLibrary(self, name, root_src_param); |
| 251 | return addStaticLibrarySource(self, name, convertOptionalPathToFileSource(root_src)); |
| 285 | 252 | } |
| 286 | 253 | |
| 287 | | pub fn addStaticLibraryFromWriteFileStep( |
| 288 | | self: *Builder, |
| 289 | | name: []const u8, |
| 290 | | wfs: *WriteFileStep, |
| 291 | | basename: []const u8, |
| 292 | | ) *LibExeObjStep { |
| 293 | | return LibExeObjStep.createStaticLibrary(self, name, @as(FileSource, .{ |
| 294 | | .write_file = .{ |
| 295 | | .step = wfs, |
| 296 | | .basename = basename, |
| 297 | | }, |
| 298 | | })); |
| 254 | pub fn addStaticLibrarySource(self: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 255 | return LibExeObjStep.createStaticLibrary(self, name, root_src); |
| 299 | 256 | } |
| 300 | 257 | |
| 301 | 258 | pub fn addTest(self: *Builder, root_src: []const u8) *LibExeObjStep { |
| 302 | 259 | return LibExeObjStep.createTest(self, "test", .{ .path = root_src }); |
| 303 | 260 | } |
| 304 | 261 | |
| 305 | | pub fn addTestFromWriteFileStep( |
| 306 | | self: *Builder, |
| 307 | | wfs: *WriteFileStep, |
| 308 | | basename: []const u8, |
| 309 | | ) *LibExeObjStep { |
| 310 | | return LibExeObjStep.createTest(self, "test", @as(FileSource, .{ |
| 311 | | .write_file = .{ |
| 312 | | .step = wfs, |
| 313 | | .basename = basename, |
| 314 | | }, |
| 315 | | })); |
| 262 | pub fn addTestSource(self: *Builder, root_src: FileSource) *LibExeObjStep { |
| 263 | return LibExeObjStep.createTest(self, "test", root_src.dupe(self)); |
| 316 | 264 | } |
| 317 | 265 | |
| 318 | 266 | pub fn addAssemble(self: *Builder, name: []const u8, src: []const u8) *LibExeObjStep { |
| 267 | return addAssembleSource(self, name, .{ .path = src }); |
| 268 | } |
| 269 | |
| 270 | pub fn addAssembleSource(self: *Builder, name: []const u8, src: FileSource) *LibExeObjStep { |
| 319 | 271 | const obj_step = LibExeObjStep.createObject(self, name, null); |
| 320 | | obj_step.addAssemblyFile(src); |
| 272 | obj_step.addAssemblyFileSource(src.dupe(self)); |
| 321 | 273 | return obj_step; |
| 322 | 274 | } |
| 323 | 275 | |
| ... | ... | @@ -359,7 +311,7 @@ pub const Builder = struct { |
| 359 | 311 | pub fn dupePkg(self: *Builder, package: Pkg) Pkg { |
| 360 | 312 | var the_copy = Pkg{ |
| 361 | 313 | .name = self.dupe(package.name), |
| 362 | | .path = self.dupePath(package.path), |
| 314 | .path = package.path.dupe(self), |
| 363 | 315 | }; |
| 364 | 316 | |
| 365 | 317 | if (package.dependencies) |dependencies| { |
| ... | ... | @@ -403,7 +355,7 @@ pub const Builder = struct { |
| 403 | 355 | } |
| 404 | 356 | |
| 405 | 357 | pub fn addTranslateC(self: *Builder, source: FileSource) *TranslateCStep { |
| 406 | | return TranslateCStep.create(self, source); |
| 358 | return TranslateCStep.create(self, source.dupe(self)); |
| 407 | 359 | } |
| 408 | 360 | |
| 409 | 361 | pub fn version(self: *const Builder, major: u32, minor: u32, patch: u32) LibExeObjStep.SharedLibKind { |
| ... | ... | @@ -507,9 +459,9 @@ pub const Builder = struct { |
| 507 | 459 | const option_ptr = self.user_input_options.getPtr(name) orelse return null; |
| 508 | 460 | option_ptr.used = true; |
| 509 | 461 | switch (type_id) { |
| 510 | | .Bool => switch (option_ptr.value) { |
| 511 | | .Flag => return true, |
| 512 | | .Scalar => |s| { |
| 462 | .bool => switch (option_ptr.value) { |
| 463 | .flag => return true, |
| 464 | .scalar => |s| { |
| 513 | 465 | if (mem.eql(u8, s, "true")) { |
| 514 | 466 | return true; |
| 515 | 467 | } else if (mem.eql(u8, s, "false")) { |
| ... | ... | @@ -520,19 +472,19 @@ pub const Builder = struct { |
| 520 | 472 | return null; |
| 521 | 473 | } |
| 522 | 474 | }, |
| 523 | | .List => { |
| 475 | .list => { |
| 524 | 476 | warn("Expected -D{s} to be a boolean, but received a list.\n\n", .{name}); |
| 525 | 477 | self.markInvalidUserInput(); |
| 526 | 478 | return null; |
| 527 | 479 | }, |
| 528 | 480 | }, |
| 529 | | .Int => switch (option_ptr.value) { |
| 530 | | .Flag => { |
| 481 | .int => switch (option_ptr.value) { |
| 482 | .flag => { |
| 531 | 483 | warn("Expected -D{s} to be an integer, but received a boolean.\n\n", .{name}); |
| 532 | 484 | self.markInvalidUserInput(); |
| 533 | 485 | return null; |
| 534 | 486 | }, |
| 535 | | .Scalar => |s| { |
| 487 | .scalar => |s| { |
| 536 | 488 | const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) { |
| 537 | 489 | error.Overflow => { |
| 538 | 490 | warn("-D{s} value {s} cannot fit into type {s}.\n\n", .{ name, s, @typeName(T) }); |
| ... | ... | @@ -547,19 +499,19 @@ pub const Builder = struct { |
| 547 | 499 | }; |
| 548 | 500 | return n; |
| 549 | 501 | }, |
| 550 | | .List => { |
| 502 | .list => { |
| 551 | 503 | warn("Expected -D{s} to be an integer, but received a list.\n\n", .{name}); |
| 552 | 504 | self.markInvalidUserInput(); |
| 553 | 505 | return null; |
| 554 | 506 | }, |
| 555 | 507 | }, |
| 556 | | .Float => switch (option_ptr.value) { |
| 557 | | .Flag => { |
| 508 | .float => switch (option_ptr.value) { |
| 509 | .flag => { |
| 558 | 510 | warn("Expected -D{s} to be a float, but received a boolean.\n\n", .{name}); |
| 559 | 511 | self.markInvalidUserInput(); |
| 560 | 512 | return null; |
| 561 | 513 | }, |
| 562 | | .Scalar => |s| { |
| 514 | .scalar => |s| { |
| 563 | 515 | const n = std.fmt.parseFloat(T, s) catch |err| { |
| 564 | 516 | warn("Expected -D{s} to be a float of type {s}.\n\n", .{ name, @typeName(T) }); |
| 565 | 517 | self.markInvalidUserInput(); |
| ... | ... | @@ -567,19 +519,19 @@ pub const Builder = struct { |
| 567 | 519 | }; |
| 568 | 520 | return n; |
| 569 | 521 | }, |
| 570 | | .List => { |
| 522 | .list => { |
| 571 | 523 | warn("Expected -D{s} to be a float, but received a list.\n\n", .{name}); |
| 572 | 524 | self.markInvalidUserInput(); |
| 573 | 525 | return null; |
| 574 | 526 | }, |
| 575 | 527 | }, |
| 576 | | .Enum => switch (option_ptr.value) { |
| 577 | | .Flag => { |
| 528 | .@"enum" => switch (option_ptr.value) { |
| 529 | .flag => { |
| 578 | 530 | warn("Expected -D{s} to be a string, but received a boolean.\n\n", .{name}); |
| 579 | 531 | self.markInvalidUserInput(); |
| 580 | 532 | return null; |
| 581 | 533 | }, |
| 582 | | .Scalar => |s| { |
| 534 | .scalar => |s| { |
| 583 | 535 | if (std.meta.stringToEnum(T, s)) |enum_lit| { |
| 584 | 536 | return enum_lit; |
| 585 | 537 | } else { |
| ... | ... | @@ -588,35 +540,35 @@ pub const Builder = struct { |
| 588 | 540 | return null; |
| 589 | 541 | } |
| 590 | 542 | }, |
| 591 | | .List => { |
| 543 | .list => { |
| 592 | 544 | warn("Expected -D{s} to be a string, but received a list.\n\n", .{name}); |
| 593 | 545 | self.markInvalidUserInput(); |
| 594 | 546 | return null; |
| 595 | 547 | }, |
| 596 | 548 | }, |
| 597 | | .String => switch (option_ptr.value) { |
| 598 | | .Flag => { |
| 549 | .string => switch (option_ptr.value) { |
| 550 | .flag => { |
| 599 | 551 | warn("Expected -D{s} to be a string, but received a boolean.\n\n", .{name}); |
| 600 | 552 | self.markInvalidUserInput(); |
| 601 | 553 | return null; |
| 602 | 554 | }, |
| 603 | | .List => { |
| 555 | .list => { |
| 604 | 556 | warn("Expected -D{s} to be a string, but received a list.\n\n", .{name}); |
| 605 | 557 | self.markInvalidUserInput(); |
| 606 | 558 | return null; |
| 607 | 559 | }, |
| 608 | | .Scalar => |s| return s, |
| 560 | .scalar => |s| return s, |
| 609 | 561 | }, |
| 610 | | .List => switch (option_ptr.value) { |
| 611 | | .Flag => { |
| 562 | .list => switch (option_ptr.value) { |
| 563 | .flag => { |
| 612 | 564 | warn("Expected -D{s} to be a list, but received a boolean.\n\n", .{name}); |
| 613 | 565 | self.markInvalidUserInput(); |
| 614 | 566 | return null; |
| 615 | 567 | }, |
| 616 | | .Scalar => |s| { |
| 568 | .scalar => |s| { |
| 617 | 569 | return self.allocator.dupe([]const u8, &[_][]const u8{s}) catch unreachable; |
| 618 | 570 | }, |
| 619 | | .List => |lst| return lst.items, |
| 571 | .list => |lst| return lst.items, |
| 620 | 572 | }, |
| 621 | 573 | } |
| 622 | 574 | } |
| ... | ... | @@ -624,7 +576,7 @@ pub const Builder = struct { |
| 624 | 576 | pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step { |
| 625 | 577 | const step_info = self.allocator.create(TopLevelStep) catch unreachable; |
| 626 | 578 | step_info.* = TopLevelStep{ |
| 627 | | .step = Step.initNoOp(.TopLevel, name, self.allocator), |
| 579 | .step = Step.initNoOp(.top_level, name, self.allocator), |
| 628 | 580 | .description = self.dupe(description), |
| 629 | 581 | }; |
| 630 | 582 | self.top_level_steps.append(step_info) catch unreachable; |
| ... | ... | @@ -771,7 +723,7 @@ pub const Builder = struct { |
| 771 | 723 | if (!gop.found_existing) { |
| 772 | 724 | gop.value_ptr.* = UserInputOption{ |
| 773 | 725 | .name = name, |
| 774 | | .value = UserValue{ .Scalar = value }, |
| 726 | .value = .{ .scalar = value }, |
| 775 | 727 | .used = false, |
| 776 | 728 | }; |
| 777 | 729 | return false; |
| ... | ... | @@ -779,27 +731,27 @@ pub const Builder = struct { |
| 779 | 731 | |
| 780 | 732 | // option already exists |
| 781 | 733 | switch (gop.value_ptr.value) { |
| 782 | | UserValue.Scalar => |s| { |
| 734 | .scalar => |s| { |
| 783 | 735 | // turn it into a list |
| 784 | 736 | var list = ArrayList([]const u8).init(self.allocator); |
| 785 | 737 | list.append(s) catch unreachable; |
| 786 | 738 | list.append(value) catch unreachable; |
| 787 | | self.user_input_options.put(name, UserInputOption{ |
| 739 | self.user_input_options.put(name, .{ |
| 788 | 740 | .name = name, |
| 789 | | .value = UserValue{ .List = list }, |
| 741 | .value = .{ .list = list }, |
| 790 | 742 | .used = false, |
| 791 | 743 | }) catch unreachable; |
| 792 | 744 | }, |
| 793 | | UserValue.List => |*list| { |
| 745 | .list => |*list| { |
| 794 | 746 | // append to the list |
| 795 | 747 | list.append(value) catch unreachable; |
| 796 | | self.user_input_options.put(name, UserInputOption{ |
| 748 | self.user_input_options.put(name, .{ |
| 797 | 749 | .name = name, |
| 798 | | .value = UserValue{ .List = list.* }, |
| 750 | .value = .{ .list = list.* }, |
| 799 | 751 | .used = false, |
| 800 | 752 | }) catch unreachable; |
| 801 | 753 | }, |
| 802 | | UserValue.Flag => { |
| 754 | .flag => { |
| 803 | 755 | warn("Option '-D{s}={s}' conflicts with flag '-D{s}'.\n", .{ name, value, name }); |
| 804 | 756 | return true; |
| 805 | 757 | }, |
| ... | ... | @@ -811,9 +763,9 @@ pub const Builder = struct { |
| 811 | 763 | const name = self.dupe(name_raw); |
| 812 | 764 | const gop = try self.user_input_options.getOrPut(name); |
| 813 | 765 | if (!gop.found_existing) { |
| 814 | | gop.value_ptr.* = UserInputOption{ |
| 766 | gop.value_ptr.* = .{ |
| 815 | 767 | .name = name, |
| 816 | | .value = UserValue{ .Flag = {} }, |
| 768 | .value = .{ .flag = {} }, |
| 817 | 769 | .used = false, |
| 818 | 770 | }; |
| 819 | 771 | return false; |
| ... | ... | @@ -821,28 +773,28 @@ pub const Builder = struct { |
| 821 | 773 | |
| 822 | 774 | // option already exists |
| 823 | 775 | switch (gop.value_ptr.value) { |
| 824 | | UserValue.Scalar => |s| { |
| 776 | .scalar => |s| { |
| 825 | 777 | warn("Flag '-D{s}' conflicts with option '-D{s}={s}'.\n", .{ name, name, s }); |
| 826 | 778 | return true; |
| 827 | 779 | }, |
| 828 | | UserValue.List => { |
| 780 | .list => { |
| 829 | 781 | warn("Flag '-D{s}' conflicts with multiple options of the same name.\n", .{name}); |
| 830 | 782 | return true; |
| 831 | 783 | }, |
| 832 | | UserValue.Flag => {}, |
| 784 | .flag => {}, |
| 833 | 785 | } |
| 834 | 786 | return false; |
| 835 | 787 | } |
| 836 | 788 | |
| 837 | 789 | fn typeToEnum(comptime T: type) TypeId { |
| 838 | 790 | return switch (@typeInfo(T)) { |
| 839 | | .Int => .Int, |
| 840 | | .Float => .Float, |
| 841 | | .Bool => .Bool, |
| 842 | | .Enum => .Enum, |
| 791 | .Int => .int, |
| 792 | .Float => .float, |
| 793 | .Bool => .bool, |
| 794 | .Enum => .@"enum", |
| 843 | 795 | else => switch (T) { |
| 844 | | []const u8 => .String, |
| 845 | | []const []const u8 => .List, |
| 796 | []const u8 => .string, |
| 797 | []const []const u8 => .list, |
| 846 | 798 | else => @compileError("Unsupported type: " ++ @typeName(T)), |
| 847 | 799 | }, |
| 848 | 800 | }; |
| ... | ... | @@ -852,17 +804,6 @@ pub const Builder = struct { |
| 852 | 804 | self.invalid_user_input = true; |
| 853 | 805 | } |
| 854 | 806 | |
| 855 | | pub fn typeIdName(id: TypeId) []const u8 { |
| 856 | | return switch (id) { |
| 857 | | .Bool => "bool", |
| 858 | | .Int => "int", |
| 859 | | .Float => "float", |
| 860 | | .Enum => "enum", |
| 861 | | .String => "string", |
| 862 | | .List => "list", |
| 863 | | }; |
| 864 | | } |
| 865 | | |
| 866 | 807 | pub fn validateUserInputDidItFail(self: *Builder) bool { |
| 867 | 808 | // make sure all args are used |
| 868 | 809 | var it = self.user_input_options.iterator(); |
| ... | ... | @@ -938,7 +879,7 @@ pub const Builder = struct { |
| 938 | 879 | |
| 939 | 880 | ///`dest_rel_path` is relative to prefix path |
| 940 | 881 | pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 941 | | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path).step); |
| 882 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .prefix, dest_rel_path).step); |
| 942 | 883 | } |
| 943 | 884 | |
| 944 | 885 | pub fn installDirectory(self: *Builder, options: InstallDirectoryOptions) void { |
| ... | ... | @@ -947,12 +888,12 @@ pub const Builder = struct { |
| 947 | 888 | |
| 948 | 889 | ///`dest_rel_path` is relative to bin path |
| 949 | 890 | pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 950 | | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Bin, dest_rel_path).step); |
| 891 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .bin, dest_rel_path).step); |
| 951 | 892 | } |
| 952 | 893 | |
| 953 | 894 | ///`dest_rel_path` is relative to lib path |
| 954 | 895 | pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 955 | | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Lib, dest_rel_path).step); |
| 896 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .lib, dest_rel_path).step); |
| 956 | 897 | } |
| 957 | 898 | |
| 958 | 899 | pub fn installRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) void { |
| ... | ... | @@ -960,18 +901,18 @@ pub const Builder = struct { |
| 960 | 901 | } |
| 961 | 902 | |
| 962 | 903 | ///`dest_rel_path` is relative to install prefix path |
| 963 | | pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 964 | | return self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path); |
| 904 | pub fn addInstallFile(self: *Builder, source: FileSource, dest_rel_path: []const u8) *InstallFileStep { |
| 905 | return self.addInstallFileWithDir(source.dupe(self), .prefix, dest_rel_path); |
| 965 | 906 | } |
| 966 | 907 | |
| 967 | 908 | ///`dest_rel_path` is relative to bin path |
| 968 | | pub fn addInstallBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 969 | | return self.addInstallFileWithDir(src_path, .Bin, dest_rel_path); |
| 909 | pub fn addInstallBinFile(self: *Builder, source: FileSource, dest_rel_path: []const u8) *InstallFileStep { |
| 910 | return self.addInstallFileWithDir(source.dupe(self), .bin, dest_rel_path); |
| 970 | 911 | } |
| 971 | 912 | |
| 972 | 913 | ///`dest_rel_path` is relative to lib path |
| 973 | | pub fn addInstallLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 974 | | return self.addInstallFileWithDir(src_path, .Lib, dest_rel_path); |
| 914 | pub fn addInstallLibFile(self: *Builder, source: FileSource, dest_rel_path: []const u8) *InstallFileStep { |
| 915 | return self.addInstallFileWithDir(source.dupe(self), .lib, dest_rel_path); |
| 975 | 916 | } |
| 976 | 917 | |
| 977 | 918 | pub fn addInstallRaw(self: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *InstallRawStep { |
| ... | ... | @@ -980,7 +921,7 @@ pub const Builder = struct { |
| 980 | 921 | |
| 981 | 922 | pub fn addInstallFileWithDir( |
| 982 | 923 | self: *Builder, |
| 983 | | src_path: []const u8, |
| 924 | source: FileSource, |
| 984 | 925 | install_dir: InstallDir, |
| 985 | 926 | dest_rel_path: []const u8, |
| 986 | 927 | ) *InstallFileStep { |
| ... | ... | @@ -988,7 +929,7 @@ pub const Builder = struct { |
| 988 | 929 | panic("dest_rel_path must be non-empty", .{}); |
| 989 | 930 | } |
| 990 | 931 | const install_step = self.allocator.create(InstallFileStep) catch unreachable; |
| 991 | | install_step.* = InstallFileStep.init(self, src_path, install_dir, dest_rel_path); |
| 932 | install_step.* = InstallFileStep.init(self, source.dupe(self), install_dir, dest_rel_path); |
| 992 | 933 | return install_step; |
| 993 | 934 | } |
| 994 | 935 | |
| ... | ... | @@ -1169,11 +1110,11 @@ pub const Builder = struct { |
| 1169 | 1110 | pub fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 { |
| 1170 | 1111 | assert(!fs.path.isAbsolute(dest_rel_path)); // Install paths must be relative to the prefix |
| 1171 | 1112 | const base_dir = switch (dir) { |
| 1172 | | .Prefix => self.install_path, |
| 1173 | | .Bin => self.exe_dir, |
| 1174 | | .Lib => self.lib_dir, |
| 1175 | | .Header => self.h_dir, |
| 1176 | | .Custom => |path| fs.path.join(self.allocator, &[_][]const u8{ self.install_path, path }) catch unreachable, |
| 1113 | .prefix => self.install_path, |
| 1114 | .bin => self.exe_dir, |
| 1115 | .lib => self.lib_dir, |
| 1116 | .header => self.h_dir, |
| 1117 | .custom => |path| fs.path.join(self.allocator, &[_][]const u8{ self.install_path, path }) catch unreachable, |
| 1177 | 1118 | }; |
| 1178 | 1119 | return fs.path.resolve( |
| 1179 | 1120 | self.allocator, |
| ... | ... | @@ -1245,7 +1186,7 @@ pub const Target = std.zig.CrossTarget; |
| 1245 | 1186 | |
| 1246 | 1187 | pub const Pkg = struct { |
| 1247 | 1188 | name: []const u8, |
| 1248 | | path: []const u8, |
| 1189 | path: FileSource, |
| 1249 | 1190 | dependencies: ?[]const Pkg = null, |
| 1250 | 1191 | }; |
| 1251 | 1192 | |
| ... | ... | @@ -1284,40 +1225,72 @@ fn isLibCppLibrary(name: []const u8) bool { |
| 1284 | 1225 | return false; |
| 1285 | 1226 | } |
| 1286 | 1227 | |
| 1228 | /// A file that is generated by a build step. |
| 1229 | /// This struct is an interface that is meant to be used with `@fieldParentPtr` to implement the actual path logic. |
| 1230 | pub const GeneratedFile = struct { |
| 1231 | /// The step that generates the file |
| 1232 | step: *Step, |
| 1233 | |
| 1234 | /// The path to the generated file. Must be either absolute or relative to the build root. |
| 1235 | /// This value must be set in the `fn make()` of the `step` and must not be `null` afterwards. |
| 1236 | path: ?[]const u8 = null, |
| 1237 | |
| 1238 | pub fn getPath(self: GeneratedFile) []const u8 { |
| 1239 | return self.path orelse std.debug.panic( |
| 1240 | "getPath() was called on a GeneratedFile that wasn't build yet. Is there a missing Step dependency on step '{s}'?", |
| 1241 | .{self.step.name}, |
| 1242 | ); |
| 1243 | } |
| 1244 | }; |
| 1245 | |
| 1246 | /// A file source is a reference to an existing or future file. |
| 1247 | /// |
| 1287 | 1248 | pub const FileSource = union(enum) { |
| 1288 | | /// Relative to build root |
| 1249 | /// A plain file path, relative to build root or absolute. |
| 1289 | 1250 | path: []const u8, |
| 1290 | | write_file: struct { |
| 1291 | | step: *WriteFileStep, |
| 1292 | | basename: []const u8, |
| 1293 | | }, |
| 1294 | | translate_c: *TranslateCStep, |
| 1295 | 1251 | |
| 1252 | /// A file that is generated by an interface. Those files usually are |
| 1253 | /// not available until built by a build step. |
| 1254 | generated: *const GeneratedFile, |
| 1255 | |
| 1256 | /// Returns a new file source that will have a relative path to the build root guaranteed. |
| 1257 | /// This should be preferred over setting `.path` directly as it documents that the files are in the project directory. |
| 1258 | pub fn relative(path: []const u8) FileSource { |
| 1259 | std.debug.assert(!std.fs.path.isAbsolute(path)); |
| 1260 | return FileSource{ .path = path }; |
| 1261 | } |
| 1262 | |
| 1263 | /// Returns a string that can be shown to represent the file source. |
| 1264 | /// Either returns the path or `"generated"`. |
| 1265 | pub fn getDisplayName(self: FileSource) []const u8 { |
| 1266 | return switch (self) { |
| 1267 | .path => self.path, |
| 1268 | .generated => "generated", |
| 1269 | }; |
| 1270 | } |
| 1271 | |
| 1272 | /// Adds dependencies this file source implies to the given step. |
| 1296 | 1273 | pub fn addStepDependencies(self: FileSource, step: *Step) void { |
| 1297 | 1274 | switch (self) { |
| 1298 | 1275 | .path => {}, |
| 1299 | | .write_file => |wf| step.dependOn(&wf.step.step), |
| 1300 | | .translate_c => |tc| step.dependOn(&tc.step), |
| 1276 | .generated => |gen| step.dependOn(gen.step), |
| 1301 | 1277 | } |
| 1302 | 1278 | } |
| 1303 | 1279 | |
| 1304 | | /// Should only be called during make() |
| 1280 | /// Should only be called during make(), returns a path relative to the build root or absolute. |
| 1305 | 1281 | pub fn getPath(self: FileSource, builder: *Builder) []const u8 { |
| 1306 | | return switch (self) { |
| 1282 | const path = switch (self) { |
| 1307 | 1283 | .path => |p| builder.pathFromRoot(p), |
| 1308 | | .write_file => |wf| wf.step.getOutputPath(wf.basename), |
| 1309 | | .translate_c => |tc| tc.getOutputPath(), |
| 1284 | .generated => |gen| gen.getPath(), |
| 1310 | 1285 | }; |
| 1286 | return path; |
| 1311 | 1287 | } |
| 1312 | 1288 | |
| 1289 | /// Duplicates the file source for a given builder. |
| 1313 | 1290 | pub fn dupe(self: FileSource, b: *Builder) FileSource { |
| 1314 | 1291 | return switch (self) { |
| 1315 | | .path => |p| .{ .path = b.dupe(p) }, |
| 1316 | | .write_file => |wf| .{ .write_file = .{ |
| 1317 | | .step = wf.step, |
| 1318 | | .basename = b.dupe(wf.basename), |
| 1319 | | } }, |
| 1320 | | .translate_c => |tc| .{ .translate_c = tc }, |
| 1292 | .path => |p| .{ .path = b.dupePath(p) }, |
| 1293 | .generated => |gen| .{ .generated = gen }, |
| 1321 | 1294 | }; |
| 1322 | 1295 | } |
| 1323 | 1296 | }; |
| ... | ... | @@ -1327,21 +1300,22 @@ const BuildOptionArtifactArg = struct { |
| 1327 | 1300 | artifact: *LibExeObjStep, |
| 1328 | 1301 | }; |
| 1329 | 1302 | |
| 1330 | | const BuildOptionWriteFileArg = struct { |
| 1303 | const BuildOptionFileSourceArg = struct { |
| 1331 | 1304 | name: []const u8, |
| 1332 | | write_file: *WriteFileStep, |
| 1333 | | basename: []const u8, |
| 1305 | source: FileSource, |
| 1334 | 1306 | }; |
| 1335 | 1307 | |
| 1336 | 1308 | pub const LibExeObjStep = struct { |
| 1309 | pub const base_id = .lib_exe_obj; |
| 1310 | |
| 1337 | 1311 | step: Step, |
| 1338 | 1312 | builder: *Builder, |
| 1339 | 1313 | name: []const u8, |
| 1340 | 1314 | target: CrossTarget = CrossTarget{}, |
| 1341 | | linker_script: ?[]const u8 = null, |
| 1315 | linker_script: ?FileSource = null, |
| 1342 | 1316 | version_script: ?[]const u8 = null, |
| 1343 | 1317 | out_filename: []const u8, |
| 1344 | | is_dynamic: bool, |
| 1318 | linkage: Linkage, |
| 1345 | 1319 | version: ?Version, |
| 1346 | 1320 | build_mode: builtin.Mode, |
| 1347 | 1321 | kind: Kind, |
| ... | ... | @@ -1381,7 +1355,7 @@ pub const LibExeObjStep = struct { |
| 1381 | 1355 | packages: ArrayList(Pkg), |
| 1382 | 1356 | build_options_contents: std.ArrayList(u8), |
| 1383 | 1357 | build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg), |
| 1384 | | build_options_write_file_args: std.ArrayList(BuildOptionWriteFileArg), |
| 1358 | build_options_file_source_args: std.ArrayList(BuildOptionFileSourceArg), |
| 1385 | 1359 | |
| 1386 | 1360 | object_src: []const u8, |
| 1387 | 1361 | |
| ... | ... | @@ -1401,7 +1375,7 @@ pub const LibExeObjStep = struct { |
| 1401 | 1375 | /// Base address for an executable image. |
| 1402 | 1376 | image_base: ?u64 = null, |
| 1403 | 1377 | |
| 1404 | | libc_file: ?[]const u8 = null, |
| 1378 | libc_file: ?FileSource = null, |
| 1405 | 1379 | |
| 1406 | 1380 | valgrind_support: ?bool = null, |
| 1407 | 1381 | |
| ... | ... | @@ -1449,26 +1423,31 @@ pub const LibExeObjStep = struct { |
| 1449 | 1423 | |
| 1450 | 1424 | want_lto: ?bool = null, |
| 1451 | 1425 | |
| 1426 | output_path_source: GeneratedFile, |
| 1427 | output_lib_path_source: GeneratedFile, |
| 1428 | output_h_path_source: GeneratedFile, |
| 1429 | output_pdb_path_source: GeneratedFile, |
| 1430 | |
| 1452 | 1431 | const LinkObject = union(enum) { |
| 1453 | | StaticPath: []const u8, |
| 1454 | | OtherStep: *LibExeObjStep, |
| 1455 | | SystemLib: []const u8, |
| 1456 | | AssemblyFile: FileSource, |
| 1457 | | CSourceFile: *CSourceFile, |
| 1458 | | CSourceFiles: *CSourceFiles, |
| 1432 | static_path: FileSource, |
| 1433 | other_step: *LibExeObjStep, |
| 1434 | system_lib: []const u8, |
| 1435 | assembly_file: FileSource, |
| 1436 | c_source_file: *CSourceFile, |
| 1437 | c_source_files: *CSourceFiles, |
| 1459 | 1438 | }; |
| 1460 | 1439 | |
| 1461 | 1440 | const IncludeDir = union(enum) { |
| 1462 | | RawPath: []const u8, |
| 1463 | | RawPathSystem: []const u8, |
| 1464 | | OtherStep: *LibExeObjStep, |
| 1441 | raw_path: []const u8, |
| 1442 | raw_path_system: []const u8, |
| 1443 | other_step: *LibExeObjStep, |
| 1465 | 1444 | }; |
| 1466 | 1445 | |
| 1467 | 1446 | const Kind = enum { |
| 1468 | | Exe, |
| 1469 | | Lib, |
| 1470 | | Obj, |
| 1471 | | Test, |
| 1447 | exe, |
| 1448 | lib, |
| 1449 | obj, |
| 1450 | @"test", |
| 1472 | 1451 | }; |
| 1473 | 1452 | |
| 1474 | 1453 | const SharedLibKind = union(enum) { |
| ... | ... | @@ -1476,37 +1455,29 @@ pub const LibExeObjStep = struct { |
| 1476 | 1455 | unversioned: void, |
| 1477 | 1456 | }; |
| 1478 | 1457 | |
| 1458 | pub const Linkage = enum { dynamic, static }; |
| 1459 | |
| 1479 | 1460 | pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource, kind: SharedLibKind) *LibExeObjStep { |
| 1480 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1481 | | self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, switch (kind) { |
| 1461 | return initExtraArgs(builder, name, root_src, .lib, .dynamic, switch (kind) { |
| 1482 | 1462 | .versioned => |ver| ver, |
| 1483 | 1463 | .unversioned => null, |
| 1484 | 1464 | }); |
| 1485 | | return self; |
| 1486 | 1465 | } |
| 1487 | 1466 | |
| 1488 | 1467 | pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 1489 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1490 | | self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, null); |
| 1491 | | return self; |
| 1468 | return initExtraArgs(builder, name, root_src, .lib, .static, null); |
| 1492 | 1469 | } |
| 1493 | 1470 | |
| 1494 | 1471 | pub fn createObject(builder: *Builder, name: []const u8, root_src: ?FileSource) *LibExeObjStep { |
| 1495 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1496 | | self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, null); |
| 1497 | | return self; |
| 1472 | return initExtraArgs(builder, name, root_src, .obj, .static, null); |
| 1498 | 1473 | } |
| 1499 | 1474 | |
| 1500 | | pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, is_dynamic: bool) *LibExeObjStep { |
| 1501 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1502 | | self.* = initExtraArgs(builder, name, root_src, Kind.Exe, is_dynamic, null); |
| 1503 | | return self; |
| 1475 | pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?FileSource, linkage: Linkage) *LibExeObjStep { |
| 1476 | return initExtraArgs(builder, name, root_src, .exe, linkage, null); |
| 1504 | 1477 | } |
| 1505 | 1478 | |
| 1506 | 1479 | pub fn createTest(builder: *Builder, name: []const u8, root_src: FileSource) *LibExeObjStep { |
| 1507 | | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1508 | | self.* = initExtraArgs(builder, name, root_src, Kind.Test, false, null); |
| 1509 | | return self; |
| 1480 | return initExtraArgs(builder, name, root_src, .@"test", .static, null); |
| 1510 | 1481 | } |
| 1511 | 1482 | |
| 1512 | 1483 | fn initExtraArgs( |
| ... | ... | @@ -1514,26 +1485,28 @@ pub const LibExeObjStep = struct { |
| 1514 | 1485 | name_raw: []const u8, |
| 1515 | 1486 | root_src_raw: ?FileSource, |
| 1516 | 1487 | kind: Kind, |
| 1517 | | is_dynamic: bool, |
| 1488 | linkage: Linkage, |
| 1518 | 1489 | ver: ?Version, |
| 1519 | | ) LibExeObjStep { |
| 1490 | ) *LibExeObjStep { |
| 1520 | 1491 | const name = builder.dupe(name_raw); |
| 1521 | 1492 | const root_src: ?FileSource = if (root_src_raw) |rsrc| rsrc.dupe(builder) else null; |
| 1522 | 1493 | if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { |
| 1523 | 1494 | panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name}); |
| 1524 | 1495 | } |
| 1525 | | var self = LibExeObjStep{ |
| 1496 | |
| 1497 | const self = builder.allocator.create(LibExeObjStep) catch unreachable; |
| 1498 | self.* = LibExeObjStep{ |
| 1526 | 1499 | .strip = false, |
| 1527 | 1500 | .builder = builder, |
| 1528 | 1501 | .verbose_link = false, |
| 1529 | 1502 | .verbose_cc = false, |
| 1530 | 1503 | .build_mode = builtin.Mode.Debug, |
| 1531 | | .is_dynamic = is_dynamic, |
| 1504 | .linkage = linkage, |
| 1532 | 1505 | .kind = kind, |
| 1533 | 1506 | .root_src = root_src, |
| 1534 | 1507 | .name = name, |
| 1535 | 1508 | .frameworks = BufSet.init(builder.allocator), |
| 1536 | | .step = Step.init(.LibExeObj, name, builder.allocator, make), |
| 1509 | .step = Step.init(base_id, name, builder.allocator, make), |
| 1537 | 1510 | .version = ver, |
| 1538 | 1511 | .out_filename = undefined, |
| 1539 | 1512 | .out_h_filename = builder.fmt("{s}.h", .{name}), |
| ... | ... | @@ -1551,7 +1524,7 @@ pub const LibExeObjStep = struct { |
| 1551 | 1524 | .object_src = undefined, |
| 1552 | 1525 | .build_options_contents = std.ArrayList(u8).init(builder.allocator), |
| 1553 | 1526 | .build_options_artifact_args = std.ArrayList(BuildOptionArtifactArg).init(builder.allocator), |
| 1554 | | .build_options_write_file_args = std.ArrayList(BuildOptionWriteFileArg).init(builder.allocator), |
| 1527 | .build_options_file_source_args = std.ArrayList(BuildOptionFileSourceArg).init(builder.allocator), |
| 1555 | 1528 | .c_std = Builder.CStd.C99, |
| 1556 | 1529 | .override_lib_dir = null, |
| 1557 | 1530 | .main_pkg_path = null, |
| ... | ... | @@ -1567,6 +1540,11 @@ pub const LibExeObjStep = struct { |
| 1567 | 1540 | .override_dest_dir = null, |
| 1568 | 1541 | .installed_path = null, |
| 1569 | 1542 | .install_step = null, |
| 1543 | |
| 1544 | .output_path_source = GeneratedFile{ .step = &self.step }, |
| 1545 | .output_lib_path_source = GeneratedFile{ .step = &self.step }, |
| 1546 | .output_h_path_source = GeneratedFile{ .step = &self.step }, |
| 1547 | .output_pdb_path_source = GeneratedFile{ .step = &self.step }, |
| 1570 | 1548 | }; |
| 1571 | 1549 | self.computeOutFileNames(); |
| 1572 | 1550 | if (root_src) |rs| rs.addStepDependencies(&self.step); |
| ... | ... | @@ -1583,16 +1561,19 @@ pub const LibExeObjStep = struct { |
| 1583 | 1561 | .root_name = self.name, |
| 1584 | 1562 | .target = target, |
| 1585 | 1563 | .output_mode = switch (self.kind) { |
| 1586 | | .Lib => .Lib, |
| 1587 | | .Obj => .Obj, |
| 1588 | | .Exe, .Test => .Exe, |
| 1564 | .lib => .Lib, |
| 1565 | .obj => .Obj, |
| 1566 | .exe, .@"test" => .Exe, |
| 1567 | }, |
| 1568 | .link_mode = switch (self.linkage) { |
| 1569 | .dynamic => .Dynamic, |
| 1570 | .static => .Static, |
| 1589 | 1571 | }, |
| 1590 | | .link_mode = if (self.is_dynamic) .Dynamic else .Static, |
| 1591 | 1572 | .version = self.version, |
| 1592 | 1573 | }) catch unreachable; |
| 1593 | 1574 | |
| 1594 | | if (self.kind == .Lib) { |
| 1595 | | if (!self.is_dynamic) { |
| 1575 | if (self.kind == .lib) { |
| 1576 | if (self.linkage == .static) { |
| 1596 | 1577 | self.out_lib_filename = self.out_filename; |
| 1597 | 1578 | } else if (self.version) |version| { |
| 1598 | 1579 | if (target.isDarwin()) { |
| ... | ... | @@ -1618,6 +1599,13 @@ pub const LibExeObjStep = struct { |
| 1618 | 1599 | self.out_lib_filename = self.out_filename; |
| 1619 | 1600 | } |
| 1620 | 1601 | } |
| 1602 | if (self.output_dir != null) { |
| 1603 | self.output_lib_path_source.path = |
| 1604 | fs.path.join( |
| 1605 | self.builder.allocator, |
| 1606 | &[_][]const u8{ self.output_dir.?, self.out_lib_filename }, |
| 1607 | ) catch unreachable; |
| 1608 | } |
| 1621 | 1609 | } |
| 1622 | 1610 | } |
| 1623 | 1611 | |
| ... | ... | @@ -1641,7 +1629,7 @@ pub const LibExeObjStep = struct { |
| 1641 | 1629 | /// Creates a `RunStep` with an executable built with `addExecutable`. |
| 1642 | 1630 | /// Add command line arguments with `addArg`. |
| 1643 | 1631 | pub fn run(exe: *LibExeObjStep) *RunStep { |
| 1644 | | assert(exe.kind == Kind.Exe); |
| 1632 | assert(exe.kind == .exe); |
| 1645 | 1633 | |
| 1646 | 1634 | // It doesn't have to be native. We catch that if you actually try to run it. |
| 1647 | 1635 | // Consider that this is declarative; the run step may not be run unless a user |
| ... | ... | @@ -1656,8 +1644,8 @@ pub const LibExeObjStep = struct { |
| 1656 | 1644 | return run_step; |
| 1657 | 1645 | } |
| 1658 | 1646 | |
| 1659 | | pub fn setLinkerScriptPath(self: *LibExeObjStep, path: []const u8) void { |
| 1660 | | self.linker_script = self.builder.dupePath(path); |
| 1647 | pub fn setLinkerScriptPath(self: *LibExeObjStep, source: FileSource) void { |
| 1648 | self.linker_script = source.dupe(self.builder); |
| 1661 | 1649 | } |
| 1662 | 1650 | |
| 1663 | 1651 | pub fn linkFramework(self: *LibExeObjStep, framework_name: []const u8) void { |
| ... | ... | @@ -1676,7 +1664,7 @@ pub const LibExeObjStep = struct { |
| 1676 | 1664 | } |
| 1677 | 1665 | for (self.link_objects.items) |link_object| { |
| 1678 | 1666 | switch (link_object) { |
| 1679 | | LinkObject.SystemLib => |n| if (mem.eql(u8, n, name)) return true, |
| 1667 | .system_lib => |n| if (mem.eql(u8, n, name)) return true, |
| 1680 | 1668 | else => continue, |
| 1681 | 1669 | } |
| 1682 | 1670 | } |
| ... | ... | @@ -1684,31 +1672,31 @@ pub const LibExeObjStep = struct { |
| 1684 | 1672 | } |
| 1685 | 1673 | |
| 1686 | 1674 | pub fn linkLibrary(self: *LibExeObjStep, lib: *LibExeObjStep) void { |
| 1687 | | assert(lib.kind == Kind.Lib); |
| 1675 | assert(lib.kind == .lib); |
| 1688 | 1676 | self.linkLibraryOrObject(lib); |
| 1689 | 1677 | } |
| 1690 | 1678 | |
| 1691 | 1679 | pub fn isDynamicLibrary(self: *LibExeObjStep) bool { |
| 1692 | | return self.kind == Kind.Lib and self.is_dynamic; |
| 1680 | return self.kind == .lib and self.linkage == .dynamic; |
| 1693 | 1681 | } |
| 1694 | 1682 | |
| 1695 | 1683 | pub fn producesPdbFile(self: *LibExeObjStep) bool { |
| 1696 | 1684 | if (!self.target.isWindows() and !self.target.isUefi()) return false; |
| 1697 | 1685 | if (self.strip) return false; |
| 1698 | | return self.isDynamicLibrary() or self.kind == .Exe; |
| 1686 | return self.isDynamicLibrary() or self.kind == .exe; |
| 1699 | 1687 | } |
| 1700 | 1688 | |
| 1701 | 1689 | pub fn linkLibC(self: *LibExeObjStep) void { |
| 1702 | 1690 | if (!self.is_linking_libc) { |
| 1703 | 1691 | self.is_linking_libc = true; |
| 1704 | | self.link_objects.append(LinkObject{ .SystemLib = "c" }) catch unreachable; |
| 1692 | self.link_objects.append(.{ .system_lib = "c" }) catch unreachable; |
| 1705 | 1693 | } |
| 1706 | 1694 | } |
| 1707 | 1695 | |
| 1708 | 1696 | pub fn linkLibCpp(self: *LibExeObjStep) void { |
| 1709 | 1697 | if (!self.is_linking_libcpp) { |
| 1710 | 1698 | self.is_linking_libcpp = true; |
| 1711 | | self.link_objects.append(LinkObject{ .SystemLib = "c++" }) catch unreachable; |
| 1699 | self.link_objects.append(.{ .system_lib = "c++" }) catch unreachable; |
| 1712 | 1700 | } |
| 1713 | 1701 | } |
| 1714 | 1702 | |
| ... | ... | @@ -1720,7 +1708,7 @@ pub const LibExeObjStep = struct { |
| 1720 | 1708 | /// This one has no integration with anything, it just puts -lname on the command line. |
| 1721 | 1709 | /// Prefer to use `linkSystemLibrary` instead. |
| 1722 | 1710 | pub fn linkSystemLibraryName(self: *LibExeObjStep, name: []const u8) void { |
| 1723 | | self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable; |
| 1711 | self.link_objects.append(.{ .system_lib = self.builder.dupe(name) }) catch unreachable; |
| 1724 | 1712 | } |
| 1725 | 1713 | |
| 1726 | 1714 | /// This links against a system library, exclusively using pkg-config to find the library. |
| ... | ... | @@ -1840,12 +1828,12 @@ pub const LibExeObjStep = struct { |
| 1840 | 1828 | } |
| 1841 | 1829 | |
| 1842 | 1830 | pub fn setNamePrefix(self: *LibExeObjStep, text: []const u8) void { |
| 1843 | | assert(self.kind == Kind.Test); |
| 1831 | assert(self.kind == .@"test"); |
| 1844 | 1832 | self.name_prefix = self.builder.dupe(text); |
| 1845 | 1833 | } |
| 1846 | 1834 | |
| 1847 | 1835 | pub fn setFilter(self: *LibExeObjStep, text: ?[]const u8) void { |
| 1848 | | assert(self.kind == Kind.Test); |
| 1836 | assert(self.kind == .@"test"); |
| 1849 | 1837 | self.filter = if (text) |t| self.builder.dupe(t) else null; |
| 1850 | 1838 | } |
| 1851 | 1839 | |
| ... | ... | @@ -1860,7 +1848,7 @@ pub const LibExeObjStep = struct { |
| 1860 | 1848 | .files = files_copy, |
| 1861 | 1849 | .flags = flags_copy, |
| 1862 | 1850 | }; |
| 1863 | | self.link_objects.append(LinkObject{ .CSourceFiles = c_source_files }) catch unreachable; |
| 1851 | self.link_objects.append(.{ .c_source_files = c_source_files }) catch unreachable; |
| 1864 | 1852 | } |
| 1865 | 1853 | |
| 1866 | 1854 | pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, flags: []const []const u8) void { |
| ... | ... | @@ -1873,7 +1861,8 @@ pub const LibExeObjStep = struct { |
| 1873 | 1861 | pub fn addCSourceFileSource(self: *LibExeObjStep, source: CSourceFile) void { |
| 1874 | 1862 | const c_source_file = self.builder.allocator.create(CSourceFile) catch unreachable; |
| 1875 | 1863 | c_source_file.* = source.dupe(self.builder); |
| 1876 | | self.link_objects.append(LinkObject{ .CSourceFile = c_source_file }) catch unreachable; |
| 1864 | self.link_objects.append(.{ .c_source_file = c_source_file }) catch unreachable; |
| 1865 | source.source.addStepDependencies(&self.step); |
| 1877 | 1866 | } |
| 1878 | 1867 | |
| 1879 | 1868 | pub fn setVerboseLink(self: *LibExeObjStep, value: bool) void { |
| ... | ... | @@ -1896,78 +1885,60 @@ pub const LibExeObjStep = struct { |
| 1896 | 1885 | self.main_pkg_path = self.builder.dupePath(dir_path); |
| 1897 | 1886 | } |
| 1898 | 1887 | |
| 1899 | | pub fn setLibCFile(self: *LibExeObjStep, libc_file: ?[]const u8) void { |
| 1900 | | self.libc_file = if (libc_file) |f| self.builder.dupe(f) else null; |
| 1888 | pub fn setLibCFile(self: *LibExeObjStep, libc_file: ?FileSource) void { |
| 1889 | self.libc_file = if (libc_file) |f| f.dupe(self.builder) else null; |
| 1901 | 1890 | } |
| 1902 | 1891 | |
| 1903 | | /// Unless setOutputDir was called, this function must be called only in |
| 1904 | | /// the make step, from a step that has declared a dependency on this one. |
| 1892 | /// Returns the generated executable, library or object file. |
| 1905 | 1893 | /// To run an executable built with zig build, use `run`, or create an install step and invoke it. |
| 1906 | | pub fn getOutputPath(self: *LibExeObjStep) []const u8 { |
| 1907 | | return fs.path.join( |
| 1908 | | self.builder.allocator, |
| 1909 | | &[_][]const u8{ self.output_dir.?, self.out_filename }, |
| 1910 | | ) catch unreachable; |
| 1894 | pub fn getOutputSource(self: *LibExeObjStep) FileSource { |
| 1895 | return FileSource{ .generated = &self.output_path_source }; |
| 1911 | 1896 | } |
| 1912 | 1897 | |
| 1913 | | /// Unless setOutputDir was called, this function must be called only in |
| 1914 | | /// the make step, from a step that has declared a dependency on this one. |
| 1915 | | pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 { |
| 1916 | | assert(self.kind == Kind.Lib); |
| 1917 | | return fs.path.join( |
| 1918 | | self.builder.allocator, |
| 1919 | | &[_][]const u8{ self.output_dir.?, self.out_lib_filename }, |
| 1920 | | ) catch unreachable; |
| 1898 | /// Returns the generated import library. This function can only be called for libraries. |
| 1899 | pub fn getOutputLibSource(self: *LibExeObjStep) FileSource { |
| 1900 | assert(self.kind == .lib); |
| 1901 | return FileSource{ .generated = &self.output_lib_path_source }; |
| 1921 | 1902 | } |
| 1922 | 1903 | |
| 1923 | | /// Unless setOutputDir was called, this function must be called only in |
| 1924 | | /// the make step, from a step that has declared a dependency on this one. |
| 1925 | | pub fn getOutputHPath(self: *LibExeObjStep) []const u8 { |
| 1926 | | assert(self.kind != Kind.Exe); |
| 1904 | /// Returns the generated header file. |
| 1905 | /// This function can only be called for libraries or object files which have `emit_h` set. |
| 1906 | pub fn getOutputHSource(self: *LibExeObjStep) FileSource { |
| 1907 | assert(self.kind != .exe); |
| 1927 | 1908 | assert(self.emit_h); |
| 1928 | | return fs.path.join( |
| 1929 | | self.builder.allocator, |
| 1930 | | &[_][]const u8{ self.output_dir.?, self.out_h_filename }, |
| 1931 | | ) catch unreachable; |
| 1909 | return FileSource{ .generated = &self.output_h_path_source }; |
| 1932 | 1910 | } |
| 1933 | 1911 | |
| 1934 | | /// Unless setOutputDir was called, this function must be called only in |
| 1935 | | /// the make step, from a step that has declared a dependency on this one. |
| 1936 | | pub fn getOutputPdbPath(self: *LibExeObjStep) []const u8 { |
| 1912 | /// Returns the generated PDB file. This function can only be called for Windows and UEFI. |
| 1913 | pub fn getOutputPdbSource(self: *LibExeObjStep) FileSource { |
| 1914 | // TODO: Is this right? Isn't PDB for *any* PE/COFF file? |
| 1937 | 1915 | assert(self.target.isWindows() or self.target.isUefi()); |
| 1938 | | return fs.path.join( |
| 1939 | | self.builder.allocator, |
| 1940 | | &[_][]const u8{ self.output_dir.?, self.out_pdb_filename }, |
| 1941 | | ) catch unreachable; |
| 1916 | return FileSource{ .generated = &self.output_pdb_path_source }; |
| 1942 | 1917 | } |
| 1943 | 1918 | |
| 1944 | 1919 | pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void { |
| 1945 | | self.link_objects.append(LinkObject{ |
| 1946 | | .AssemblyFile = .{ .path = self.builder.dupe(path) }, |
| 1920 | self.link_objects.append(.{ |
| 1921 | .assembly_file = .{ .path = self.builder.dupe(path) }, |
| 1947 | 1922 | }) catch unreachable; |
| 1948 | 1923 | } |
| 1949 | 1924 | |
| 1950 | | pub fn addAssemblyFileFromWriteFileStep(self: *LibExeObjStep, wfs: *WriteFileStep, basename: []const u8) void { |
| 1951 | | self.addAssemblyFileSource(.{ |
| 1952 | | .write_file = .{ |
| 1953 | | .step = wfs, |
| 1954 | | .basename = self.builder.dupe(basename), |
| 1955 | | }, |
| 1956 | | }); |
| 1957 | | } |
| 1958 | | |
| 1959 | 1925 | pub fn addAssemblyFileSource(self: *LibExeObjStep, source: FileSource) void { |
| 1960 | 1926 | const source_duped = source.dupe(self.builder); |
| 1961 | | self.link_objects.append(LinkObject{ .AssemblyFile = source_duped }) catch unreachable; |
| 1927 | self.link_objects.append(.{ .assembly_file = source_duped }) catch unreachable; |
| 1962 | 1928 | source_duped.addStepDependencies(&self.step); |
| 1963 | 1929 | } |
| 1964 | 1930 | |
| 1965 | | pub fn addObjectFile(self: *LibExeObjStep, path: []const u8) void { |
| 1966 | | self.link_objects.append(LinkObject{ .StaticPath = self.builder.dupe(path) }) catch unreachable; |
| 1931 | pub fn addObjectFile(self: *LibExeObjStep, source_file: []const u8) void { |
| 1932 | self.addObjectFileSource(.{ .path = source_file }); |
| 1933 | } |
| 1934 | |
| 1935 | pub fn addObjectFileSource(self: *LibExeObjStep, source: FileSource) void { |
| 1936 | self.link_objects.append(.{ .static_path = source.dupe(self.builder) }) catch unreachable; |
| 1937 | source.addStepDependencies(&self.step); |
| 1967 | 1938 | } |
| 1968 | 1939 | |
| 1969 | 1940 | pub fn addObject(self: *LibExeObjStep, obj: *LibExeObjStep) void { |
| 1970 | | assert(obj.kind == Kind.Obj); |
| 1941 | assert(obj.kind == .obj); |
| 1971 | 1942 | self.linkLibraryOrObject(obj); |
| 1972 | 1943 | } |
| 1973 | 1944 | |
| ... | ... | @@ -2072,26 +2043,24 @@ pub const LibExeObjStep = struct { |
| 2072 | 2043 | /// The value is the path in the cache dir. |
| 2073 | 2044 | /// Adds a dependency automatically. |
| 2074 | 2045 | /// basename refers to the basename of the WriteFileStep |
| 2075 | | pub fn addBuildOptionWriteFile( |
| 2046 | pub fn addBuildOptionFileSource( |
| 2076 | 2047 | self: *LibExeObjStep, |
| 2077 | 2048 | name: []const u8, |
| 2078 | | write_file: *WriteFileStep, |
| 2079 | | basename: []const u8, |
| 2049 | source: FileSource, |
| 2080 | 2050 | ) void { |
| 2081 | | self.build_options_write_file_args.append(.{ |
| 2051 | self.build_options_file_source_args.append(.{ |
| 2082 | 2052 | .name = name, |
| 2083 | | .write_file = write_file, |
| 2084 | | .basename = basename, |
| 2053 | .source = source.dupe(self.builder), |
| 2085 | 2054 | }) catch unreachable; |
| 2086 | | self.step.dependOn(&write_file.step); |
| 2055 | source.addStepDependencies(&self.step); |
| 2087 | 2056 | } |
| 2088 | 2057 | |
| 2089 | 2058 | pub fn addSystemIncludeDir(self: *LibExeObjStep, path: []const u8) void { |
| 2090 | | self.include_dirs.append(IncludeDir{ .RawPathSystem = self.builder.dupe(path) }) catch unreachable; |
| 2059 | self.include_dirs.append(IncludeDir{ .raw_path_system = self.builder.dupe(path) }) catch unreachable; |
| 2091 | 2060 | } |
| 2092 | 2061 | |
| 2093 | 2062 | pub fn addIncludeDir(self: *LibExeObjStep, path: []const u8) void { |
| 2094 | | self.include_dirs.append(IncludeDir{ .RawPath = self.builder.dupe(path) }) catch unreachable; |
| 2063 | self.include_dirs.append(IncludeDir{ .raw_path = self.builder.dupe(path) }) catch unreachable; |
| 2095 | 2064 | } |
| 2096 | 2065 | |
| 2097 | 2066 | pub fn addLibPath(self: *LibExeObjStep, path: []const u8) void { |
| ... | ... | @@ -2108,43 +2077,53 @@ pub const LibExeObjStep = struct { |
| 2108 | 2077 | |
| 2109 | 2078 | pub fn addPackage(self: *LibExeObjStep, package: Pkg) void { |
| 2110 | 2079 | self.packages.append(self.builder.dupePkg(package)) catch unreachable; |
| 2080 | self.addRecursiveBuildDeps(package); |
| 2081 | } |
| 2082 | |
| 2083 | fn addRecursiveBuildDeps(self: *LibExeObjStep, package: Pkg) void { |
| 2084 | package.path.addStepDependencies(&self.step); |
| 2085 | if (package.dependencies) |deps| { |
| 2086 | for (deps) |dep| { |
| 2087 | self.addRecursiveBuildDeps(dep); |
| 2088 | } |
| 2089 | } |
| 2111 | 2090 | } |
| 2112 | 2091 | |
| 2113 | 2092 | pub fn addPackagePath(self: *LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void { |
| 2114 | | self.packages.append(Pkg{ |
| 2093 | self.addPackage(Pkg{ |
| 2115 | 2094 | .name = self.builder.dupe(name), |
| 2116 | | .path = self.builder.dupe(pkg_index_path), |
| 2117 | | }) catch unreachable; |
| 2095 | .path = .{ .path = self.builder.dupe(pkg_index_path) }, |
| 2096 | }); |
| 2118 | 2097 | } |
| 2119 | 2098 | |
| 2120 | 2099 | /// If Vcpkg was found on the system, it will be added to include and lib |
| 2121 | 2100 | /// paths for the specified target. |
| 2122 | | pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void { |
| 2101 | pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: LibExeObjStep.Linkage) !void { |
| 2123 | 2102 | // Ideally in the Unattempted case we would call the function recursively |
| 2124 | 2103 | // after findVcpkgRoot and have only one switch statement, but the compiler |
| 2125 | 2104 | // cannot resolve the error set. |
| 2126 | 2105 | switch (self.builder.vcpkg_root) { |
| 2127 | | .Unattempted => { |
| 2106 | .unattempted => { |
| 2128 | 2107 | self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root| |
| 2129 | | VcpkgRoot{ .Found = root } |
| 2108 | VcpkgRoot{ .found = root } |
| 2130 | 2109 | else |
| 2131 | | .NotFound; |
| 2110 | .not_found; |
| 2132 | 2111 | }, |
| 2133 | | .NotFound => return error.VcpkgNotFound, |
| 2134 | | .Found => {}, |
| 2112 | .not_found => return error.VcpkgNotFound, |
| 2113 | .found => {}, |
| 2135 | 2114 | } |
| 2136 | 2115 | |
| 2137 | 2116 | switch (self.builder.vcpkg_root) { |
| 2138 | | .Unattempted => unreachable, |
| 2139 | | .NotFound => return error.VcpkgNotFound, |
| 2140 | | .Found => |root| { |
| 2117 | .unattempted => unreachable, |
| 2118 | .not_found => return error.VcpkgNotFound, |
| 2119 | .found => |root| { |
| 2141 | 2120 | const allocator = self.builder.allocator; |
| 2142 | | const triplet = try self.target.vcpkgTriplet(allocator, linkage); |
| 2121 | const triplet = try self.target.vcpkgTriplet(allocator, if (linkage == .static) .Static else .Dynamic); |
| 2143 | 2122 | defer self.builder.allocator.free(triplet); |
| 2144 | 2123 | |
| 2145 | 2124 | const include_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "include" }); |
| 2146 | 2125 | errdefer allocator.free(include_path); |
| 2147 | | try self.include_dirs.append(IncludeDir{ .RawPath = include_path }); |
| 2126 | try self.include_dirs.append(IncludeDir{ .raw_path = include_path }); |
| 2148 | 2127 | |
| 2149 | 2128 | const lib_path = try fs.path.join(allocator, &[_][]const u8{ root, "installed", triplet, "lib" }); |
| 2150 | 2129 | try self.lib_paths.append(lib_path); |
| ... | ... | @@ -2155,7 +2134,7 @@ pub const LibExeObjStep = struct { |
| 2155 | 2134 | } |
| 2156 | 2135 | |
| 2157 | 2136 | pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void { |
| 2158 | | assert(self.kind == Kind.Test); |
| 2137 | assert(self.kind == .@"test"); |
| 2159 | 2138 | const duped_args = self.builder.allocator.alloc(?[]u8, args.len) catch unreachable; |
| 2160 | 2139 | for (args) |arg, i| { |
| 2161 | 2140 | duped_args[i] = if (arg) |a| self.builder.dupe(a) else null; |
| ... | ... | @@ -2165,13 +2144,19 @@ pub const LibExeObjStep = struct { |
| 2165 | 2144 | |
| 2166 | 2145 | fn linkLibraryOrObject(self: *LibExeObjStep, other: *LibExeObjStep) void { |
| 2167 | 2146 | self.step.dependOn(&other.step); |
| 2168 | | self.link_objects.append(LinkObject{ .OtherStep = other }) catch unreachable; |
| 2169 | | self.include_dirs.append(IncludeDir{ .OtherStep = other }) catch unreachable; |
| 2147 | self.link_objects.append(.{ .other_step = other }) catch unreachable; |
| 2148 | self.include_dirs.append(.{ .other_step = other }) catch unreachable; |
| 2149 | |
| 2150 | // BUG: The following code introduces a order-of-call dependency: |
| 2151 | // var lib = addSharedLibrary(...); |
| 2152 | // var exe = addExecutable(...); |
| 2153 | // exe.linkLibrary(lib); |
| 2154 | // lib.linkSystemLibrary("foobar"); // this will be ignored for exe! |
| 2170 | 2155 | |
| 2171 | 2156 | // Inherit dependency on system libraries |
| 2172 | 2157 | for (other.link_objects.items) |link_object| { |
| 2173 | 2158 | switch (link_object) { |
| 2174 | | .SystemLib => |name| self.linkSystemLibrary(name), |
| 2159 | .system_lib => |name| self.linkSystemLibrary(name), |
| 2175 | 2160 | else => continue, |
| 2176 | 2161 | } |
| 2177 | 2162 | } |
| ... | ... | @@ -2190,7 +2175,7 @@ pub const LibExeObjStep = struct { |
| 2190 | 2175 | |
| 2191 | 2176 | try zig_args.append("--pkg-begin"); |
| 2192 | 2177 | try zig_args.append(pkg.name); |
| 2193 | | try zig_args.append(builder.pathFromRoot(pkg.path)); |
| 2178 | try zig_args.append(builder.pathFromRoot(pkg.path.getPath(self.builder))); |
| 2194 | 2179 | |
| 2195 | 2180 | if (pkg.dependencies) |dependencies| { |
| 2196 | 2181 | for (dependencies) |sub_pkg| { |
| ... | ... | @@ -2216,10 +2201,10 @@ pub const LibExeObjStep = struct { |
| 2216 | 2201 | zig_args.append(builder.zig_exe) catch unreachable; |
| 2217 | 2202 | |
| 2218 | 2203 | const cmd = switch (self.kind) { |
| 2219 | | .Lib => "build-lib", |
| 2220 | | .Exe => "build-exe", |
| 2221 | | .Obj => "build-obj", |
| 2222 | | .Test => "test", |
| 2204 | .lib => "build-lib", |
| 2205 | .exe => "build-exe", |
| 2206 | .obj => "build-obj", |
| 2207 | .@"test" => "test", |
| 2223 | 2208 | }; |
| 2224 | 2209 | zig_args.append(cmd) catch unreachable; |
| 2225 | 2210 | |
| ... | ... | @@ -2238,21 +2223,19 @@ pub const LibExeObjStep = struct { |
| 2238 | 2223 | var prev_has_extra_flags = false; |
| 2239 | 2224 | for (self.link_objects.items) |link_object| { |
| 2240 | 2225 | switch (link_object) { |
| 2241 | | .StaticPath => |static_path| { |
| 2242 | | try zig_args.append(builder.pathFromRoot(static_path)); |
| 2243 | | }, |
| 2226 | .static_path => |static_path| try zig_args.append(static_path.getPath(builder)), |
| 2244 | 2227 | |
| 2245 | | .OtherStep => |other| switch (other.kind) { |
| 2246 | | .Exe => unreachable, |
| 2247 | | .Test => unreachable, |
| 2248 | | .Obj => { |
| 2249 | | try zig_args.append(other.getOutputPath()); |
| 2228 | .other_step => |other| switch (other.kind) { |
| 2229 | .exe => unreachable, |
| 2230 | .@"test" => unreachable, |
| 2231 | .obj => { |
| 2232 | try zig_args.append(other.getOutputSource().getPath(builder)); |
| 2250 | 2233 | }, |
| 2251 | | .Lib => { |
| 2252 | | const full_path_lib = other.getOutputLibPath(); |
| 2234 | .lib => { |
| 2235 | const full_path_lib = other.getOutputLibSource().getPath(builder); |
| 2253 | 2236 | try zig_args.append(full_path_lib); |
| 2254 | 2237 | |
| 2255 | | if (other.is_dynamic and !self.target.isWindows()) { |
| 2238 | if (other.linkage == .dynamic and !self.target.isWindows()) { |
| 2256 | 2239 | if (fs.path.dirname(full_path_lib)) |dirname| { |
| 2257 | 2240 | try zig_args.append("-rpath"); |
| 2258 | 2241 | try zig_args.append(dirname); |
| ... | ... | @@ -2260,10 +2243,11 @@ pub const LibExeObjStep = struct { |
| 2260 | 2243 | } |
| 2261 | 2244 | }, |
| 2262 | 2245 | }, |
| 2263 | | .SystemLib => |name| { |
| 2246 | .system_lib => |name| { |
| 2264 | 2247 | try zig_args.append(builder.fmt("-l{s}", .{name})); |
| 2265 | 2248 | }, |
| 2266 | | .AssemblyFile => |asm_file| { |
| 2249 | |
| 2250 | .assembly_file => |asm_file| { |
| 2267 | 2251 | if (prev_has_extra_flags) { |
| 2268 | 2252 | try zig_args.append("-extra-cflags"); |
| 2269 | 2253 | try zig_args.append("--"); |
| ... | ... | @@ -2272,7 +2256,7 @@ pub const LibExeObjStep = struct { |
| 2272 | 2256 | try zig_args.append(asm_file.getPath(builder)); |
| 2273 | 2257 | }, |
| 2274 | 2258 | |
| 2275 | | .CSourceFile => |c_source_file| { |
| 2259 | .c_source_file => |c_source_file| { |
| 2276 | 2260 | if (c_source_file.args.len == 0) { |
| 2277 | 2261 | if (prev_has_extra_flags) { |
| 2278 | 2262 | try zig_args.append("-cflags"); |
| ... | ... | @@ -2289,7 +2273,7 @@ pub const LibExeObjStep = struct { |
| 2289 | 2273 | try zig_args.append(c_source_file.source.getPath(builder)); |
| 2290 | 2274 | }, |
| 2291 | 2275 | |
| 2292 | | .CSourceFiles => |c_source_files| { |
| 2276 | .c_source_files => |c_source_files| { |
| 2293 | 2277 | if (c_source_files.flags.len == 0) { |
| 2294 | 2278 | if (prev_has_extra_flags) { |
| 2295 | 2279 | try zig_args.append("-cflags"); |
| ... | ... | @@ -2312,7 +2296,7 @@ pub const LibExeObjStep = struct { |
| 2312 | 2296 | |
| 2313 | 2297 | if (self.build_options_contents.items.len > 0 or |
| 2314 | 2298 | self.build_options_artifact_args.items.len > 0 or |
| 2315 | | self.build_options_write_file_args.items.len > 0) |
| 2299 | self.build_options_file_source_args.items.len > 0) |
| 2316 | 2300 | { |
| 2317 | 2301 | // Render build artifact and write file options at the last minute, now that the path is known. |
| 2318 | 2302 | // |
| ... | ... | @@ -2322,14 +2306,14 @@ pub const LibExeObjStep = struct { |
| 2322 | 2306 | self.addBuildOption( |
| 2323 | 2307 | []const u8, |
| 2324 | 2308 | item.name, |
| 2325 | | self.builder.pathFromRoot(item.artifact.getOutputPath()), |
| 2309 | self.builder.pathFromRoot(item.artifact.getOutputSource().getPath(self.builder)), |
| 2326 | 2310 | ); |
| 2327 | 2311 | } |
| 2328 | | for (self.build_options_write_file_args.items) |item| { |
| 2312 | for (self.build_options_file_source_args.items) |item| { |
| 2329 | 2313 | self.addBuildOption( |
| 2330 | 2314 | []const u8, |
| 2331 | 2315 | item.name, |
| 2332 | | self.builder.pathFromRoot(item.write_file.getOutputPath(item.basename)), |
| 2316 | item.source.getPath(self.builder), |
| 2333 | 2317 | ); |
| 2334 | 2318 | } |
| 2335 | 2319 | |
| ... | ... | @@ -2400,7 +2384,7 @@ pub const LibExeObjStep = struct { |
| 2400 | 2384 | |
| 2401 | 2385 | if (self.libc_file) |libc_file| { |
| 2402 | 2386 | try zig_args.append("--libc"); |
| 2403 | | try zig_args.append(builder.pathFromRoot(libc_file)); |
| 2387 | try zig_args.append(libc_file.getPath(self.builder)); |
| 2404 | 2388 | } |
| 2405 | 2389 | |
| 2406 | 2390 | switch (self.build_mode) { |
| ... | ... | @@ -2417,13 +2401,13 @@ pub const LibExeObjStep = struct { |
| 2417 | 2401 | zig_args.append("--name") catch unreachable; |
| 2418 | 2402 | zig_args.append(self.name) catch unreachable; |
| 2419 | 2403 | |
| 2420 | | if (self.kind == Kind.Lib and self.is_dynamic) { |
| 2404 | if (self.kind == .lib and self.linkage == .dynamic) { |
| 2421 | 2405 | if (self.version) |version| { |
| 2422 | 2406 | zig_args.append("--version") catch unreachable; |
| 2423 | 2407 | zig_args.append(builder.fmt("{}", .{version})) catch unreachable; |
| 2424 | 2408 | } |
| 2425 | 2409 | } |
| 2426 | | if (self.is_dynamic) { |
| 2410 | if (self.linkage == .dynamic) { |
| 2427 | 2411 | try zig_args.append("-dynamic"); |
| 2428 | 2412 | } |
| 2429 | 2413 | if (self.bundle_compiler_rt) |x| { |
| ... | ... | @@ -2502,7 +2486,7 @@ pub const LibExeObjStep = struct { |
| 2502 | 2486 | |
| 2503 | 2487 | if (self.linker_script) |linker_script| { |
| 2504 | 2488 | try zig_args.append("--script"); |
| 2505 | | try zig_args.append(builder.pathFromRoot(linker_script)); |
| 2489 | try zig_args.append(linker_script.getPath(builder)); |
| 2506 | 2490 | } |
| 2507 | 2491 | |
| 2508 | 2492 | if (self.version_script) |version_script| { |
| ... | ... | @@ -2577,16 +2561,16 @@ pub const LibExeObjStep = struct { |
| 2577 | 2561 | |
| 2578 | 2562 | for (self.include_dirs.items) |include_dir| { |
| 2579 | 2563 | switch (include_dir) { |
| 2580 | | .RawPath => |include_path| { |
| 2564 | .raw_path => |include_path| { |
| 2581 | 2565 | try zig_args.append("-I"); |
| 2582 | 2566 | try zig_args.append(self.builder.pathFromRoot(include_path)); |
| 2583 | 2567 | }, |
| 2584 | | .RawPathSystem => |include_path| { |
| 2568 | .raw_path_system => |include_path| { |
| 2585 | 2569 | try zig_args.append("-isystem"); |
| 2586 | 2570 | try zig_args.append(self.builder.pathFromRoot(include_path)); |
| 2587 | 2571 | }, |
| 2588 | | .OtherStep => |other| if (other.emit_h) { |
| 2589 | | const h_path = other.getOutputHPath(); |
| 2572 | .other_step => |other| if (other.emit_h) { |
| 2573 | const h_path = other.getOutputHSource().getPath(self.builder); |
| 2590 | 2574 | try zig_args.append("-isystem"); |
| 2591 | 2575 | try zig_args.append(fs.path.dirname(h_path).?); |
| 2592 | 2576 | }, |
| ... | ... | @@ -2691,7 +2675,7 @@ pub const LibExeObjStep = struct { |
| 2691 | 2675 | }); |
| 2692 | 2676 | } |
| 2693 | 2677 | |
| 2694 | | if (self.kind == Kind.Test) { |
| 2678 | if (self.kind == .@"test") { |
| 2695 | 2679 | try builder.spawnChild(zig_args.items); |
| 2696 | 2680 | } else { |
| 2697 | 2681 | try zig_args.append("--enable-cache"); |
| ... | ... | @@ -2726,13 +2710,43 @@ pub const LibExeObjStep = struct { |
| 2726 | 2710 | } |
| 2727 | 2711 | } |
| 2728 | 2712 | |
| 2729 | | if (self.kind == Kind.Lib and self.is_dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { |
| 2730 | | try doAtomicSymLinks(builder.allocator, self.getOutputPath(), self.major_only_filename.?, self.name_only_filename.?); |
| 2713 | // This will ensure all output filenames will now have the output_dir available! |
| 2714 | self.computeOutFileNames(); |
| 2715 | |
| 2716 | // Update generated files |
| 2717 | if (self.output_dir != null) { |
| 2718 | self.output_path_source.path = |
| 2719 | fs.path.join( |
| 2720 | self.builder.allocator, |
| 2721 | &[_][]const u8{ self.output_dir.?, self.out_filename }, |
| 2722 | ) catch unreachable; |
| 2723 | |
| 2724 | if (self.emit_h) { |
| 2725 | self.output_h_path_source.path = |
| 2726 | fs.path.join( |
| 2727 | self.builder.allocator, |
| 2728 | &[_][]const u8{ self.output_dir.?, self.out_h_filename }, |
| 2729 | ) catch unreachable; |
| 2730 | } |
| 2731 | |
| 2732 | if (self.target.isWindows() or self.target.isUefi()) { |
| 2733 | self.output_pdb_path_source.path = |
| 2734 | fs.path.join( |
| 2735 | self.builder.allocator, |
| 2736 | &[_][]const u8{ self.output_dir.?, self.out_pdb_filename }, |
| 2737 | ) catch unreachable; |
| 2738 | } |
| 2739 | } |
| 2740 | |
| 2741 | if (self.kind == .lib and self.linkage == .dynamic and self.version != null and self.target.wantSharedLibSymLinks()) { |
| 2742 | try doAtomicSymLinks(builder.allocator, self.getOutputSource().getPath(builder), self.major_only_filename.?, self.name_only_filename.?); |
| 2731 | 2743 | } |
| 2732 | 2744 | } |
| 2733 | 2745 | }; |
| 2734 | 2746 | |
| 2735 | 2747 | pub const InstallArtifactStep = struct { |
| 2748 | pub const base_id = .install_artifact; |
| 2749 | |
| 2736 | 2750 | step: Step, |
| 2737 | 2751 | builder: *Builder, |
| 2738 | 2752 | artifact: *LibExeObjStep, |
| ... | ... | @@ -2748,22 +2762,22 @@ pub const InstallArtifactStep = struct { |
| 2748 | 2762 | const self = builder.allocator.create(Self) catch unreachable; |
| 2749 | 2763 | self.* = Self{ |
| 2750 | 2764 | .builder = builder, |
| 2751 | | .step = Step.init(.InstallArtifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), |
| 2765 | .step = Step.init(.install_artifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make), |
| 2752 | 2766 | .artifact = artifact, |
| 2753 | 2767 | .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { |
| 2754 | | .Obj => unreachable, |
| 2755 | | .Test => unreachable, |
| 2756 | | .Exe => InstallDir{ .Bin = {} }, |
| 2757 | | .Lib => InstallDir{ .Lib = {} }, |
| 2768 | .obj => unreachable, |
| 2769 | .@"test" => unreachable, |
| 2770 | .exe => InstallDir{ .bin = {} }, |
| 2771 | .lib => InstallDir{ .lib = {} }, |
| 2758 | 2772 | }, |
| 2759 | 2773 | .pdb_dir = if (artifact.producesPdbFile()) blk: { |
| 2760 | | if (artifact.kind == .Exe) { |
| 2761 | | break :blk InstallDir{ .Bin = {} }; |
| 2774 | if (artifact.kind == .exe) { |
| 2775 | break :blk InstallDir{ .bin = {} }; |
| 2762 | 2776 | } else { |
| 2763 | | break :blk InstallDir{ .Lib = {} }; |
| 2777 | break :blk InstallDir{ .lib = {} }; |
| 2764 | 2778 | } |
| 2765 | 2779 | } else null, |
| 2766 | | .h_dir = if (artifact.kind == .Lib and artifact.emit_h) .Header else null, |
| 2780 | .h_dir = if (artifact.kind == .lib and artifact.emit_h) .header else null, |
| 2767 | 2781 | }; |
| 2768 | 2782 | self.step.dependOn(&artifact.step); |
| 2769 | 2783 | artifact.install_step = self; |
| ... | ... | @@ -2771,13 +2785,13 @@ pub const InstallArtifactStep = struct { |
| 2771 | 2785 | builder.pushInstalledFile(self.dest_dir, artifact.out_filename); |
| 2772 | 2786 | if (self.artifact.isDynamicLibrary()) { |
| 2773 | 2787 | if (artifact.major_only_filename) |name| { |
| 2774 | | builder.pushInstalledFile(.Lib, name); |
| 2788 | builder.pushInstalledFile(.lib, name); |
| 2775 | 2789 | } |
| 2776 | 2790 | if (artifact.name_only_filename) |name| { |
| 2777 | | builder.pushInstalledFile(.Lib, name); |
| 2791 | builder.pushInstalledFile(.lib, name); |
| 2778 | 2792 | } |
| 2779 | 2793 | if (self.artifact.target.isWindows()) { |
| 2780 | | builder.pushInstalledFile(.Lib, artifact.out_lib_filename); |
| 2794 | builder.pushInstalledFile(.lib, artifact.out_lib_filename); |
| 2781 | 2795 | } |
| 2782 | 2796 | } |
| 2783 | 2797 | if (self.pdb_dir) |pdb_dir| { |
| ... | ... | @@ -2794,40 +2808,42 @@ pub const InstallArtifactStep = struct { |
| 2794 | 2808 | const builder = self.builder; |
| 2795 | 2809 | |
| 2796 | 2810 | const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename); |
| 2797 | | try builder.updateFile(self.artifact.getOutputPath(), full_dest_path); |
| 2811 | try builder.updateFile(self.artifact.getOutputSource().getPath(builder), full_dest_path); |
| 2798 | 2812 | if (self.artifact.isDynamicLibrary() and self.artifact.version != null and self.artifact.target.wantSharedLibSymLinks()) { |
| 2799 | 2813 | try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename.?, self.artifact.name_only_filename.?); |
| 2800 | 2814 | } |
| 2801 | 2815 | if (self.pdb_dir) |pdb_dir| { |
| 2802 | 2816 | const full_pdb_path = builder.getInstallPath(pdb_dir, self.artifact.out_pdb_filename); |
| 2803 | | try builder.updateFile(self.artifact.getOutputPdbPath(), full_pdb_path); |
| 2817 | try builder.updateFile(self.artifact.getOutputPdbSource().getPath(builder), full_pdb_path); |
| 2804 | 2818 | } |
| 2805 | 2819 | if (self.h_dir) |h_dir| { |
| 2806 | 2820 | const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename); |
| 2807 | | try builder.updateFile(self.artifact.getOutputHPath(), full_pdb_path); |
| 2821 | try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_pdb_path); |
| 2808 | 2822 | } |
| 2809 | 2823 | self.artifact.installed_path = full_dest_path; |
| 2810 | 2824 | } |
| 2811 | 2825 | }; |
| 2812 | 2826 | |
| 2813 | 2827 | pub const InstallFileStep = struct { |
| 2828 | pub const base_id = .install_file; |
| 2829 | |
| 2814 | 2830 | step: Step, |
| 2815 | 2831 | builder: *Builder, |
| 2816 | | src_path: []const u8, |
| 2832 | source: FileSource, |
| 2817 | 2833 | dir: InstallDir, |
| 2818 | 2834 | dest_rel_path: []const u8, |
| 2819 | 2835 | |
| 2820 | 2836 | pub fn init( |
| 2821 | 2837 | builder: *Builder, |
| 2822 | | src_path: []const u8, |
| 2838 | source: FileSource, |
| 2823 | 2839 | dir: InstallDir, |
| 2824 | 2840 | dest_rel_path: []const u8, |
| 2825 | 2841 | ) InstallFileStep { |
| 2826 | 2842 | builder.pushInstalledFile(dir, dest_rel_path); |
| 2827 | 2843 | return InstallFileStep{ |
| 2828 | 2844 | .builder = builder, |
| 2829 | | .step = Step.init(.InstallFile, builder.fmt("install {s}", .{src_path}), builder.allocator, make), |
| 2830 | | .src_path = builder.dupePath(src_path), |
| 2845 | .step = Step.init(.install_file, builder.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }), builder.allocator, make), |
| 2846 | .source = source.dupe(builder), |
| 2831 | 2847 | .dir = dir.dupe(builder), |
| 2832 | 2848 | .dest_rel_path = builder.dupePath(dest_rel_path), |
| 2833 | 2849 | }; |
| ... | ... | @@ -2836,7 +2852,7 @@ pub const InstallFileStep = struct { |
| 2836 | 2852 | fn make(step: *Step) !void { |
| 2837 | 2853 | const self = @fieldParentPtr(InstallFileStep, "step", step); |
| 2838 | 2854 | const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path); |
| 2839 | | const full_src_path = self.builder.pathFromRoot(self.src_path); |
| 2855 | const full_src_path = self.source.getPath(self.builder); |
| 2840 | 2856 | try self.builder.updateFile(full_src_path, full_dest_path); |
| 2841 | 2857 | } |
| 2842 | 2858 | }; |
| ... | ... | @@ -2867,6 +2883,8 @@ pub const InstallDirectoryOptions = struct { |
| 2867 | 2883 | }; |
| 2868 | 2884 | |
| 2869 | 2885 | pub const InstallDirStep = struct { |
| 2886 | pub const base_id = .install_dir; |
| 2887 | |
| 2870 | 2888 | step: Step, |
| 2871 | 2889 | builder: *Builder, |
| 2872 | 2890 | options: InstallDirectoryOptions, |
| ... | ... | @@ -2878,7 +2896,7 @@ pub const InstallDirStep = struct { |
| 2878 | 2896 | builder.pushInstalledFile(options.install_dir, options.install_subdir); |
| 2879 | 2897 | return InstallDirStep{ |
| 2880 | 2898 | .builder = builder, |
| 2881 | | .step = Step.init(.InstallDir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make), |
| 2899 | .step = Step.init(.install_dir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make), |
| 2882 | 2900 | .options = options.dupe(builder), |
| 2883 | 2901 | }; |
| 2884 | 2902 | } |
| ... | ... | @@ -2919,6 +2937,8 @@ pub const InstallDirStep = struct { |
| 2919 | 2937 | }; |
| 2920 | 2938 | |
| 2921 | 2939 | pub const LogStep = struct { |
| 2940 | pub const base_id = .log; |
| 2941 | |
| 2922 | 2942 | step: Step, |
| 2923 | 2943 | builder: *Builder, |
| 2924 | 2944 | data: []const u8, |
| ... | ... | @@ -2926,7 +2946,7 @@ pub const LogStep = struct { |
| 2926 | 2946 | pub fn init(builder: *Builder, data: []const u8) LogStep { |
| 2927 | 2947 | return LogStep{ |
| 2928 | 2948 | .builder = builder, |
| 2929 | | .step = Step.init(.Log, builder.fmt("log {s}", .{data}), builder.allocator, make), |
| 2949 | .step = Step.init(.log, builder.fmt("log {s}", .{data}), builder.allocator, make), |
| 2930 | 2950 | .data = builder.dupe(data), |
| 2931 | 2951 | }; |
| 2932 | 2952 | } |
| ... | ... | @@ -2938,6 +2958,8 @@ pub const LogStep = struct { |
| 2938 | 2958 | }; |
| 2939 | 2959 | |
| 2940 | 2960 | pub const RemoveDirStep = struct { |
| 2961 | pub const base_id = .remove_dir; |
| 2962 | |
| 2941 | 2963 | step: Step, |
| 2942 | 2964 | builder: *Builder, |
| 2943 | 2965 | dir_path: []const u8, |
| ... | ... | @@ -2945,7 +2967,7 @@ pub const RemoveDirStep = struct { |
| 2945 | 2967 | pub fn init(builder: *Builder, dir_path: []const u8) RemoveDirStep { |
| 2946 | 2968 | return RemoveDirStep{ |
| 2947 | 2969 | .builder = builder, |
| 2948 | | .step = Step.init(.RemoveDir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make), |
| 2970 | .step = Step.init(.remove_dir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make), |
| 2949 | 2971 | .dir_path = builder.dupePath(dir_path), |
| 2950 | 2972 | }; |
| 2951 | 2973 | } |
| ... | ... | @@ -2971,20 +2993,20 @@ pub const Step = struct { |
| 2971 | 2993 | done_flag: bool, |
| 2972 | 2994 | |
| 2973 | 2995 | pub const Id = enum { |
| 2974 | | TopLevel, |
| 2975 | | LibExeObj, |
| 2976 | | InstallArtifact, |
| 2977 | | InstallFile, |
| 2978 | | InstallDir, |
| 2979 | | Log, |
| 2980 | | RemoveDir, |
| 2981 | | Fmt, |
| 2982 | | TranslateC, |
| 2983 | | WriteFile, |
| 2984 | | Run, |
| 2985 | | CheckFile, |
| 2986 | | InstallRaw, |
| 2987 | | Custom, |
| 2996 | top_level, |
| 2997 | lib_exe_obj, |
| 2998 | install_artifact, |
| 2999 | install_file, |
| 3000 | install_dir, |
| 3001 | log, |
| 3002 | remove_dir, |
| 3003 | fmt, |
| 3004 | translate_c, |
| 3005 | write_file, |
| 3006 | run, |
| 3007 | check_file, |
| 3008 | install_raw, |
| 3009 | custom, |
| 2988 | 3010 | }; |
| 2989 | 3011 | |
| 2990 | 3012 | pub fn init(id: Id, name: []const u8, allocator: *Allocator, makeFn: fn (*Step) anyerror!void) Step { |
| ... | ... | @@ -3015,23 +3037,11 @@ pub const Step = struct { |
| 3015 | 3037 | fn makeNoOp(self: *Step) anyerror!void {} |
| 3016 | 3038 | |
| 3017 | 3039 | pub fn cast(step: *Step, comptime T: type) ?*T { |
| 3018 | | if (step.id == comptime typeToId(T)) { |
| 3040 | if (step.id == T.base_id) { |
| 3019 | 3041 | return @fieldParentPtr(T, "step", step); |
| 3020 | 3042 | } |
| 3021 | 3043 | return null; |
| 3022 | 3044 | } |
| 3023 | | |
| 3024 | | fn typeToId(comptime T: type) Id { |
| 3025 | | inline for (@typeInfo(Id).Enum.fields) |f| { |
| 3026 | | if (std.mem.eql(u8, f.name, "TopLevel") or |
| 3027 | | std.mem.eql(u8, f.name, "Custom")) continue; |
| 3028 | | |
| 3029 | | if (T == @field(ThisModule, f.name ++ "Step")) { |
| 3030 | | return @field(Id, f.name); |
| 3031 | | } |
| 3032 | | } |
| 3033 | | unreachable; |
| 3034 | | } |
| 3035 | 3045 | }; |
| 3036 | 3046 | |
| 3037 | 3047 | fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void { |
| ... | ... | @@ -3077,32 +3087,30 @@ fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 { |
| 3077 | 3087 | } |
| 3078 | 3088 | |
| 3079 | 3089 | const VcpkgRoot = union(VcpkgRootStatus) { |
| 3080 | | Unattempted: void, |
| 3081 | | NotFound: void, |
| 3082 | | Found: []const u8, |
| 3090 | unattempted: void, |
| 3091 | not_found: void, |
| 3092 | found: []const u8, |
| 3083 | 3093 | }; |
| 3084 | 3094 | |
| 3085 | 3095 | const VcpkgRootStatus = enum { |
| 3086 | | Unattempted, |
| 3087 | | NotFound, |
| 3088 | | Found, |
| 3096 | unattempted, |
| 3097 | not_found, |
| 3098 | found, |
| 3089 | 3099 | }; |
| 3090 | 3100 | |
| 3091 | | pub const VcpkgLinkage = std.builtin.LinkMode; |
| 3092 | | |
| 3093 | 3101 | pub const InstallDir = union(enum) { |
| 3094 | | Prefix: void, |
| 3095 | | Lib: void, |
| 3096 | | Bin: void, |
| 3097 | | Header: void, |
| 3102 | prefix: void, |
| 3103 | lib: void, |
| 3104 | bin: void, |
| 3105 | header: void, |
| 3098 | 3106 | /// A path relative to the prefix |
| 3099 | | Custom: []const u8, |
| 3107 | custom: []const u8, |
| 3100 | 3108 | |
| 3101 | 3109 | fn dupe(self: InstallDir, builder: *Builder) InstallDir { |
| 3102 | | if (self == .Custom) { |
| 3110 | if (self == .custom) { |
| 3103 | 3111 | // Written with this temporary to avoid RLS problems |
| 3104 | | const duped_path = builder.dupe(self.Custom); |
| 3105 | | return .{ .Custom = duped_path }; |
| 3112 | const duped_path = builder.dupe(self.custom); |
| 3113 | return .{ .custom = duped_path }; |
| 3106 | 3114 | } else { |
| 3107 | 3115 | return self; |
| 3108 | 3116 | } |
| ... | ... | @@ -3137,11 +3145,11 @@ test "Builder.dupePkg()" { |
| 3137 | 3145 | |
| 3138 | 3146 | var pkg_dep = Pkg{ |
| 3139 | 3147 | .name = "pkg_dep", |
| 3140 | | .path = "/not/a/pkg_dep.zig", |
| 3148 | .path = .{ .path = "/not/a/pkg_dep.zig" }, |
| 3141 | 3149 | }; |
| 3142 | 3150 | var pkg_top = Pkg{ |
| 3143 | 3151 | .name = "pkg_top", |
| 3144 | | .path = "/not/a/pkg_top.zig", |
| 3152 | .path = .{ .path = "/not/a/pkg_top.zig" }, |
| 3145 | 3153 | .dependencies = &[_]Pkg{pkg_dep}, |
| 3146 | 3154 | }; |
| 3147 | 3155 | const dupe = builder.dupePkg(pkg_top); |
| ... | ... | @@ -3160,9 +3168,9 @@ test "Builder.dupePkg()" { |
| 3160 | 3168 | // the same as those in stack allocated package's fields |
| 3161 | 3169 | try std.testing.expect(dupe_deps.ptr != original_deps.ptr); |
| 3162 | 3170 | try std.testing.expect(dupe.name.ptr != pkg_top.name.ptr); |
| 3163 | | try std.testing.expect(dupe.path.ptr != pkg_top.path.ptr); |
| 3171 | try std.testing.expect(dupe.path.path.ptr != pkg_top.path.path.ptr); |
| 3164 | 3172 | try std.testing.expect(dupe_deps[0].name.ptr != pkg_dep.name.ptr); |
| 3165 | | try std.testing.expect(dupe_deps[0].path.ptr != pkg_dep.path.ptr); |
| 3173 | try std.testing.expect(dupe_deps[0].path.path.ptr != pkg_dep.path.path.ptr); |
| 3166 | 3174 | } |
| 3167 | 3175 | |
| 3168 | 3176 | test "LibExeObjStep.addBuildOption" { |
| ... | ... | @@ -3219,11 +3227,11 @@ test "LibExeObjStep.addPackage" { |
| 3219 | 3227 | |
| 3220 | 3228 | const pkg_dep = Pkg{ |
| 3221 | 3229 | .name = "pkg_dep", |
| 3222 | | .path = "/not/a/pkg_dep.zig", |
| 3230 | .path = .{ .path = "/not/a/pkg_dep.zig" }, |
| 3223 | 3231 | }; |
| 3224 | 3232 | const pkg_top = Pkg{ |
| 3225 | 3233 | .name = "pkg_dep", |
| 3226 | | .path = "/not/a/pkg_top.zig", |
| 3234 | .path = .{ .path = "/not/a/pkg_top.zig" }, |
| 3227 | 3235 | .dependencies = &[_]Pkg{pkg_dep}, |
| 3228 | 3236 | }; |
| 3229 | 3237 | |