| author | |
| committer | |
| log | aa0652ff8dc9add09567d69a92ddaff5ad386919 |
| tree | 87fd48ec099c4237a30302df1e720e7aa559abbe |
| parent | dd51fc30f884aa1c3305793010a30d826689be89 |
13 files changed, 421 insertions(+), 283 deletions(-)
BRANCH_TODO+5-1| ... | ... | @@ -1,9 +1,10 @@ |
| 1 | * replace b.dupe() with string internment | |
| 1 | * implement the build options | |
| 2 | 2 | * don't forget to add -listen arg back |
| 3 | 3 | * get zig init template working |
| 4 | 4 | * finish migrating the rest of the build steps |
| 5 | 5 | * make zig-pkg path root configurable in maker (make sure --system still works) |
| 6 | 6 | * eliminate calls to getPath, getPath2, getPath3 |
| 7 | * replace b.dupe() with string internment | |
| 7 | 8 | * solve the TODOs added in this branch |
| 8 | 9 | * get zig tests passing |
| 9 | 10 | * test a bunch of third party projects / help people migrate |
| ... | ... | @@ -13,3 +14,6 @@ |
| 13 | 14 | ## Followup Issues |
| 14 | 15 | * link_eh_frame_hdr should be DefaultingBool |
| 15 | 16 | * make --foo, --no-foo CLI args uniform (make them -f args instead) |
| 17 | * install steps should provide generated files for installed things, then delete the run step hack | |
| 18 | ||
| 19 |
lib/compiler/Maker.zig+170-44| ... | ... | @@ -7,6 +7,7 @@ const Cache = std.Build.Cache; |
| 7 | 7 | const Configuration = std.Build.Configuration; |
| 8 | 8 | const File = std.Io.File; |
| 9 | 9 | const Io = std.Io; |
| 10 | const Dir = std.Io.Dir; | |
| 10 | 11 | const Path = std.Build.Cache.Path; |
| 11 | 12 | const Writer = std.Io.Writer; |
| 12 | 13 | const assert = std.debug.assert; |
| ... | ... | @@ -82,7 +83,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 82 | 83 | const global_cache_root = expectArgOrFatal(args, &arg_idx, "--global-cache"); |
| 83 | 84 | const configure_path = expectArgOrFatal(args, &arg_idx, "--configuration"); |
| 84 | 85 | |
| 85 | const cwd: Io.Dir = .cwd(); | |
| 86 | const cwd: Dir = .cwd(); | |
| 86 | 87 | |
| 87 | 88 | const zig_lib_directory: Cache.Directory = .{ |
| 88 | 89 | .path = zig_lib_dir, |
| ... | ... | @@ -497,7 +498,7 @@ pub fn main(init: process.Init.Minimal) !void { |
| 497 | 498 | |
| 498 | 499 | const install_prefix_path: Path = if (graph.environ_map.get("DESTDIR")) |dest_dir| .{ |
| 499 | 500 | .root_dir = .cwd(), |
| 500 | .sub_path = try Io.Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }), | |
| 501 | .sub_path = try Dir.path.join(arena, &.{ dest_dir, override_install_prefix orelse "/usr" }), | |
| 501 | 502 | } else if (override_install_prefix) |cwd_relative| .{ |
| 502 | 503 | .root_dir = .cwd(), |
| 503 | 504 | .sub_path = cwd_relative, |
| ... | ... | @@ -1675,7 +1676,7 @@ fn cleanTmpFiles(io: Io, steps: []const Configuration.Step.Index) void { |
| 1675 | 1676 | const wf = step_index.cast(std.Build.Step.WriteFile) orelse continue; |
| 1676 | 1677 | if (wf.mode != .tmp) continue; |
| 1677 | 1678 | const path = wf.generated_directory.path orelse continue; |
| 1678 | Io.Dir.cwd().deleteTree(io, path) catch |err| { | |
| 1679 | Dir.cwd().deleteTree(io, path) catch |err| { | |
| 1679 | 1680 | log.warn("failed to delete {s}: {t}", .{ path, err }); |
| 1680 | 1681 | }; |
| 1681 | 1682 | } |
| ... | ... | @@ -1699,29 +1700,14 @@ pub fn resolveLazyPath( |
| 1699 | 1700 | ) Allocator.Error!Path { |
| 1700 | 1701 | _ = asking_step_index; // TODO use this to enhance debugability when this function fails |
| 1701 | 1702 | const c = &maker.scanned_config.configuration; |
| 1702 | const graph = maker.graph; | |
| 1703 | 1703 | return switch (lazy_path) { |
| 1704 | 1704 | .source_path => |sp| try packagePath(maker, arena, sp.owner, sp.sub_path.slice(c)), |
| 1705 | .relative => |relative| switch (relative.flags.base) { | |
| 1706 | .cwd => .{ | |
| 1707 | .root_dir = .cwd(), | |
| 1708 | .sub_path = relative.sub_path.slice(c), | |
| 1709 | }, | |
| 1710 | .local_cache => .{ | |
| 1711 | .root_dir = graph.local_cache_root, | |
| 1712 | }, | |
| 1713 | .global_cache => .{ | |
| 1714 | .root_dir = graph.global_cache_root, | |
| 1715 | }, | |
| 1716 | .build_root => .{ | |
| 1717 | .root_dir = graph.build_root_directory, | |
| 1718 | }, | |
| 1719 | }, | |
| 1705 | .relative => |relative| relativePath(maker, relative), | |
| 1720 | 1706 | .generated => |gen| { |
| 1721 | const base = maker.generated_files[@intFromEnum(gen.index)]; | |
| 1707 | const base = generatedPath(maker, gen.index); | |
| 1722 | 1708 | var file_path = base; |
| 1723 | 1709 | for (0..gen.flags.up) |_| { |
| 1724 | file_path.sub_path = Io.Dir.path.dirname(file_path.sub_path) orelse | |
| 1710 | file_path.sub_path = Dir.path.dirname(file_path.sub_path) orelse | |
| 1725 | 1711 | fatal("invalid LazyPath traversal: up {d} times from {f}", .{ gen.flags.up, base }); |
| 1726 | 1712 | } |
| 1727 | 1713 | return file_path.join(arena, gen.sub_path.slice(c)); |
| ... | ... | @@ -1750,7 +1736,7 @@ pub fn resolveLazyPathAbs( |
| 1750 | 1736 | const p = try resolveLazyPath(maker, arena, lazy_path, asking_step_index); |
| 1751 | 1737 | const root_dir_path = p.root_dir.path orelse return p.subPathOrDot(); |
| 1752 | 1738 | if (p.sub_path.len == 0) return root_dir_path; |
| 1753 | return Io.Dir.path.join(arena, &.{ root_dir_path, p.sub_path }); | |
| 1739 | return Dir.path.join(arena, &.{ root_dir_path, p.sub_path }); | |
| 1754 | 1740 | } |
| 1755 | 1741 | |
| 1756 | 1742 | /// `resolveLazyPath` is preferred, but this can be necessary when passing Path |
| ... | ... | @@ -1765,11 +1751,11 @@ pub fn resolveLazyPathIndexAbs( |
| 1765 | 1751 | return resolveLazyPathAbs(maker, arena, lazy_path_index.get(c), asking_step_index); |
| 1766 | 1752 | } |
| 1767 | 1753 | |
| 1768 | pub fn generatedPath(maker: *Maker, index: Configuration.GeneratedFileIndex) *Path { | |
| 1754 | pub fn generatedPath(maker: *const Maker, index: Configuration.GeneratedFileIndex) *Path { | |
| 1769 | 1755 | return &maker.generated_files[@intFromEnum(index)]; |
| 1770 | 1756 | } |
| 1771 | 1757 | |
| 1772 | fn packagePath( | |
| 1758 | pub fn packagePath( | |
| 1773 | 1759 | maker: *const Maker, |
| 1774 | 1760 | arena: Allocator, |
| 1775 | 1761 | package_index: Configuration.Package.Index, |
| ... | ... | @@ -1785,43 +1771,183 @@ fn packagePath( |
| 1785 | 1771 | const pkg_root = graph.pkg_root; |
| 1786 | 1772 | return .{ |
| 1787 | 1773 | .root_dir = pkg_root.root_dir, |
| 1788 | .sub_path = try Io.Dir.path.join(arena, &.{ pkg_root.sub_path, hash, sub_path }), | |
| 1774 | .sub_path = try Dir.path.join(arena, &.{ pkg_root.sub_path, hash, sub_path }), | |
| 1775 | }; | |
| 1776 | } | |
| 1777 | ||
| 1778 | pub fn relativePath(maker: *const Maker, relative: Configuration.LazyPath.Relative) Path { | |
| 1779 | const graph = maker.graph; | |
| 1780 | const c = &maker.scanned_config.configuration; | |
| 1781 | const sub_path = relative.sub_path.slice(c); | |
| 1782 | return switch (relative.flags.base) { | |
| 1783 | .cwd => .{ | |
| 1784 | .root_dir = .cwd(), | |
| 1785 | .sub_path = sub_path, | |
| 1786 | }, | |
| 1787 | .local_cache => .{ | |
| 1788 | .root_dir = graph.local_cache_root, | |
| 1789 | .sub_path = sub_path, | |
| 1790 | }, | |
| 1791 | .global_cache => .{ | |
| 1792 | .root_dir = graph.global_cache_root, | |
| 1793 | .sub_path = sub_path, | |
| 1794 | }, | |
| 1795 | .build_root => .{ | |
| 1796 | .root_dir = graph.build_root_directory, | |
| 1797 | .sub_path = sub_path, | |
| 1798 | }, | |
| 1789 | 1799 | }; |
| 1790 | 1800 | } |
| 1791 | 1801 | |
| 1792 | /// Wrapper around `Io.Dir.updateFile` that handles verbose and error output. | |
| 1793 | pub fn installFile( | |
| 1802 | pub fn resolveInstallDir( | |
| 1794 | 1803 | maker: *Maker, |
| 1795 | 1804 | arena: Allocator, |
| 1796 | src_lazy_path: Configuration.LazyPath, | |
| 1797 | dest_path: []const u8, | |
| 1805 | dest_dir: Configuration.InstallDestDir, | |
| 1806 | ) Allocator.Error!Path { | |
| 1807 | const c = &maker.scanned_config.configuration; | |
| 1808 | return switch (dest_dir.unpack().?) { | |
| 1809 | .prefix => maker.install_paths.prefix, | |
| 1810 | .lib => maker.install_paths.lib, | |
| 1811 | .bin => maker.install_paths.bin, | |
| 1812 | .header => maker.install_paths.include, | |
| 1813 | .sub_path => |s| try maker.install_paths.prefix.join(arena, s.slice(c)), | |
| 1814 | }; | |
| 1815 | } | |
| 1816 | ||
| 1817 | pub fn installLazyPathSub( | |
| 1818 | maker: *Maker, | |
| 1819 | arena: Allocator, | |
| 1820 | source: Configuration.LazyPath.Index, | |
| 1821 | dest_dir: Configuration.InstallDestDir, | |
| 1822 | sub_path: []const u8, | |
| 1798 | 1823 | asking_step_index: Configuration.Step.Index, |
| 1799 | ) !Io.Dir.PrevStatus { | |
| 1824 | ) !Dir.PrevStatus { | |
| 1825 | const src_path = try resolveLazyPathIndex(maker, arena, source, asking_step_index); | |
| 1826 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); | |
| 1827 | const dest_path = try dest_dir_path.join(arena, sub_path); | |
| 1828 | return installPath(maker, arena, src_path, dest_path, asking_step_index); | |
| 1829 | } | |
| 1830 | ||
| 1831 | pub fn installLazyPath( | |
| 1832 | maker: *Maker, | |
| 1833 | arena: Allocator, | |
| 1834 | source: Configuration.LazyPath.Index, | |
| 1835 | dest_dir: Configuration.InstallDestDir, | |
| 1836 | asking_step_index: Configuration.Step.Index, | |
| 1837 | ) !Dir.PrevStatus { | |
| 1838 | const src_path = try resolveLazyPathIndex(maker, arena, source, asking_step_index); | |
| 1839 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); | |
| 1840 | const dest_path = try dest_dir_path.join(arena, src_path.basename()); | |
| 1841 | return installPath(maker, arena, src_path, dest_path, asking_step_index); | |
| 1842 | } | |
| 1843 | ||
| 1844 | pub fn installGenerated( | |
| 1845 | maker: *Maker, | |
| 1846 | arena: Allocator, | |
| 1847 | source: Configuration.GeneratedFileIndex, | |
| 1848 | dest_dir: Configuration.InstallDestDir, | |
| 1849 | asking_step_index: Configuration.Step.Index, | |
| 1850 | ) !Dir.PrevStatus { | |
| 1851 | const src_path = generatedPath(maker, source).*; | |
| 1852 | const dest_dir_path = try resolveInstallDir(maker, arena, dest_dir); | |
| 1853 | const dest_path = try dest_dir_path.join(arena, src_path.basename()); | |
| 1854 | return installPath(maker, arena, src_path, dest_path, asking_step_index); | |
| 1855 | } | |
| 1856 | ||
| 1857 | pub fn installPath( | |
| 1858 | maker: *Maker, | |
| 1859 | arena: Allocator, | |
| 1860 | src_path: Path, | |
| 1861 | dest_path: Path, | |
| 1862 | asking_step_index: Configuration.Step.Index, | |
| 1863 | ) !Dir.PrevStatus { | |
| 1800 | 1864 | const graph = maker.graph; |
| 1801 | 1865 | const io = graph.io; |
| 1802 | const src_path = try resolveLazyPath(maker, arena, src_lazy_path, asking_step_index); | |
| 1803 | { | |
| 1804 | const src_path_rendered = try src_path.toString(arena); | |
| 1805 | defer arena.free(src_path_rendered); | |
| 1806 | try graph.handleVerbose(.inherit, null, &.{ "install", "-C", src_path_rendered, dest_path }); | |
| 1807 | } | |
| 1808 | return Io.Dir.updateFile(src_path.root_dir.handle, io, src_path.sub_path, .cwd(), dest_path, .{}) catch |err| { | |
| 1866 | if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{ | |
| 1867 | "install", "-C", try src_path.toString(arena), try dest_path.toString(arena), | |
| 1868 | }); | |
| 1869 | return Dir.updateFile( | |
| 1870 | src_path.root_dir.handle, | |
| 1871 | io, | |
| 1872 | src_path.sub_path, | |
| 1873 | dest_path.root_dir.handle, | |
| 1874 | dest_path.sub_path, | |
| 1875 | .{}, | |
| 1876 | ) catch |err| { | |
| 1809 | 1877 | const s = stepByIndex(maker, asking_step_index); |
| 1810 | return s.fail(maker, "unable to update file from '{f}' to '{s}': {t}", .{ src_path, dest_path, err }); | |
| 1878 | return s.fail(maker, "unable to update file from {f} to {f}: {t}", .{ src_path, dest_path, err }); | |
| 1811 | 1879 | }; |
| 1812 | 1880 | } |
| 1813 | 1881 | |
| 1814 | /// Wrapper around `Io.Dir.createDirPathStatus` that handles verbose and error output. | |
| 1882 | /// Wrapper around `Dir.createDirPathStatus` that handles verbose and error output. | |
| 1815 | 1883 | pub fn installDir( |
| 1816 | 1884 | maker: *Maker, |
| 1817 | dest_path: []const u8, | |
| 1885 | arena: Allocator, | |
| 1886 | dest_path: Path, | |
| 1818 | 1887 | asking_step_index: Configuration.Step.Index, |
| 1819 | ) !Io.Dir.CreatePathStatus { | |
| 1888 | ) !Dir.CreatePathStatus { | |
| 1820 | 1889 | const graph = maker.graph; |
| 1821 | 1890 | const io = graph.io; |
| 1822 | try graph.handleVerbose(.inherit, null, &.{ "install", "-d", dest_path }); | |
| 1823 | return Io.Dir.cwd().createDirPathStatus(io, dest_path, .default_dir) catch |err| { | |
| 1891 | if (graph.verbose) try graph.handleVerbose(.inherit, null, &.{ | |
| 1892 | "install", "-d", try dest_path.toString(arena), | |
| 1893 | }); | |
| 1894 | return dest_path.root_dir.handle.createDirPathStatus(io, dest_path.sub_path, .default_dir) catch |err| { | |
| 1824 | 1895 | const s = stepByIndex(maker, asking_step_index); |
| 1825 | return s.fail(maker, "unable to create dir '{s}': {t}", .{ dest_path, err }); | |
| 1896 | return s.fail(maker, "unable to create dir {f}: {t}", .{ dest_path, err }); | |
| 1897 | }; | |
| 1898 | } | |
| 1899 | ||
| 1900 | pub fn installSymLinks( | |
| 1901 | maker: *Maker, | |
| 1902 | arena: Allocator, | |
| 1903 | output_path: Path, | |
| 1904 | compile_step_index: Configuration.Step.Index, | |
| 1905 | asking_step_index: Configuration.Step.Index, | |
| 1906 | ) !void { | |
| 1907 | const c = &maker.scanned_config.configuration; | |
| 1908 | const conf_step = compile_step_index.ptr(c); | |
| 1909 | const conf_comp = conf_step.extended.get(c.extra).compile; | |
| 1910 | const root_module = conf_comp.root_module.get(c); | |
| 1911 | const target = root_module.resolved_target.get(c).?.result.get(c); | |
| 1912 | const os_tag = target.flags.os_tag.unwrap().?; | |
| 1913 | ||
| 1914 | assert(conf_comp.flags3.kind == .lib); | |
| 1915 | assert(conf_comp.flags2.linkage == .dynamic); | |
| 1916 | assert(os_tag != .windows); | |
| 1917 | ||
| 1918 | const version = std.SemanticVersion.parse(conf_comp.version.value.?.slice(c)) catch unreachable; | |
| 1919 | const name = conf_comp.root_name.slice(c); | |
| 1920 | ||
| 1921 | const filename_major_only, const filename_name_only = if (os_tag.isDarwin()) .{ | |
| 1922 | try std.fmt.allocPrint(arena, "lib{s}.{d}.dylib", .{ name, version.major }), | |
| 1923 | try std.fmt.allocPrint(arena, "lib{s}.dylib", .{name}), | |
| 1924 | } else .{ | |
| 1925 | try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ name, version.major }), | |
| 1926 | try std.fmt.allocPrint(arena, "lib{s}.so", .{name}), | |
| 1927 | }; | |
| 1928 | ||
| 1929 | return installSymLinksInner(maker, arena, output_path, asking_step_index, filename_major_only, filename_name_only); | |
| 1930 | } | |
| 1931 | ||
| 1932 | fn installSymLinksInner( | |
| 1933 | maker: *Maker, | |
| 1934 | arena: Allocator, | |
| 1935 | output_path: Path, | |
| 1936 | asking_step_index: Configuration.Step.Index, | |
| 1937 | filename_major_only: []const u8, | |
| 1938 | filename_name_only: []const u8, | |
| 1939 | ) !void { | |
| 1940 | const io = maker.graph.io; | |
| 1941 | const step = stepByIndex(maker, asking_step_index); | |
| 1942 | const out_dir = output_path.dirname().?; | |
| 1943 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | |
| 1944 | const major_only_path = try out_dir.join(arena, filename_major_only); | |
| 1945 | output_path.root_dir.handle.symLinkAtomic(io, output_path.sub_path, major_only_path.sub_path, .{}) catch |err| { | |
| 1946 | return step.fail(maker, "unable to symlink {f} -> {f}: {t}", .{ output_path, major_only_path, err }); | |
| 1947 | }; | |
| 1948 | // sym link for libfoo.so to libfoo.so.1 | |
| 1949 | const name_only_path = try out_dir.join(arena, filename_name_only); | |
| 1950 | major_only_path.root_dir.handle.symLinkAtomic(io, major_only_path.sub_path, name_only_path.sub_path, .{}) catch |err| { | |
| 1951 | return step.fail(maker, "unable to symlink {f} -> {s}: {t}", .{ name_only_path, filename_major_only, err }); | |
| 1826 | 1952 | }; |
| 1827 | 1953 | } |
lib/compiler/Maker/Graph.zig+2-1| ... | ... | @@ -5,6 +5,7 @@ const std = @import("std"); |
| 5 | 5 | const Io = std.Io; |
| 6 | 6 | const Allocator = std.mem.Allocator; |
| 7 | 7 | const Configuration = std.Build.Configuration; |
| 8 | const Path = std.Build.Cache.Path; | |
| 8 | 9 | |
| 9 | 10 | io: Io, |
| 10 | 11 | /// Process lifetime. |
| ... | ... | @@ -16,7 +17,7 @@ global_cache_root: std.Build.Cache.Directory, |
| 16 | 17 | local_cache_root: std.Build.Cache.Directory, |
| 17 | 18 | zig_lib_directory: std.Build.Cache.Directory, |
| 18 | 19 | build_root_directory: std.Build.Cache.Directory, |
| 19 | pkg_root: std.Build.Cache.Path, | |
| 20 | pkg_root: Path, | |
| 20 | 21 | |
| 21 | 22 | debug_compiler_runtime_libs: ?std.builtin.OptimizeMode = null, |
| 22 | 23 | incremental: ?bool = null, |
lib/compiler/Maker/Step.zig+26-34| ... | ... | @@ -8,6 +8,7 @@ const std = @import("std"); |
| 8 | 8 | const Allocator = std.mem.Allocator; |
| 9 | 9 | const Cache = std.Build.Cache; |
| 10 | 10 | const Io = std.Io; |
| 11 | const Dir = std.Io.Dir; | |
| 11 | 12 | const LazyPath = std.Build.Configuration.LazyPath; |
| 12 | 13 | const Package = std.Build.Configuration.Package; |
| 13 | 14 | const Path = std.Build.Cache.Path; |
| ... | ... | @@ -19,6 +20,8 @@ const Maker = @import("../Maker.zig"); |
| 19 | 20 | |
| 20 | 21 | const Compile = @import("Step/Compile.zig"); |
| 21 | 22 | const Run = @import("Step/Run.zig"); |
| 23 | const InstallArtifact = @import("Step/InstallArtifact.zig"); | |
| 24 | const InstallFile = @import("Step/InstallFile.zig"); | |
| 22 | 25 | |
| 23 | 26 | /// Avoid false sharing. |
| 24 | 27 | _: void align(std.atomic.cache_line) = {}, |
| ... | ... | @@ -69,9 +72,9 @@ pub const Extended = union(enum) { |
| 69 | 72 | config_header: Todo, |
| 70 | 73 | fail: Todo, |
| 71 | 74 | fmt: Todo, |
| 72 | install_artifact: Todo, | |
| 75 | install_artifact: InstallArtifact, | |
| 73 | 76 | install_dir: Todo, |
| 74 | install_file: Todo, | |
| 77 | install_file: InstallFile, | |
| 75 | 78 | objcopy: Todo, |
| 76 | 79 | options: Todo, |
| 77 | 80 | remove_dir: Todo, |
| ... | ... | @@ -524,7 +527,7 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 524 | 527 | const digest = body[@sizeOf(EmitDigest)..][0..Cache.bin_digest_len]; |
| 525 | 528 | result = .{ |
| 526 | 529 | .root_dir = graph.local_cache_root, |
| 527 | .sub_path = try arena.dupe(u8, "o" ++ Io.Dir.path.sep_str ++ Cache.binToHex(digest.*)), | |
| 530 | .sub_path = try arena.dupe(u8, "o" ++ Dir.path.sep_str ++ Cache.binToHex(digest.*)), | |
| 528 | 531 | }; |
| 529 | 532 | }, |
| 530 | 533 | .file_system_inputs => { |
| ... | ... | @@ -535,14 +538,14 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 535 | 538 | while (it.next()) |prefixed_path| { |
| 536 | 539 | const prefix_index: std.zig.Server.Message.PathPrefix = @enumFromInt(prefixed_path[0] - 1); |
| 537 | 540 | const sub_path = try arena.dupe(u8, prefixed_path[1..]); |
| 538 | const sub_path_dirname = Io.Dir.path.dirname(sub_path) orelse ""; | |
| 541 | const sub_path_dirname = Dir.path.dirname(sub_path) orelse ""; | |
| 539 | 542 | switch (prefix_index) { |
| 540 | 543 | .cwd => { |
| 541 | 544 | const path: Path = .{ |
| 542 | 545 | .root_dir = .cwd(), |
| 543 | 546 | .sub_path = sub_path_dirname, |
| 544 | 547 | }; |
| 545 | try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path)); | |
| 548 | try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path)); | |
| 546 | 549 | }, |
| 547 | 550 | .zig_lib => zl: { |
| 548 | 551 | switch (conf_step.extended.get(conf.extra)) { |
| ... | ... | @@ -558,21 +561,21 @@ fn zigProcessUpdate(step_index: Configuration.Step.Index, maker: *Maker, zp: *Zi |
| 558 | 561 | .root_dir = graph.zig_lib_directory, |
| 559 | 562 | .sub_path = sub_path_dirname, |
| 560 | 563 | }; |
| 561 | try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path)); | |
| 564 | try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path)); | |
| 562 | 565 | }, |
| 563 | 566 | .local_cache => { |
| 564 | 567 | const path: Path = .{ |
| 565 | 568 | .root_dir = graph.local_cache_root, |
| 566 | 569 | .sub_path = sub_path_dirname, |
| 567 | 570 | }; |
| 568 | try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path)); | |
| 571 | try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path)); | |
| 569 | 572 | }, |
| 570 | 573 | .global_cache => { |
| 571 | 574 | const path: Path = .{ |
| 572 | 575 | .root_dir = graph.global_cache_root, |
| 573 | 576 | .sub_path = sub_path_dirname, |
| 574 | 577 | }; |
| 575 | try addWatchInputFromPath(s, maker, path, Io.Dir.path.basename(sub_path)); | |
| 578 | try addWatchInputFromPath(s, maker, path, Dir.path.basename(sub_path)); | |
| 576 | 579 | }, |
| 577 | 580 | } |
| 578 | 581 | } |
| ... | ... | @@ -680,7 +683,7 @@ fn failWithCacheError( |
| 680 | 683 | const pp = man.files.keys()[op.file_index].prefixed_path; |
| 681 | 684 | const prefix = man.cache.prefixes()[pp.prefix].path orelse ""; |
| 682 | 685 | return s.fail(maker, "failed to check cache: '{s}{c}{s}' {t} {t}", .{ |
| 683 | prefix, Io.Dir.path.sep, pp.sub_path, man.diagnostic, op.err, | |
| 686 | prefix, Dir.path.sep, pp.sub_path, man.diagnostic, op.err, | |
| 684 | 687 | }); |
| 685 | 688 | }, |
| 686 | 689 | }, |
| ... | ... | @@ -718,14 +721,14 @@ fn setWatchInputsFromManifest(s: *Step, maker: *Maker, man: *Cache.Manifest) !vo |
| 718 | 721 | const sub_path = try arena.dupe(u8, file.prefixed_path.sub_path); |
| 719 | 722 | try addWatchInputFromPath(s, maker, .{ |
| 720 | 723 | .root_dir = prefixes[file.prefixed_path.prefix], |
| 721 | .sub_path = Io.Dir.path.dirname(sub_path) orelse "", | |
| 722 | }, Io.Dir.path.basename(sub_path)); | |
| 724 | .sub_path = Dir.path.dirname(sub_path) orelse "", | |
| 725 | }, Dir.path.basename(sub_path)); | |
| 723 | 726 | } |
| 724 | 727 | } |
| 725 | 728 | |
| 726 | 729 | /// For steps that have a single input that never changes when re-running `make`. |
| 727 | pub fn singleUnchangingWatchInput(step: *Step, maker: *Maker, lazy_path: LazyPath) Allocator.Error!void { | |
| 728 | if (!step.inputs.populated()) try step.addWatchInput(maker, lazy_path); | |
| 730 | pub fn singleUnchangingWatchInput(step: *Step, maker: *Maker, arena: Allocator, lazy_path: LazyPath) Allocator.Error!void { | |
| 731 | if (!step.inputs.populated()) try step.addWatchInput(maker, arena, lazy_path); | |
| 729 | 732 | } |
| 730 | 733 | |
| 731 | 734 | pub fn clearWatchInputs(step: *Step, maker: *Maker) void { |
| ... | ... | @@ -733,19 +736,15 @@ pub fn clearWatchInputs(step: *Step, maker: *Maker) void { |
| 733 | 736 | } |
| 734 | 737 | |
| 735 | 738 | /// Places a *file* dependency on the path. |
| 736 | pub fn addWatchInput(step: *Step, maker: *Maker, lazy_file: LazyPath) Allocator.Error!void { | |
| 739 | pub fn addWatchInput(step: *Step, maker: *Maker, arena: Allocator, lazy_file: LazyPath) Allocator.Error!void { | |
| 740 | const conf = &maker.scanned_config.configuration; | |
| 737 | 741 | switch (lazy_file) { |
| 738 | .src_path => |src_path| try addWatchInputFromBuilder(step, src_path.owner, src_path.sub_path), | |
| 739 | .dependency => |d| try addWatchInputFromBuilder(step, d.dependency.builder, d.sub_path), | |
| 740 | .cwd_relative => |path_string| { | |
| 741 | try addWatchInputFromPath(step, maker, .{ | |
| 742 | .root_dir = .{ | |
| 743 | .path = null, | |
| 744 | .handle = Io.Dir.cwd(), | |
| 745 | }, | |
| 746 | .sub_path = Io.Dir.path.dirname(path_string) orelse "", | |
| 747 | }, Io.Dir.path.basename(path_string)); | |
| 742 | .source_path => |source_path| { | |
| 743 | const sub_path = source_path.sub_path.slice(conf); | |
| 744 | const pkg_path = try maker.packagePath(arena, source_path.owner, sub_path); | |
| 745 | try addWatchInputPath(step, maker, pkg_path); | |
| 748 | 746 | }, |
| 747 | .relative => |relative| try addWatchInputPath(step, maker, maker.relativePath(relative)), | |
| 749 | 748 | // Nothing to watch because this dependency edge is modeled instead via `dependants`. |
| 750 | 749 | .generated => {}, |
| 751 | 750 | } |
| ... | ... | @@ -766,7 +765,7 @@ pub fn addDirectoryWatchInput(step: *Step, lazy_directory: LazyPath) Allocator.E |
| 766 | 765 | try addDirectoryWatchInputFromPath(step, .{ |
| 767 | 766 | .root_dir = .{ |
| 768 | 767 | .path = null, |
| 769 | .handle = Io.Dir.cwd(), | |
| 768 | .handle = .cwd(), | |
| 770 | 769 | }, |
| 771 | 770 | .sub_path = path_string, |
| 772 | 771 | }); |
| ... | ... | @@ -789,13 +788,6 @@ pub fn addDirectoryWatchInputFromPath(step: *Step, maker: *Maker, path: Path) !v |
| 789 | 788 | return addWatchInputFromPath(step, maker, path, "."); |
| 790 | 789 | } |
| 791 | 790 | |
| 792 | fn addWatchInputFromBuilder(step: *Step, maker: *Maker, package: Package, sub_path: []const u8) !void { | |
| 793 | return addWatchInputFromPath(step, maker, .{ | |
| 794 | .root_dir = package.build_root, | |
| 795 | .sub_path = Io.Dir.path.dirname(sub_path) orelse "", | |
| 796 | }, Io.Dir.path.basename(sub_path)); | |
| 797 | } | |
| 798 | ||
| 799 | 791 | fn addDirectoryWatchInputFromBuilder(step: *Step, package: Package, sub_path: []const u8) !void { |
| 800 | 792 | return addDirectoryWatchInputFromPath(step, .{ |
| 801 | 793 | .root_dir = package.build_root, |
| ... | ... | @@ -806,8 +798,8 @@ fn addDirectoryWatchInputFromBuilder(step: *Step, package: Package, sub_path: [] |
| 806 | 798 | fn addWatchInputPath(step: *Step, maker: *Maker, path: Path) Allocator.Error!void { |
| 807 | 799 | return addWatchInputFromPath(step, maker, .{ |
| 808 | 800 | .root_dir = path.root_dir, |
| 809 | .sub_path = Io.Dir.path.dirname(path.sub_path) orelse "", | |
| 810 | }, Io.Dir.path.basename(path.sub_path)); | |
| 801 | .sub_path = Dir.path.dirname(path.sub_path) orelse "", | |
| 802 | }, Dir.path.basename(path.sub_path)); | |
| 811 | 803 | } |
| 812 | 804 | |
| 813 | 805 | fn addWatchInputFromPath(step: *Step, maker: *Maker, directory: Path, basename: []const u8) Allocator.Error!void { |
lib/compiler/Maker/Step/Compile.zig+6-39| ... | ... | @@ -28,7 +28,7 @@ pub fn make( |
| 28 | 28 | progress_node: std.Progress.Node, |
| 29 | 29 | ) Step.ExtendedMakeError!void { |
| 30 | 30 | const graph = maker.graph; |
| 31 | const step = maker.stepByIndex(compile_index); | |
| 31 | const arena = graph.arena; // TODO don't leak into process arena | |
| 32 | 32 | const conf = &maker.scanned_config.configuration; |
| 33 | 33 | const conf_step = compile_index.ptr(conf); |
| 34 | 34 | const conf_comp = conf_step.extended.get(conf.extra).compile; |
| ... | ... | @@ -69,16 +69,12 @@ pub fn make( |
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | if (conf_comp.flags3.kind == .lib and conf_comp.flags2.linkage == .dynamic and |
| 72 | conf_comp.version.value != null and conf_comp.generated_bin.value != null and | |
| 73 | target.flags.os_tag != .windows) | |
| 72 | conf_comp.version.value != null and target.flags.os_tag != .windows) | |
| 74 | 73 | { |
| 75 | if (true) @panic("TODO"); | |
| 76 | try doAtomicSymLinks( | |
| 77 | step, | |
| 78 | conf_comp.getEmittedBin().getPath2(step), | |
| 79 | conf_comp.major_only_filename.?, | |
| 80 | conf_comp.name_only_filename.?, | |
| 81 | ); | |
| 74 | if (conf_comp.generated_bin.value) |generated_bin| { | |
| 75 | const full_dest_path = maker.generatedPath(generated_bin).*; | |
| 76 | try maker.installSymLinks(arena, full_dest_path, compile_index, compile_index); | |
| 77 | } | |
| 82 | 78 | } |
| 83 | 79 | } |
| 84 | 80 | |
| ... | ... | @@ -964,35 +960,6 @@ pub fn rebuildInFuzzMode(compile: *Compile, maker: *Maker, progress_node: std.Pr |
| 964 | 960 | return maybe_output_bin_path.?; |
| 965 | 961 | } |
| 966 | 962 | |
| 967 | pub fn doAtomicSymLinks( | |
| 968 | step: *Step, | |
| 969 | maker: *Maker, | |
| 970 | output_path: []const u8, | |
| 971 | filename_major_only: []const u8, | |
| 972 | filename_name_only: []const u8, | |
| 973 | ) !void { | |
| 974 | const graph = maker.graph; | |
| 975 | const arena = graph.arena; // TODO don't leak into process arena | |
| 976 | const io = graph.io; | |
| 977 | const out_dir = Dir.path.dirname(output_path) orelse "."; | |
| 978 | const out_basename = Dir.path.basename(output_path); | |
| 979 | // sym link for libfoo.so.1 to libfoo.so.1.2.3 | |
| 980 | const major_only_path = try Dir.path.join(arena, &.{ out_dir, filename_major_only }); | |
| 981 | const cwd: Io.Dir = .cwd(); | |
| 982 | cwd.symLinkAtomic(io, out_basename, major_only_path, .{}) catch |err| { | |
| 983 | return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{ | |
| 984 | major_only_path, out_basename, err, | |
| 985 | }); | |
| 986 | }; | |
| 987 | // sym link for libfoo.so to libfoo.so.1 | |
| 988 | const name_only_path = try Dir.path.join(arena, &.{ out_dir, filename_name_only }); | |
| 989 | cwd.symLinkAtomic(io, filename_major_only, name_only_path, .{}) catch |err| { | |
| 990 | return step.fail(maker, "unable to symlink {s} -> {s}: {t}", .{ | |
| 991 | name_only_path, filename_major_only, err, | |
| 992 | }); | |
| 993 | }; | |
| 994 | } | |
| 995 | ||
| 996 | 963 | pub const PkgConfigError = error{ |
| 997 | 964 | PkgConfigCrashed, |
| 998 | 965 | PkgConfigFailed, |
lib/compiler/Maker/Step/InstallArtifact.zig+88-49| ... | ... | @@ -1,88 +1,127 @@ |
| 1 | const InstallArtifact = @This(); | |
| 1 | 2 | |
| 2 | fn make(step: *Step, options: Step.MakeOptions) !void { | |
| 3 | _ = options; | |
| 4 | const install_artifact: *InstallArtifact = @fieldParentPtr("step", step); | |
| 5 | const b = step.owner; | |
| 6 | const io = b.graph.io; | |
| 3 | const std = @import("std"); | |
| 4 | const Io = std.Io; | |
| 5 | const Configuration = std.Build.Configuration; | |
| 6 | const assert = std.debug.assert; | |
| 7 | ||
| 8 | const Step = @import("../Step.zig"); | |
| 9 | const Maker = @import("../../Maker.zig"); | |
| 10 | ||
| 11 | pub fn make( | |
| 12 | install_artifact: *InstallArtifact, | |
| 13 | step_index: Configuration.Step.Index, | |
| 14 | maker: *Maker, | |
| 15 | progress_node: std.Progress.Node, | |
| 16 | ) Step.ExtendedMakeError!void { | |
| 17 | _ = install_artifact; | |
| 18 | _ = progress_node; | |
| 19 | const step = maker.stepByIndex(step_index); | |
| 20 | const conf = &maker.scanned_config.configuration; | |
| 21 | const graph = maker.graph; | |
| 22 | const arena = graph.arena; // TODO don't leak into process arena | |
| 23 | const io = graph.io; | |
| 24 | const conf_step = step_index.ptr(conf); | |
| 25 | const conf_ia = conf_step.extended.get(conf.extra).install_artifact; | |
| 26 | const compile_step_index = conf_step.deps.get(conf).steps.slice[0]; | |
| 27 | const conf_comp_step = compile_step_index.ptr(conf); | |
| 28 | const conf_comp = conf_comp_step.extended.get(conf.extra).compile; | |
| 29 | const root_module = conf_comp.root_module.get(conf); | |
| 30 | const target = root_module.resolved_target.get(conf).?.result.get(conf); | |
| 7 | 31 | |
| 8 | 32 | var all_cached = true; |
| 9 | 33 | |
| 10 | if (install_artifact.dest_dir) |dest_dir| { | |
| 11 | const full_dest_path = b.getInstallPath(dest_dir, install_artifact.dest_sub_path); | |
| 12 | const p = try step.installFile(install_artifact.emitted_bin.?, full_dest_path); | |
| 13 | all_cached = all_cached and p == .fresh; | |
| 34 | if (conf_ia.bin_dir.value) |bin_dir| { | |
| 35 | if (conf_comp.generated_bin.value) |generated_bin| { | |
| 36 | const bin_sub_path = if (conf_ia.bin_sub_path.value) |s| s.slice(conf) else try std.zig.binNameAlloc(arena, .{ | |
| 37 | .root_name = conf_comp.root_name.slice(conf), | |
| 38 | .cpu_arch = target.flags.cpu_arch.unwrap().?, | |
| 39 | .os_tag = target.flags.os_tag.unwrap().?, | |
| 40 | .ofmt = target.flags.object_format.unwrap().?, | |
| 41 | .abi = target.flags.abi.unwrap().?, | |
| 42 | .output_mode = conf_comp.flags3.kind.toOutputMode(), | |
| 43 | .link_mode = conf_comp.flags2.linkage.unwrap(), | |
| 44 | .version = v: { | |
| 45 | const string = conf_comp.version.value orelse break :v null; | |
| 46 | const slice = string.slice(conf); | |
| 47 | break :v std.SemanticVersion.parse(slice) catch @panic("bad semver string"); | |
| 48 | }, | |
| 49 | }); | |
| 50 | const dest_dir = try maker.resolveInstallDir(arena, bin_dir); | |
| 51 | const dest_path = try dest_dir.join(arena, bin_sub_path); | |
| 52 | const src_path = maker.generatedPath(generated_bin).*; | |
| 53 | const p = try maker.installPath(arena, src_path, dest_path, step_index); | |
| 54 | all_cached = all_cached and p == .fresh; | |
| 14 | 55 | |
| 15 | if (install_artifact.dylib_symlinks) |dls| { | |
| 16 | try Step.Compile.doAtomicSymLinks(step, full_dest_path, dls.major_only_filename, dls.name_only_filename); | |
| 56 | if (conf_ia.flags.dylib_symlinks) | |
| 57 | try maker.installSymLinks(arena, dest_path, compile_step_index, step_index); | |
| 17 | 58 | } |
| 18 | ||
| 19 | install_artifact.artifact.installed_path = full_dest_path; | |
| 20 | 59 | } |
| 21 | 60 | |
| 22 | if (install_artifact.compiler_rt_dyn_lib_dir) |compiler_rt_dir| { | |
| 23 | const full_compiler_rt_path = b.getInstallPath(compiler_rt_dir, install_artifact.emitted_compiler_rt_dyn_lib.?.basename(b, step)); | |
| 24 | const p = try step.installFile(install_artifact.emitted_compiler_rt_dyn_lib.?, full_compiler_rt_path); | |
| 25 | all_cached = all_cached and p == .fresh; | |
| 61 | if (conf_ia.implib_dir.value) |implib_dir| { | |
| 62 | if (conf_comp.generated_implib.value) |generated_implib| { | |
| 63 | const p = try maker.installGenerated(arena, generated_implib, implib_dir, step_index); | |
| 64 | all_cached = all_cached and p == .fresh; | |
| 65 | } | |
| 26 | 66 | } |
| 27 | 67 | |
| 28 | if (install_artifact.implib_dir) |implib_dir| { | |
| 29 | const full_implib_path = b.getInstallPath(implib_dir, install_artifact.emitted_implib.?.basename(b, step)); | |
| 30 | const p = try step.installFile(install_artifact.emitted_implib.?, full_implib_path); | |
| 31 | all_cached = all_cached and p == .fresh; | |
| 68 | if (conf_ia.pdb_dir.value) |pdb_dir| { | |
| 69 | if (conf_comp.generated_pdb.value) |generated_pdb| { | |
| 70 | const p = try maker.installGenerated(arena, generated_pdb, pdb_dir, step_index); | |
| 71 | all_cached = all_cached and p == .fresh; | |
| 72 | } | |
| 32 | 73 | } |
| 33 | 74 | |
| 34 | if (install_artifact.pdb_dir) |pdb_dir| { | |
| 35 | const full_pdb_path = b.getInstallPath(pdb_dir, install_artifact.emitted_pdb.?.basename(b, step)); | |
| 36 | const p = try step.installFile(install_artifact.emitted_pdb.?, full_pdb_path); | |
| 37 | all_cached = all_cached and p == .fresh; | |
| 38 | } | |
| 75 | if (conf_ia.h_dir.value) |h_dir| { | |
| 76 | const h_prefix = try maker.resolveInstallDir(arena, h_dir); | |
| 39 | 77 | |
| 40 | if (install_artifact.h_dir) |h_dir| { | |
| 41 | if (install_artifact.emitted_h) |emitted_h| { | |
| 42 | const full_h_path = b.getInstallPath(h_dir, emitted_h.basename(b, step)); | |
| 43 | const p = try step.installFile(emitted_h, full_h_path); | |
| 78 | if (conf_comp.generated_h.value) |generated_h| { | |
| 79 | const p = try maker.installGenerated(arena, generated_h, h_dir, step_index); | |
| 44 | 80 | all_cached = all_cached and p == .fresh; |
| 45 | 81 | } |
| 46 | 82 | |
| 47 | for (install_artifact.artifact.installed_headers.items) |installation| switch (installation) { | |
| 83 | for (conf_comp.installed_headers.slice) |installation| switch (installation.get(conf.extra)) { | |
| 48 | 84 | .file => |file| { |
| 49 | const full_h_path = b.getInstallPath(h_dir, file.dest_rel_path); | |
| 50 | const p = try step.installFile(file.source, full_h_path); | |
| 85 | const src_path = try maker.resolveLazyPathIndex(arena, file.source, step_index); | |
| 86 | const dest_path = try h_prefix.join(arena, file.dest_sub_path.slice(conf)); | |
| 87 | const p = try maker.installPath(arena, src_path, dest_path, step_index); | |
| 51 | 88 | all_cached = all_cached and p == .fresh; |
| 52 | 89 | }, |
| 53 | 90 | .directory => |dir| { |
| 54 | const src_dir_path = dir.source.getPath3(b, step); | |
| 55 | const full_h_prefix = b.getInstallPath(h_dir, dir.dest_rel_path); | |
| 91 | const src_dir_path = try maker.resolveLazyPathIndex(arena, dir.source, step_index); | |
| 92 | const full_h_prefix = try h_prefix.join(arena, dir.dest_sub_path.slice(conf)); | |
| 56 | 93 | |
| 57 | 94 | var src_dir = src_dir_path.root_dir.handle.openDir(io, src_dir_path.subPathOrDot(), .{ .iterate = true }) catch |err| { |
| 58 | return step.fail("unable to open source directory '{f}': {s}", .{ | |
| 59 | src_dir_path, @errorName(err), | |
| 60 | }); | |
| 95 | return step.fail(maker, "unable to open source directory {f}: {t}", .{ src_dir_path, err }); | |
| 61 | 96 | }; |
| 62 | 97 | defer src_dir.close(io); |
| 63 | 98 | |
| 64 | var it = try src_dir.walk(b.allocator); | |
| 65 | next_entry: while (try it.next(io)) |entry| { | |
| 66 | for (dir.options.exclude_extensions) |ext| { | |
| 67 | if (std.mem.endsWith(u8, entry.path, ext)) continue :next_entry; | |
| 99 | var it = try src_dir.walk(arena); | |
| 100 | next_entry: while (it.next(io) catch |err| switch (err) { | |
| 101 | error.Canceled, error.OutOfMemory => |e| return e, | |
| 102 | else => |e| return step.fail(maker, "failed to iterate directory {f}: {t}", .{ src_dir_path, e }), | |
| 103 | }) |entry| { | |
| 104 | for (dir.exclude_extensions.slice) |ext| { | |
| 105 | if (std.mem.endsWith(u8, entry.path, ext.slice(conf))) continue :next_entry; | |
| 68 | 106 | } |
| 69 | if (dir.options.include_extensions) |incs| { | |
| 70 | for (incs) |inc| { | |
| 71 | if (std.mem.endsWith(u8, entry.path, inc)) break; | |
| 107 | if (dir.flags.include_extensions) { | |
| 108 | for (dir.include_extensions.slice) |inc| { | |
| 109 | if (std.mem.endsWith(u8, entry.path, inc.slice(conf))) break; | |
| 72 | 110 | } else { |
| 73 | 111 | continue :next_entry; |
| 74 | 112 | } |
| 75 | 113 | } |
| 76 | 114 | |
| 77 | const full_dest_path = b.pathJoin(&.{ full_h_prefix, entry.path }); | |
| 115 | const full_dest_path = try full_h_prefix.join(arena, entry.path); | |
| 78 | 116 | switch (entry.kind) { |
| 79 | 117 | .directory => { |
| 80 | try Step.handleVerbose(b, .inherit, &.{ "install", "-d", full_dest_path }); | |
| 81 | const p = try step.installDir(full_dest_path); | |
| 118 | const p = try maker.installDir(arena, full_dest_path, step_index); | |
| 82 | 119 | all_cached = all_cached and p == .existed; |
| 83 | 120 | }, |
| 84 | 121 | .file => { |
| 85 | const p = try step.installFile(try dir.source.join(b.allocator, entry.path), full_dest_path); | |
| 122 | const entry_dir_path = try maker.resolveLazyPathIndex(arena, dir.source, step_index); | |
| 123 | const entry_path = try entry_dir_path.join(arena, entry.path); | |
| 124 | const p = try maker.installPath(arena, entry_path, full_dest_path, step_index); | |
| 86 | 125 | all_cached = all_cached and p == .fresh; |
| 87 | 126 | }, |
| 88 | 127 | else => continue, |
lib/compiler/Maker/Step/InstallFile.zig created+25| ... | ... | @@ -0,0 +1,25 @@ |
| 1 | const InstallFile = @This(); | |
| 2 | ||
| 3 | const std = @import("std"); | |
| 4 | const Configuration = std.Build.Configuration; | |
| 5 | ||
| 6 | const Step = @import("../Step.zig"); | |
| 7 | const Maker = @import("../../Maker.zig"); | |
| 8 | ||
| 9 | pub fn make( | |
| 10 | install_file: *InstallFile, | |
| 11 | step_index: Configuration.Step.Index, | |
| 12 | maker: *Maker, | |
| 13 | progress_node: std.Progress.Node, | |
| 14 | ) Step.ExtendedMakeError!void { | |
| 15 | _ = install_file; | |
| 16 | _ = progress_node; | |
| 17 | const arena = maker.graph.arena; // TODO don't leak into process arena | |
| 18 | const step = maker.stepByIndex(step_index); | |
| 19 | const conf = &maker.scanned_config.configuration; | |
| 20 | const conf_step = step_index.ptr(conf); | |
| 21 | const conf_if = conf_step.extended.get(conf.extra).install_file; | |
| 22 | try step.singleUnchangingWatchInput(maker, arena, conf_if.source.get(conf)); | |
| 23 | const p = try maker.installLazyPathSub(arena, conf_if.source, conf_if.dest_dir, conf_if.dest_sub_path.slice(conf), step_index); | |
| 24 | step.result_cached = p == .fresh; | |
| 25 | } |
lib/compiler/configurer.zig+23-12| ... | ... | @@ -739,21 +739,28 @@ fn serialize(b: *std.Build, wc: *Configuration.Wip, writer: *Io.Writer) !void { |
| 739 | 739 | const ia: *Step.InstallArtifact = @fieldParentPtr("step", step); |
| 740 | 740 | break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallArtifact, .{ |
| 741 | 741 | .flags = .{ |
| 742 | .dylib_symlinks = ia.dylib_symlinks != null, | |
| 742 | .dylib_symlinks = ia.dylib_symlinks, | |
| 743 | .bin_dir = ia.dest_dir != null, | |
| 744 | .implib_dir = ia.implib_dir != null, | |
| 745 | .pdb_dir = ia.pdb_dir != null, | |
| 746 | .h_dir = ia.h_dir != null, | |
| 747 | .bin_sub_path = ia.dest_sub_path != null, | |
| 743 | 748 | }, |
| 744 | .dest_dir = try addInstallDir(wc, ia.dest_dir), | |
| 745 | .dest_sub_path = try wc.addString(ia.dest_sub_path), | |
| 746 | .emitted_bin = try s.addOptionalLazyPathEnum(ia.emitted_bin), | |
| 747 | .implib_dir = try addInstallDir(wc, ia.implib_dir), | |
| 748 | .emitted_implib = try s.addOptionalLazyPathEnum(ia.emitted_implib), | |
| 749 | .pdb_dir = try addInstallDir(wc, ia.pdb_dir), | |
| 750 | .emitted_pdb = try s.addOptionalLazyPathEnum(ia.emitted_pdb), | |
| 751 | .h_dir = try addInstallDir(wc, ia.h_dir), | |
| 752 | .emitted_h = try s.addOptionalLazyPathEnum(ia.emitted_h), | |
| 753 | .artifact = s.stepIndex(&ia.artifact.step), | |
| 749 | .bin_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.dest_dir) }, | |
| 750 | .implib_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.implib_dir) }, | |
| 751 | .pdb_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.pdb_dir) }, | |
| 752 | .h_dir = .{ .value = try addInstallDirDefaultNull(wc, ia.h_dir) }, | |
| 753 | .bin_sub_path = .{ .value = try s.addOptionalString(ia.dest_sub_path) }, | |
| 754 | }))); | |
| 755 | }, | |
| 756 | .install_file => e: { | |
| 757 | const sif: *Step.InstallFile = @fieldParentPtr("step", step); | |
| 758 | break :e @enumFromInt(try wc.addExtra(@as(Configuration.Step.InstallFile, .{ | |
| 759 | .source = try s.addLazyPath(sif.source), | |
| 760 | .dest_dir = try addInstallDir(wc, sif.dir), | |
| 761 | .dest_sub_path = try wc.addString(sif.dest_rel_path), | |
| 754 | 762 | }))); |
| 755 | 763 | }, |
| 756 | .install_file => @panic("TODO"), | |
| 757 | 764 | .install_dir => @panic("TODO"), |
| 758 | 765 | .remove_dir => @panic("TODO"), |
| 759 | 766 | .fail => @panic("TODO"), |
| ... | ... | @@ -851,6 +858,10 @@ fn addInstallDir(wc: *Configuration.Wip, install_dir: ?std.Build.InstallDir) !Co |
| 851 | 858 | } |
| 852 | 859 | } |
| 853 | 860 | |
| 861 | fn addInstallDirDefaultNull(wc: *Configuration.Wip, install_dir: ?std.Build.InstallDir) !?Configuration.InstallDestDir { | |
| 862 | return try addInstallDir(wc, install_dir orelse return null); | |
| 863 | } | |
| 864 | ||
| 854 | 865 | /// If the given `Step` is a `Step.Compile`, adds any dependencies for that step which |
| 855 | 866 | /// are implied by the module graph rooted at `step.cast(Step.Compile).?.root_module`. |
| 856 | 867 | fn createModuleDependenciesForStep(step: *Step) Allocator.Error!void { |
lib/std/Build/Cache/Path.zig+7| ... | ... | @@ -213,6 +213,13 @@ pub fn stem(p: Path) []const u8 { |
| 213 | 213 | return fs.path.stem(p.sub_path); |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | pub fn dirname(p: Path) ?Path { | |
| 217 | return .{ | |
| 218 | .root_dir = p.root_dir, | |
| 219 | .sub_path = fs.path.dirname(p.subPathOpt() orelse return null) orelse "", | |
| 220 | }; | |
| 221 | } | |
| 222 | ||
| 216 | 223 | pub fn basename(p: Path) []const u8 { |
| 217 | 224 | return fs.path.basename(p.sub_path); |
| 218 | 225 | } |
lib/std/Build/Configuration.zig+47-20| ... | ... | @@ -478,29 +478,25 @@ pub const Step = extern struct { |
| 478 | 478 | }; |
| 479 | 479 | }; |
| 480 | 480 | |
| 481 | /// The first dependency step index will be the compile step whose | |
| 482 | /// artifacts are being installed with this step. | |
| 481 | 483 | pub const InstallArtifact = struct { |
| 482 | 484 | flags: @This().Flags, |
| 483 | ||
| 484 | dest_dir: InstallDestDir, | |
| 485 | dest_sub_path: String, | |
| 486 | emitted_bin: LazyPath.OptionalIndex, | |
| 487 | ||
| 488 | implib_dir: InstallDestDir, | |
| 489 | emitted_implib: LazyPath.OptionalIndex, | |
| 490 | ||
| 491 | pdb_dir: InstallDestDir, | |
| 492 | emitted_pdb: LazyPath.OptionalIndex, | |
| 493 | ||
| 494 | h_dir: InstallDestDir, | |
| 495 | emitted_h: LazyPath.OptionalIndex, | |
| 496 | ||
| 497 | /// Always a compile step. | |
| 498 | artifact: Step.Index, | |
| 485 | bin_dir: Storage.FlagOptional(.flags, .bin_dir, InstallDestDir), | |
| 486 | implib_dir: Storage.FlagOptional(.flags, .implib_dir, InstallDestDir), | |
| 487 | pdb_dir: Storage.FlagOptional(.flags, .pdb_dir, InstallDestDir), | |
| 488 | h_dir: Storage.FlagOptional(.flags, .h_dir, InstallDestDir), | |
| 489 | bin_sub_path: Storage.FlagOptional(.flags, .bin_sub_path, String), | |
| 499 | 490 | |
| 500 | 491 | pub const Flags = packed struct(u32) { |
| 501 | 492 | tag: Tag = .install_artifact, |
| 502 | 493 | dylib_symlinks: bool, |
| 503 | _: u26 = 0, | |
| 494 | bin_dir: bool, | |
| 495 | implib_dir: bool, | |
| 496 | pdb_dir: bool, | |
| 497 | h_dir: bool, | |
| 498 | bin_sub_path: bool, | |
| 499 | _: u21 = 0, | |
| 504 | 500 | }; |
| 505 | 501 | }; |
| 506 | 502 | |
| ... | ... | @@ -790,6 +786,14 @@ pub const Step = extern struct { |
| 790 | 786 | .@"test", .test_obj => true, |
| 791 | 787 | }; |
| 792 | 788 | } |
| 789 | ||
| 790 | pub fn toOutputMode(kind: Kind) std.builtin.OutputMode { | |
| 791 | return switch (kind) { | |
| 792 | .exe, .@"test" => .Exe, | |
| 793 | .lib => .Lib, | |
| 794 | .obj, .test_obj => .Obj, | |
| 795 | }; | |
| 796 | } | |
| 793 | 797 | }; |
| 794 | 798 | pub const Subsystem = enum(u4) { |
| 795 | 799 | console, |
| ... | ... | @@ -991,7 +995,10 @@ pub const Step = extern struct { |
| 991 | 995 | }; |
| 992 | 996 | |
| 993 | 997 | pub const InstallFile = struct { |
| 994 | flags: @This().Flags, | |
| 998 | flags: @This().Flags = .{}, | |
| 999 | source: LazyPath.Index, | |
| 1000 | dest_dir: InstallDestDir, | |
| 1001 | dest_sub_path: String, | |
| 995 | 1002 | |
| 996 | 1003 | pub const Flags = packed struct(u32) { |
| 997 | 1004 | tag: Tag = .install_file, |
| ... | ... | @@ -1434,6 +1441,25 @@ pub const InstallDestDir = enum(u32) { |
| 1434 | 1441 | assert(@intFromEnum(sub_path) < @intFromEnum(InstallDestDir.none)); |
| 1435 | 1442 | return @enumFromInt(@intFromEnum(sub_path)); |
| 1436 | 1443 | } |
| 1444 | ||
| 1445 | pub const Unpacked = union(enum) { | |
| 1446 | prefix, | |
| 1447 | lib, | |
| 1448 | bin, | |
| 1449 | header, | |
| 1450 | sub_path: String, | |
| 1451 | }; | |
| 1452 | ||
| 1453 | pub fn unpack(this: @This()) ?Unpacked { | |
| 1454 | return switch (this) { | |
| 1455 | .none => null, | |
| 1456 | .prefix => .prefix, | |
| 1457 | .lib => .lib, | |
| 1458 | .bin => .bin, | |
| 1459 | .header => .header, | |
| 1460 | _ => .{ .sub_path = @enumFromInt(@intFromEnum(this)) }, | |
| 1461 | }; | |
| 1462 | } | |
| 1437 | 1463 | }; |
| 1438 | 1464 | |
| 1439 | 1465 | /// Points into `string_bytes`, null-terminated. |
| ... | ... | @@ -2366,7 +2392,8 @@ pub const Storage = enum { |
| 2366 | 2392 | else => comptime unreachable, |
| 2367 | 2393 | }, |
| 2368 | 2394 | .auto => switch (Field.storage) { |
| 2369 | .flag_optional, .enum_optional, .extended => 1, | |
| 2395 | .flag_optional, .enum_optional => (@sizeOf(Field.Value) + 3) / 4, | |
| 2396 | .extended => 1, | |
| 2370 | 2397 | .length_prefixed_list, |
| 2371 | 2398 | .flag_length_prefixed_list, |
| 2372 | 2399 | .flag_list, |
| ... | ... | @@ -2520,7 +2547,7 @@ pub const LoadError = Io.Reader.Error || Allocator.Error; |
| 2520 | 2547 | |
| 2521 | 2548 | pub fn load(arena: Allocator, reader: *Io.Reader) LoadError!Configuration { |
| 2522 | 2549 | const header = try reader.takeStruct(Header, .little); |
| 2523 | var result: Configuration = .{ | |
| 2550 | const result: Configuration = .{ | |
| 2524 | 2551 | .string_bytes = try arena.alloc(u8, header.string_bytes_len), |
| 2525 | 2552 | .steps = try arena.alloc(Step, header.steps_len), |
| 2526 | 2553 | .path_deps_sub = try arena.alloc(String, header.path_deps_len), |
lib/std/Build/Step/Compile.zig-35| ... | ... | @@ -26,12 +26,9 @@ name: []const u8, |
| 26 | 26 | linker_script: ?LazyPath = null, |
| 27 | 27 | version_script: ?LazyPath = null, |
| 28 | 28 | out_filename: []const u8, |
| 29 | out_lib_filename: []const u8, | |
| 30 | 29 | linkage: ?std.builtin.LinkMode = null, |
| 31 | 30 | version: ?std.SemanticVersion, |
| 32 | 31 | kind: Kind, |
| 33 | major_only_filename: ?[]const u8, | |
| 34 | name_only_filename: ?[]const u8, | |
| 35 | 32 | formatted_panics: ?bool = null, |
| 36 | 33 | compress_debug_sections: std.zig.CompressDebugSections = .none, |
| 37 | 34 | verbose_link: bool, |
| ... | ... | @@ -413,9 +410,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 413 | 410 | }), |
| 414 | 411 | .version = options.version, |
| 415 | 412 | .out_filename = out_filename, |
| 416 | .out_lib_filename = undefined, | |
| 417 | .major_only_filename = null, | |
| 418 | .name_only_filename = null, | |
| 419 | 413 | .installed_headers = .empty, |
| 420 | 414 | .zig_lib_dir = null, |
| 421 | 415 | .exec_cmd_args = null, |
| ... | ... | @@ -463,35 +457,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile { |
| 463 | 457 | lp.addStepDependencies(&compile.step); |
| 464 | 458 | } |
| 465 | 459 | |
| 466 | if (compile.kind == .lib) { | |
| 467 | if (compile.linkage != null and compile.linkage.? == .static) { | |
| 468 | compile.out_lib_filename = compile.out_filename; | |
| 469 | } else if (compile.version) |version| { | |
| 470 | if (target.os.tag.isDarwin()) { | |
| 471 | compile.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{ | |
| 472 | compile.name, | |
| 473 | version.major, | |
| 474 | }); | |
| 475 | compile.name_only_filename = owner.fmt("lib{s}.dylib", .{compile.name}); | |
| 476 | compile.out_lib_filename = compile.out_filename; | |
| 477 | } else if (target.os.tag == .windows) { | |
| 478 | compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name}); | |
| 479 | } else { | |
| 480 | compile.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ compile.name, version.major }); | |
| 481 | compile.name_only_filename = owner.fmt("lib{s}.so", .{compile.name}); | |
| 482 | compile.out_lib_filename = compile.out_filename; | |
| 483 | } | |
| 484 | } else { | |
| 485 | if (target.os.tag.isDarwin()) { | |
| 486 | compile.out_lib_filename = compile.out_filename; | |
| 487 | } else if (target.os.tag == .windows) { | |
| 488 | compile.out_lib_filename = owner.fmt("{s}.lib", .{compile.name}); | |
| 489 | } else { | |
| 490 | compile.out_lib_filename = compile.out_filename; | |
| 491 | } | |
| 492 | } | |
| 493 | } | |
| 494 | ||
| 495 | 460 | return compile; |
| 496 | 461 | } |
| 497 | 462 |
lib/std/Build/Step/InstallArtifact.zig+22-36| ... | ... | @@ -8,7 +8,7 @@ const LazyPath = std.Build.LazyPath; |
| 8 | 8 | step: Step, |
| 9 | 9 | |
| 10 | 10 | dest_dir: ?InstallDir, |
| 11 | dest_sub_path: []const u8, | |
| 11 | dest_sub_path: ?[]const u8, | |
| 12 | 12 | emitted_bin: ?LazyPath, |
| 13 | 13 | |
| 14 | 14 | implib_dir: ?InstallDir, |
| ... | ... | @@ -24,7 +24,7 @@ emitted_compiler_rt_dyn_lib: ?LazyPath, |
| 24 | 24 | h_dir: ?InstallDir, |
| 25 | 25 | emitted_h: ?LazyPath, |
| 26 | 26 | |
| 27 | dylib_symlinks: ?DylibSymlinkInfo, | |
| 27 | dylib_symlinks: bool, | |
| 28 | 28 | |
| 29 | 29 | artifact: *Step.Compile, |
| 30 | 30 | |
| ... | ... | @@ -67,6 +67,16 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins |
| 67 | 67 | }, |
| 68 | 68 | .override => |o| o, |
| 69 | 69 | }; |
| 70 | const pdb_dir: ?InstallDir = switch (options.pdb_dir) { | |
| 71 | .disabled => null, | |
| 72 | .default => if (artifact.producesPdbFile()) dest_dir else null, | |
| 73 | .override => |o| o, | |
| 74 | }; | |
| 75 | const implib_dir: ?InstallDir = switch (options.implib_dir) { | |
| 76 | .disabled => null, | |
| 77 | .default => if (artifact.producesImplib()) .lib else null, | |
| 78 | .override => |o| o, | |
| 79 | }; | |
| 70 | 80 | install_artifact.* = .{ |
| 71 | 81 | .step = Step.init(.{ |
| 72 | 82 | .tag = base_tag, |
| ... | ... | @@ -74,54 +84,30 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins |
| 74 | 84 | .owner = owner, |
| 75 | 85 | }), |
| 76 | 86 | .dest_dir = dest_dir, |
| 77 | .pdb_dir = switch (options.pdb_dir) { | |
| 78 | .disabled => null, | |
| 79 | .default => if (artifact.producesPdbFile()) dest_dir else null, | |
| 80 | .override => |o| o, | |
| 81 | }, | |
| 82 | .compiler_rt_dyn_lib_dir = switch (options.compiler_rt_dyn_lib_dir) { | |
| 83 | .disabled => null, | |
| 84 | .default => if (artifact.producesCompilerRtDynLib()) dest_dir else null, | |
| 85 | .override => |o| o, | |
| 86 | }, | |
| 87 | .pdb_dir = pdb_dir, | |
| 87 | 88 | .h_dir = switch (options.h_dir) { |
| 88 | 89 | .disabled => null, |
| 89 | 90 | .default => if (artifact.kind == .lib) .header else null, |
| 90 | 91 | .override => |o| o, |
| 91 | 92 | }, |
| 92 | .implib_dir = switch (options.implib_dir) { | |
| 93 | .disabled => null, | |
| 94 | .default => if (artifact.producesImplib()) .lib else null, | |
| 95 | .override => |o| o, | |
| 96 | }, | |
| 93 | .implib_dir = implib_dir, | |
| 97 | 94 | |
| 98 | .dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and | |
| 99 | artifact.isDynamicLibrary() and | |
| 100 | artifact.version != null and | |
| 101 | std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{ | |
| 102 | .major_only_filename = artifact.major_only_filename.?, | |
| 103 | .name_only_filename = artifact.name_only_filename.?, | |
| 104 | } else null, | |
| 95 | .dylib_symlinks = options.dylib_symlinks orelse (dest_dir != null and | |
| 96 | artifact.isDynamicLibrary() and artifact.version != null and | |
| 97 | std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget())), | |
| 105 | 98 | |
| 106 | .dest_sub_path = options.dest_sub_path orelse artifact.out_filename, | |
| 99 | .dest_sub_path = options.dest_sub_path, | |
| 107 | 100 | |
| 108 | .emitted_bin = null, | |
| 109 | .emitted_pdb = null, | |
| 110 | .emitted_compiler_rt_dyn_lib = null, | |
| 101 | .emitted_bin = if (dest_dir != null) artifact.getEmittedBin() else null, | |
| 102 | .emitted_pdb = if (pdb_dir != null) artifact.getEmittedPdb() else null, | |
| 103 | // https://github.com/ziglang/zig/issues/9698 | |
| 111 | 104 | .emitted_h = null, |
| 112 | .emitted_implib = null, | |
| 105 | .emitted_implib = if (implib_dir != null) artifact.getEmittedImplib() else null, | |
| 113 | 106 | |
| 114 | 107 | .artifact = artifact, |
| 115 | 108 | }; |
| 116 | 109 | |
| 117 | 110 | install_artifact.step.dependOn(&artifact.step); |
| 118 | 111 | |
| 119 | if (install_artifact.dest_dir != null) install_artifact.emitted_bin = artifact.getEmittedBin(); | |
| 120 | if (install_artifact.compiler_rt_dyn_lib_dir != null) install_artifact.emitted_compiler_rt_dyn_lib = artifact.getEmittedCompilerRtDynLib(); | |
| 121 | if (install_artifact.pdb_dir != null) install_artifact.emitted_pdb = artifact.getEmittedPdb(); | |
| 122 | // https://github.com/ziglang/zig/issues/9698 | |
| 123 | //if (install_artifact.h_dir != null) install_artifact.emitted_h = artifact.getEmittedH(); | |
| 124 | if (install_artifact.implib_dir != null) install_artifact.emitted_implib = artifact.getEmittedImplib(); | |
| 125 | ||
| 126 | 112 | return install_artifact; |
| 127 | 113 | } |
lib/std/Build/Step/InstallFile.zig-12| ... | ... | @@ -25,7 +25,6 @@ pub fn create( |
| 25 | 25 | .tag = base_tag, |
| 26 | 26 | .name = owner.fmt("install {s} to {s}", .{ source.getDisplayName(), dest_rel_path }), |
| 27 | 27 | .owner = owner, |
| 28 | .makeFn = make, | |
| 29 | 28 | }), |
| 30 | 29 | .source = source.dupe(owner), |
| 31 | 30 | .dir = dir.dupe(owner), |
| ... | ... | @@ -34,14 +33,3 @@ pub fn create( |
| 34 | 33 | source.addStepDependencies(&install_file.step); |
| 35 | 34 | return install_file; |
| 36 | 35 | } |
| 37 | ||
| 38 | fn make(step: *Step, options: Step.MakeOptions) !void { | |
| 39 | _ = options; | |
| 40 | const b = step.owner; | |
| 41 | const install_file: *InstallFile = @fieldParentPtr("step", step); | |
| 42 | try step.singleUnchangingWatchInput(install_file.source); | |
| 43 | ||
| 44 | const full_dest_path = b.getInstallPath(install_file.dir, install_file.dest_rel_path); | |
| 45 | const p = try step.installFile(install_file.source, full_dest_path); | |
| 46 | step.result_cached = p == .fresh; | |
| 47 | } |