| ... | ... | @@ -18,10 +18,8 @@ const File = std.fs.File; |
| 18 | 18 | pub const FmtStep = @import("build/fmt.zig").FmtStep; |
| 19 | 19 | |
| 20 | 20 | pub const Builder = struct { |
| 21 | | uninstall_tls: TopLevelStep, |
| 22 | 21 | install_tls: TopLevelStep, |
| 23 | | have_uninstall_step: bool, |
| 24 | | have_install_step: bool, |
| 22 | uninstall_tls: TopLevelStep, |
| 25 | 23 | allocator: *Allocator, |
| 26 | 24 | native_system_lib_paths: ArrayList([]const u8), |
| 27 | 25 | native_system_include_dirs: ArrayList([]const u8), |
| ... | ... | @@ -42,14 +40,15 @@ pub const Builder = struct { |
| 42 | 40 | default_step: *Step, |
| 43 | 41 | env_map: *BufMap, |
| 44 | 42 | top_level_steps: ArrayList(*TopLevelStep), |
| 45 | | prefix: []const u8, |
| 43 | install_prefix: ?[]const u8, |
| 46 | 44 | search_prefixes: ArrayList([]const u8), |
| 47 | | lib_dir: []const u8, |
| 48 | | exe_dir: []const u8, |
| 49 | | installed_files: ArrayList([]const u8), |
| 45 | lib_dir: ?[]const u8, |
| 46 | exe_dir: ?[]const u8, |
| 47 | installed_files: ArrayList(InstalledFile), |
| 50 | 48 | build_root: []const u8, |
| 51 | 49 | cache_root: []const u8, |
| 52 | 50 | release_mode: ?builtin.Mode, |
| 51 | is_release: bool, |
| 53 | 52 | override_std_dir: ?[]const u8, |
| 54 | 53 | override_lib_dir: ?[]const u8, |
| 55 | 54 | |
| ... | ... | @@ -93,13 +92,20 @@ pub const Builder = struct { |
| 93 | 92 | description: []const u8, |
| 94 | 93 | }; |
| 95 | 94 | |
| 96 | | pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder { |
| 97 | | const env_map = allocator.create(BufMap) catch unreachable; |
| 98 | | env_map.* = process.getEnvMap(allocator) catch unreachable; |
| 99 | | var self = Builder{ |
| 95 | pub fn create( |
| 96 | allocator: *Allocator, |
| 97 | zig_exe: []const u8, |
| 98 | build_root: []const u8, |
| 99 | cache_root: []const u8, |
| 100 | ) !*Builder { |
| 101 | const env_map = try allocator.create(BufMap); |
| 102 | env_map.* = try process.getEnvMap(allocator); |
| 103 | |
| 104 | const self = try allocator.create(Builder); |
| 105 | self.* = Builder{ |
| 100 | 106 | .zig_exe = zig_exe, |
| 101 | 107 | .build_root = build_root, |
| 102 | | .cache_root = fs.path.relative(allocator, build_root, cache_root) catch unreachable, |
| 108 | .cache_root = try fs.path.relative(allocator, build_root, cache_root), |
| 103 | 109 | .verbose = false, |
| 104 | 110 | .verbose_tokenize = false, |
| 105 | 111 | .verbose_ast = false, |
| ... | ... | @@ -119,42 +125,53 @@ pub const Builder = struct { |
| 119 | 125 | .top_level_steps = ArrayList(*TopLevelStep).init(allocator), |
| 120 | 126 | .default_step = undefined, |
| 121 | 127 | .env_map = env_map, |
| 122 | | .prefix = undefined, |
| 128 | .install_prefix = null, |
| 123 | 129 | .search_prefixes = ArrayList([]const u8).init(allocator), |
| 124 | | .lib_dir = undefined, |
| 125 | | .exe_dir = undefined, |
| 126 | | .installed_files = ArrayList([]const u8).init(allocator), |
| 127 | | .uninstall_tls = TopLevelStep{ |
| 128 | | .step = Step.init("uninstall", allocator, makeUninstall), |
| 129 | | .description = "Remove build artifacts from prefix path", |
| 130 | | }, |
| 131 | | .have_uninstall_step = false, |
| 130 | .lib_dir = null, |
| 131 | .exe_dir = null, |
| 132 | .installed_files = ArrayList(InstalledFile).init(allocator), |
| 132 | 133 | .install_tls = TopLevelStep{ |
| 133 | 134 | .step = Step.initNoOp("install", allocator), |
| 134 | 135 | .description = "Copy build artifacts to prefix path", |
| 135 | 136 | }, |
| 136 | | .have_install_step = false, |
| 137 | .uninstall_tls = TopLevelStep{ |
| 138 | .step = Step.init("uninstall", allocator, makeUninstall), |
| 139 | .description = "Remove build artifacts from prefix path", |
| 140 | }, |
| 137 | 141 | .release_mode = null, |
| 142 | .is_release = false, |
| 138 | 143 | .override_std_dir = null, |
| 139 | 144 | .override_lib_dir = null, |
| 140 | 145 | }; |
| 146 | try self.top_level_steps.append(&self.install_tls); |
| 147 | try self.top_level_steps.append(&self.uninstall_tls); |
| 141 | 148 | self.detectNativeSystemPaths(); |
| 142 | | self.default_step = self.step("default", "Build the project"); |
| 149 | self.default_step = &self.install_tls.step; |
| 143 | 150 | return self; |
| 144 | 151 | } |
| 145 | 152 | |
| 146 | | pub fn deinit(self: *Builder) void { |
| 153 | pub fn destroy(self: *Builder) void { |
| 147 | 154 | self.native_system_lib_paths.deinit(); |
| 148 | 155 | self.native_system_include_dirs.deinit(); |
| 149 | 156 | self.native_system_rpaths.deinit(); |
| 150 | 157 | self.env_map.deinit(); |
| 151 | 158 | self.top_level_steps.deinit(); |
| 159 | self.allocator.destroy(self); |
| 152 | 160 | } |
| 153 | 161 | |
| 154 | | pub fn setInstallPrefix(self: *Builder, maybe_prefix: ?[]const u8) void { |
| 155 | | self.prefix = maybe_prefix orelse "/usr/local"; // TODO better default |
| 156 | | self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ self.prefix, "lib" }) catch unreachable; |
| 157 | | self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ self.prefix, "bin" }) catch unreachable; |
| 162 | pub fn setInstallPrefix(self: *Builder, optional_prefix: ?[]const u8) void { |
| 163 | self.install_prefix = optional_prefix; |
| 164 | } |
| 165 | |
| 166 | fn resolveInstallPrefix(self: *Builder) void { |
| 167 | const prefix = if (self.install_prefix) |prefix| prefix else blk: { |
| 168 | const prefix = self.cache_root; |
| 169 | self.install_prefix = prefix; |
| 170 | break :blk prefix; |
| 171 | }; |
| 172 | |
| 173 | self.lib_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "lib" }) catch unreachable; |
| 174 | self.exe_dir = fs.path.join(self.allocator, [_][]const u8{ prefix, "bin" }) catch unreachable; |
| 158 | 175 | } |
| 159 | 176 | |
| 160 | 177 | pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep { |
| ... | ... | @@ -263,18 +280,10 @@ pub const Builder = struct { |
| 263 | 280 | } |
| 264 | 281 | |
| 265 | 282 | pub fn getInstallStep(self: *Builder) *Step { |
| 266 | | if (self.have_install_step) return &self.install_tls.step; |
| 267 | | |
| 268 | | self.top_level_steps.append(&self.install_tls) catch unreachable; |
| 269 | | self.have_install_step = true; |
| 270 | 283 | return &self.install_tls.step; |
| 271 | 284 | } |
| 272 | 285 | |
| 273 | 286 | pub fn getUninstallStep(self: *Builder) *Step { |
| 274 | | if (self.have_uninstall_step) return &self.uninstall_tls.step; |
| 275 | | |
| 276 | | self.top_level_steps.append(&self.uninstall_tls) catch unreachable; |
| 277 | | self.have_uninstall_step = true; |
| 278 | 287 | return &self.uninstall_tls.step; |
| 279 | 288 | } |
| 280 | 289 | |
| ... | ... | @@ -283,10 +292,11 @@ pub const Builder = struct { |
| 283 | 292 | const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls); |
| 284 | 293 | |
| 285 | 294 | for (self.installed_files.toSliceConst()) |installed_file| { |
| 295 | const full_path = self.getInstallPath(installed_file.dir, installed_file.path); |
| 286 | 296 | if (self.verbose) { |
| 287 | | warn("rm {}\n", installed_file); |
| 297 | warn("rm {}\n", full_path); |
| 288 | 298 | } |
| 289 | | fs.deleteFile(installed_file) catch {}; |
| 299 | fs.deleteFile(full_path) catch {}; |
| 290 | 300 | } |
| 291 | 301 | |
| 292 | 302 | // TODO remove empty directories |
| ... | ... | @@ -460,6 +470,18 @@ pub const Builder = struct { |
| 460 | 470 | return &step_info.step; |
| 461 | 471 | } |
| 462 | 472 | |
| 473 | /// This provides the -Drelease option to the build user and does not give them the choice. |
| 474 | pub fn setPreferredReleaseMode(self: *Builder, mode: builtin.Mode) void { |
| 475 | if (self.release_mode != null) { |
| 476 | @panic("setPreferredReleaseMode must be called before standardReleaseOptions and may not be called twice"); |
| 477 | } |
| 478 | const description = self.fmt("create a release build ({})", @tagName(mode)); |
| 479 | self.is_release = self.option(bool, "release", description) orelse false; |
| 480 | self.release_mode = if (is_release) mode else builtin.Mode.Debug; |
| 481 | } |
| 482 | |
| 483 | /// If you call this without first calling `setPreferredReleaseMode` then it gives the build user |
| 484 | /// the choice of what kind of release. |
| 463 | 485 | pub fn standardReleaseOptions(self: *Builder) builtin.Mode { |
| 464 | 486 | if (self.release_mode) |mode| return mode; |
| 465 | 487 | |
| ... | ... | @@ -467,11 +489,20 @@ pub const Builder = struct { |
| 467 | 489 | const release_fast = self.option(bool, "release-fast", "optimizations on and safety off") orelse false; |
| 468 | 490 | const release_small = self.option(bool, "release-small", "size optimizations on and safety off") orelse false; |
| 469 | 491 | |
| 470 | | const mode = if (release_safe and !release_fast and !release_small) builtin.Mode.ReleaseSafe else if (release_fast and !release_safe and !release_small) builtin.Mode.ReleaseFast else if (release_small and !release_fast and !release_safe) builtin.Mode.ReleaseSmall else if (!release_fast and !release_safe and !release_small) builtin.Mode.Debug else x: { |
| 492 | const mode = if (release_safe and !release_fast and !release_small) |
| 493 | builtin.Mode.ReleaseSafe |
| 494 | else if (release_fast and !release_safe and !release_small) |
| 495 | builtin.Mode.ReleaseFast |
| 496 | else if (release_small and !release_fast and !release_safe) |
| 497 | builtin.Mode.ReleaseSmall |
| 498 | else if (!release_fast and !release_safe and !release_small) |
| 499 | builtin.Mode.Debug |
| 500 | else x: { |
| 471 | 501 | warn("Multiple release modes (of -Drelease-safe, -Drelease-fast and -Drelease-small)"); |
| 472 | 502 | self.markInvalidUserInput(); |
| 473 | 503 | break :x builtin.Mode.Debug; |
| 474 | 504 | }; |
| 505 | self.is_release = mode != .Debug; |
| 475 | 506 | self.release_mode = mode; |
| 476 | 507 | return mode; |
| 477 | 508 | } |
| ... | ... | @@ -571,6 +602,8 @@ pub const Builder = struct { |
| 571 | 602 | } |
| 572 | 603 | |
| 573 | 604 | pub fn validateUserInputDidItFail(self: *Builder) bool { |
| 605 | self.resolveInstallPrefix(); |
| 606 | |
| 574 | 607 | // make sure all args are used |
| 575 | 608 | var it = self.user_input_options.iterator(); |
| 576 | 609 | while (true) { |
| ... | ... | @@ -644,27 +677,52 @@ pub const Builder = struct { |
| 644 | 677 | return InstallArtifactStep.create(self, artifact); |
| 645 | 678 | } |
| 646 | 679 | |
| 647 | | ///::dest_rel_path is relative to prefix path or it can be an absolute path |
| 680 | ///`dest_rel_path` is relative to prefix path |
| 648 | 681 | pub fn installFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 649 | | self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step); |
| 682 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path).step); |
| 683 | } |
| 684 | |
| 685 | ///`dest_rel_path` is relative to bin path |
| 686 | pub fn installBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 687 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Bin, dest_rel_path).step); |
| 650 | 688 | } |
| 651 | 689 | |
| 652 | | ///::dest_rel_path is relative to prefix path or it can be an absolute path |
| 690 | ///`dest_rel_path` is relative to lib path |
| 691 | pub fn installLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) void { |
| 692 | self.getInstallStep().dependOn(&self.addInstallFileWithDir(src_path, .Lib, dest_rel_path).step); |
| 693 | } |
| 694 | |
| 695 | ///`dest_rel_path` is relative to install prefix path |
| 653 | 696 | pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 654 | | const full_dest_path = fs.path.resolve( |
| 655 | | self.allocator, |
| 656 | | [_][]const u8{ self.prefix, dest_rel_path }, |
| 657 | | ) catch unreachable; |
| 658 | | self.pushInstalledFile(full_dest_path); |
| 697 | return self.addInstallFileWithDir(src_path, .Prefix, dest_rel_path); |
| 698 | } |
| 699 | |
| 700 | ///`dest_rel_path` is relative to bin path |
| 701 | pub fn addInstallBinFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 702 | return self.addInstallFileWithDir(src_path, .Bin, dest_rel_path); |
| 703 | } |
| 659 | 704 | |
| 705 | ///`dest_rel_path` is relative to lib path |
| 706 | pub fn addInstallLibFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep { |
| 707 | return self.addInstallFileWithDir(src_path, .Lib, dest_rel_path); |
| 708 | } |
| 709 | |
| 710 | pub fn addInstallFileWithDir( |
| 711 | self: *Builder, |
| 712 | src_path: []const u8, |
| 713 | install_dir: InstallDir, |
| 714 | dest_rel_path: []const u8, |
| 715 | ) *InstallFileStep { |
| 660 | 716 | const install_step = self.allocator.create(InstallFileStep) catch unreachable; |
| 661 | | install_step.* = InstallFileStep.init(self, src_path, full_dest_path); |
| 717 | install_step.* = InstallFileStep.init(self, src_path, install_dir, dest_rel_path); |
| 662 | 718 | return install_step; |
| 663 | 719 | } |
| 664 | 720 | |
| 665 | | pub fn pushInstalledFile(self: *Builder, full_path: []const u8) void { |
| 666 | | _ = self.getUninstallStep(); |
| 667 | | self.installed_files.append(full_path) catch unreachable; |
| 721 | pub fn pushInstalledFile(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) void { |
| 722 | self.installed_files.append(InstalledFile{ |
| 723 | .dir = dir, |
| 724 | .path = dest_rel_path, |
| 725 | }) catch unreachable; |
| 668 | 726 | } |
| 669 | 727 | |
| 670 | 728 | fn copyFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void { |
| ... | ... | @@ -786,6 +844,18 @@ pub const Builder = struct { |
| 786 | 844 | pub fn addSearchPrefix(self: *Builder, search_prefix: []const u8) void { |
| 787 | 845 | self.search_prefixes.append(search_prefix) catch unreachable; |
| 788 | 846 | } |
| 847 | |
| 848 | fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 { |
| 849 | const base_dir = switch (dir) { |
| 850 | .Prefix => self.install_prefix.?, |
| 851 | .Bin => self.exe_dir.?, |
| 852 | .Lib => self.lib_dir.?, |
| 853 | }; |
| 854 | return fs.path.resolve( |
| 855 | self.allocator, |
| 856 | [_][]const u8{ base_dir, dest_rel_path }, |
| 857 | ) catch unreachable; |
| 858 | } |
| 789 | 859 | }; |
| 790 | 860 | |
| 791 | 861 | const Version = struct { |
| ... | ... | @@ -980,6 +1050,9 @@ pub const LibExeObjStep = struct { |
| 980 | 1050 | output_dir: ?[]const u8, |
| 981 | 1051 | need_system_paths: bool, |
| 982 | 1052 | |
| 1053 | installed_path: ?[]const u8, |
| 1054 | install_step: ?*InstallArtifactStep, |
| 1055 | |
| 983 | 1056 | const LinkObject = union(enum) { |
| 984 | 1057 | StaticPath: []const u8, |
| 985 | 1058 | OtherStep: *LibExeObjStep, |
| ... | ... | @@ -1071,6 +1144,8 @@ pub const LibExeObjStep = struct { |
| 1071 | 1144 | .output_dir = null, |
| 1072 | 1145 | .need_system_paths = false, |
| 1073 | 1146 | .single_threaded = false, |
| 1147 | .installed_path = null, |
| 1148 | .install_step = null, |
| 1074 | 1149 | }; |
| 1075 | 1150 | self.computeOutFileNames(); |
| 1076 | 1151 | return self; |
| ... | ... | @@ -1146,10 +1221,15 @@ pub const LibExeObjStep = struct { |
| 1146 | 1221 | self.output_dir = self.builder.dupe(dir); |
| 1147 | 1222 | } |
| 1148 | 1223 | |
| 1224 | pub fn install(self: *LibExeObjStep) void { |
| 1225 | self.builder.installArtifact(self); |
| 1226 | } |
| 1227 | |
| 1149 | 1228 | /// Creates a `RunStep` with an executable built with `addExecutable`. |
| 1150 | 1229 | /// Add command line arguments with `addArg`. |
| 1151 | 1230 | pub fn run(exe: *LibExeObjStep) *RunStep { |
| 1152 | 1231 | assert(exe.kind == Kind.Exe); |
| 1232 | |
| 1153 | 1233 | // It doesn't have to be native. We catch that if you actually try to run it. |
| 1154 | 1234 | // Consider that this is declarative; the run step may not be run unless a user |
| 1155 | 1235 | // option is supplied. |
| ... | ... | @@ -1692,7 +1772,8 @@ pub const RunStep = struct { |
| 1692 | 1772 | // On Windows we don't have rpaths so we have to add .dll search paths to PATH |
| 1693 | 1773 | self.addPathForDynLibs(artifact); |
| 1694 | 1774 | } |
| 1695 | | try argv.append(artifact.getOutputPath()); |
| 1775 | const executable_path = artifact.installed_path orelse artifact.getOutputPath(); |
| 1776 | try argv.append(executable_path); |
| 1696 | 1777 | }, |
| 1697 | 1778 | } |
| 1698 | 1779 | } |
| ... | ... | @@ -1719,38 +1800,32 @@ const InstallArtifactStep = struct { |
| 1719 | 1800 | step: Step, |
| 1720 | 1801 | builder: *Builder, |
| 1721 | 1802 | artifact: *LibExeObjStep, |
| 1722 | | dest_file: []const u8, |
| 1803 | dest_dir: InstallDir, |
| 1723 | 1804 | |
| 1724 | 1805 | const Self = @This(); |
| 1725 | 1806 | |
| 1726 | 1807 | pub fn create(builder: *Builder, artifact: *LibExeObjStep) *Self { |
| 1727 | | const dest_dir = switch (artifact.kind) { |
| 1728 | | LibExeObjStep.Kind.Obj => unreachable, |
| 1729 | | LibExeObjStep.Kind.Test => unreachable, |
| 1730 | | LibExeObjStep.Kind.Exe => builder.exe_dir, |
| 1731 | | LibExeObjStep.Kind.Lib => builder.lib_dir, |
| 1732 | | }; |
| 1808 | if (artifact.install_step) |s| return s; |
| 1809 | |
| 1733 | 1810 | const self = builder.allocator.create(Self) catch unreachable; |
| 1734 | 1811 | self.* = Self{ |
| 1735 | 1812 | .builder = builder, |
| 1736 | 1813 | .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make), |
| 1737 | 1814 | .artifact = artifact, |
| 1738 | | .dest_file = fs.path.join( |
| 1739 | | builder.allocator, |
| 1740 | | [_][]const u8{ dest_dir, artifact.out_filename }, |
| 1741 | | ) catch unreachable, |
| 1815 | .dest_dir = switch (artifact.kind) { |
| 1816 | .Obj => unreachable, |
| 1817 | .Test => unreachable, |
| 1818 | .Exe => InstallDir.Bin, |
| 1819 | .Lib => InstallDir.Lib, |
| 1820 | }, |
| 1742 | 1821 | }; |
| 1743 | 1822 | self.step.dependOn(&artifact.step); |
| 1744 | | builder.pushInstalledFile(self.dest_file); |
| 1745 | | if (self.artifact.kind == LibExeObjStep.Kind.Lib and self.artifact.is_dynamic) { |
| 1746 | | builder.pushInstalledFile(fs.path.join( |
| 1747 | | builder.allocator, |
| 1748 | | [_][]const u8{ builder.lib_dir, artifact.major_only_filename }, |
| 1749 | | ) catch unreachable); |
| 1750 | | builder.pushInstalledFile(fs.path.join( |
| 1751 | | builder.allocator, |
| 1752 | | [_][]const u8{ builder.lib_dir, artifact.name_only_filename }, |
| 1753 | | ) catch unreachable); |
| 1823 | artifact.install_step = self; |
| 1824 | |
| 1825 | builder.pushInstalledFile(self.dest_dir, artifact.out_filename); |
| 1826 | if (self.artifact.isDynamicLibrary()) { |
| 1827 | builder.pushInstalledFile(.Lib, artifact.major_only_filename); |
| 1828 | builder.pushInstalledFile(.Lib, artifact.name_only_filename); |
| 1754 | 1829 | } |
| 1755 | 1830 | return self; |
| 1756 | 1831 | } |
| ... | ... | @@ -1768,10 +1843,12 @@ const InstallArtifactStep = struct { |
| 1768 | 1843 | .Lib => if (!self.artifact.is_dynamic) u32(0o666) else u32(0o755), |
| 1769 | 1844 | }, |
| 1770 | 1845 | }; |
| 1771 | | try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode); |
| 1846 | const full_dest_path = builder.getInstallPath(self.dest_dir, self.artifact.out_filename); |
| 1847 | try builder.copyFileMode(self.artifact.getOutputPath(), full_dest_path, mode); |
| 1772 | 1848 | if (self.artifact.isDynamicLibrary()) { |
| 1773 | | try doAtomicSymLinks(builder.allocator, self.dest_file, self.artifact.major_only_filename, self.artifact.name_only_filename); |
| 1849 | try doAtomicSymLinks(builder.allocator, full_dest_path, self.artifact.major_only_filename, self.artifact.name_only_filename); |
| 1774 | 1850 | } |
| 1851 | self.artifact.installed_path = full_dest_path; |
| 1775 | 1852 | } |
| 1776 | 1853 | }; |
| 1777 | 1854 | |
| ... | ... | @@ -1779,20 +1856,29 @@ pub const InstallFileStep = struct { |
| 1779 | 1856 | step: Step, |
| 1780 | 1857 | builder: *Builder, |
| 1781 | 1858 | src_path: []const u8, |
| 1782 | | dest_path: []const u8, |
| 1783 | | |
| 1784 | | pub fn init(builder: *Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep { |
| 1859 | dir: InstallDir, |
| 1860 | dest_rel_path: []const u8, |
| 1861 | |
| 1862 | pub fn init( |
| 1863 | builder: *Builder, |
| 1864 | src_path: []const u8, |
| 1865 | dir: InstallDir, |
| 1866 | dest_rel_path: []const u8, |
| 1867 | ) InstallFileStep { |
| 1868 | builder.pushInstalledFile(dir, dest_rel_path); |
| 1785 | 1869 | return InstallFileStep{ |
| 1786 | 1870 | .builder = builder, |
| 1787 | 1871 | .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make), |
| 1788 | 1872 | .src_path = src_path, |
| 1789 | | .dest_path = dest_path, |
| 1873 | .dir = dir, |
| 1874 | .dest_rel_path = dest_rel_path, |
| 1790 | 1875 | }; |
| 1791 | 1876 | } |
| 1792 | 1877 | |
| 1793 | 1878 | fn make(step: *Step) !void { |
| 1794 | 1879 | const self = @fieldParentPtr(InstallFileStep, "step", step); |
| 1795 | | try self.builder.copyFile(self.src_path, self.dest_path); |
| 1880 | const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path); |
| 1881 | try self.builder.copyFile(self.src_path, full_dest_path); |
| 1796 | 1882 | } |
| 1797 | 1883 | }; |
| 1798 | 1884 | |
| ... | ... | @@ -1925,3 +2011,14 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj |
| 1925 | 2011 | return err; |
| 1926 | 2012 | }; |
| 1927 | 2013 | } |
| 2014 | |
| 2015 | pub const InstallDir = enum { |
| 2016 | Prefix, |
| 2017 | Lib, |
| 2018 | Bin, |
| 2019 | }; |
| 2020 | |
| 2021 | pub const InstalledFile = struct { |
| 2022 | dir: InstallDir, |
| 2023 | path: []const u8, |
| 2024 | }; |