| author | |
| committer | |
| log | 8eff0a0a669dbdacf9cebbc96fdf20536f3073ee |
| tree | 316411f9bb95eb8df2bc34cd9bfcba83ad246835 |
| parent | c9413a880be0e5817d31a35c95d4c8f7d1f81eff |
Dependencies no longer require a build.zig file.
Adds path function to Dependency struct which
returns a LazyPath into a dependency.3 files changed, 108 insertions(+), 37 deletions(-)
lib/std/Build.zig+31-6| ... | ... | @@ -1707,6 +1707,15 @@ pub const Dependency = struct { |
| 1707 | 1707 | panic("unable to find module '{s}'", .{name}); |
| 1708 | 1708 | }; |
| 1709 | 1709 | } |
| 1710 | ||
| 1711 | pub fn path(d: *Dependency, sub_path: []const u8) LazyPath { | |
| 1712 | return .{ | |
| 1713 | .dependency = .{ | |
| 1714 | .dependency = d, | |
| 1715 | .sub_path = sub_path, | |
| 1716 | }, | |
| 1717 | }; | |
| 1718 | } | |
| 1710 | 1719 | }; |
| 1711 | 1720 | |
| 1712 | 1721 | pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| ... | ... | @@ -1724,7 +1733,7 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| 1724 | 1733 | inline for (@typeInfo(deps.packages).Struct.decls) |decl| { |
| 1725 | 1734 | if (mem.eql(u8, decl.name, pkg_hash)) { |
| 1726 | 1735 | const pkg = @field(deps.packages, decl.name); |
| 1727 | return dependencyInner(b, name, pkg.build_root, pkg.build_zig, pkg.deps, args); | |
| 1736 | return dependencyInner(b, name, pkg.build_root, if (@hasDecl(pkg, "build_zig")) pkg.build_zig else null, pkg.deps, args); | |
| 1728 | 1737 | } |
| 1729 | 1738 | } |
| 1730 | 1739 | |
| ... | ... | @@ -1801,7 +1810,7 @@ pub fn dependencyInner( |
| 1801 | 1810 | b: *Build, |
| 1802 | 1811 | name: []const u8, |
| 1803 | 1812 | build_root_string: []const u8, |
| 1804 | comptime build_zig: type, | |
| 1813 | comptime build_zig: ?type, | |
| 1805 | 1814 | pkg_deps: AvailableDeps, |
| 1806 | 1815 | args: anytype, |
| 1807 | 1816 | ) *Dependency { |
| ... | ... | @@ -1821,11 +1830,14 @@ pub fn dependencyInner( |
| 1821 | 1830 | process.exit(1); |
| 1822 | 1831 | }, |
| 1823 | 1832 | }; |
| 1833 | ||
| 1824 | 1834 | const sub_builder = b.createChild(name, build_root, pkg_deps, user_input_options) catch @panic("unhandled error"); |
| 1825 | sub_builder.runBuild(build_zig) catch @panic("unhandled error"); | |
| 1835 | if (build_zig) |bz| { | |
| 1836 | sub_builder.runBuild(bz) catch @panic("unhandled error"); | |
| 1826 | 1837 | |
| 1827 | if (sub_builder.validateUserInputDidItFail()) { | |
| 1828 | std.debug.dumpCurrentStackTrace(@returnAddress()); | |
| 1838 | if (sub_builder.validateUserInputDidItFail()) { | |
| 1839 | std.debug.dumpCurrentStackTrace(@returnAddress()); | |
| 1840 | } | |
| 1829 | 1841 | } |
| 1830 | 1842 | |
| 1831 | 1843 | const dep = b.allocator.create(Dependency) catch @panic("OOM"); |
| ... | ... | @@ -1892,6 +1904,11 @@ pub const LazyPath = union(enum) { |
| 1892 | 1904 | /// Use of this tag indicates a dependency on the host system. |
| 1893 | 1905 | cwd_relative: []const u8, |
| 1894 | 1906 | |
| 1907 | dependency: struct { | |
| 1908 | dependency: *Dependency, | |
| 1909 | sub_path: []const u8, | |
| 1910 | }, | |
| 1911 | ||
| 1895 | 1912 | /// Returns a new file source that will have a relative path to the build root guaranteed. |
| 1896 | 1913 | /// Asserts the parameter is not an absolute path. |
| 1897 | 1914 | pub fn relative(path: []const u8) LazyPath { |
| ... | ... | @@ -1905,13 +1922,14 @@ pub const LazyPath = union(enum) { |
| 1905 | 1922 | return switch (self) { |
| 1906 | 1923 | .path, .cwd_relative => self.path, |
| 1907 | 1924 | .generated => "generated", |
| 1925 | .dependency => "dependency", | |
| 1908 | 1926 | }; |
| 1909 | 1927 | } |
| 1910 | 1928 | |
| 1911 | 1929 | /// Adds dependencies this file source implies to the given step. |
| 1912 | 1930 | pub fn addStepDependencies(self: LazyPath, other_step: *Step) void { |
| 1913 | 1931 | switch (self) { |
| 1914 | .path, .cwd_relative => {}, | |
| 1932 | .path, .cwd_relative, .dependency => {}, | |
| 1915 | 1933 | .generated => |gen| other_step.dependOn(gen.step), |
| 1916 | 1934 | } |
| 1917 | 1935 | } |
| ... | ... | @@ -1937,6 +1955,12 @@ pub const LazyPath = union(enum) { |
| 1937 | 1955 | dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {}; |
| 1938 | 1956 | @panic("misconfigured build script"); |
| 1939 | 1957 | }, |
| 1958 | .dependency => |dep| { | |
| 1959 | return dep.dependency.builder.pathJoin(&[_][]const u8{ | |
| 1960 | dep.dependency.builder.build_root.path.?, | |
| 1961 | dep.sub_path, | |
| 1962 | }); | |
| 1963 | }, | |
| 1940 | 1964 | } |
| 1941 | 1965 | } |
| 1942 | 1966 | |
| ... | ... | @@ -1946,6 +1970,7 @@ pub const LazyPath = union(enum) { |
| 1946 | 1970 | .path => |p| .{ .path = b.dupePath(p) }, |
| 1947 | 1971 | .cwd_relative => |p| .{ .cwd_relative = b.dupePath(p) }, |
| 1948 | 1972 | .generated => |gen| .{ .generated = gen }, |
| 1973 | .dependency => |dep| .{ .dependency = dep }, | |
| 1949 | 1974 | }; |
| 1950 | 1975 | } |
| 1951 | 1976 | }; |
lib/std/Build/Step/Compile.zig+1-1| ... | ... | @@ -1896,7 +1896,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { |
| 1896 | 1896 | continue; |
| 1897 | 1897 | } |
| 1898 | 1898 | }, |
| 1899 | .generated => {}, | |
| 1899 | .generated, .dependency => {}, | |
| 1900 | 1900 | }; |
| 1901 | 1901 | |
| 1902 | 1902 | zig_args.appendAssumeCapacity(rpath.getPath2(b, step)); |
src/Package.zig+76-30| ... | ... | @@ -327,30 +327,45 @@ pub fn fetchAndAddDependencies( |
| 327 | 327 | name, |
| 328 | 328 | ); |
| 329 | 329 | |
| 330 | if (!sub.found_existing) { | |
| 331 | try sub.mod.fetchAndAddDependencies( | |
| 332 | deps_pkg, | |
| 333 | arena, | |
| 334 | thread_pool, | |
| 335 | http_client, | |
| 336 | sub.mod.root_src_directory, | |
| 337 | global_cache_directory, | |
| 338 | local_cache_directory, | |
| 339 | dependencies_source, | |
| 340 | error_bundle, | |
| 341 | all_modules, | |
| 342 | root_prog_node, | |
| 343 | dep.hash.?, | |
| 344 | ); | |
| 345 | } | |
| 330 | if (sub.mod) |mod| { | |
| 331 | if (!sub.found_existing) { | |
| 332 | try mod.fetchAndAddDependencies( | |
| 333 | deps_pkg, | |
| 334 | arena, | |
| 335 | thread_pool, | |
| 336 | http_client, | |
| 337 | mod.root_src_directory, | |
| 338 | global_cache_directory, | |
| 339 | local_cache_directory, | |
| 340 | dependencies_source, | |
| 341 | error_bundle, | |
| 342 | all_modules, | |
| 343 | root_prog_node, | |
| 344 | dep.hash.?, | |
| 345 | ); | |
| 346 | } | |
| 346 | 347 | |
| 347 | try pkg.add(gpa, name, sub.mod); | |
| 348 | if (deps_pkg.table.get(dep.hash.?)) |other_sub| { | |
| 349 | // This should be the same package (and hence module) since it's the same hash | |
| 350 | // TODO: dedup multiple versions of the same package | |
| 351 | assert(other_sub == sub.mod); | |
| 352 | } else { | |
| 353 | try deps_pkg.add(gpa, dep.hash.?, sub.mod); | |
| 348 | try pkg.add(gpa, name, mod); | |
| 349 | if (deps_pkg.table.get(dep.hash.?)) |other_sub| { | |
| 350 | // This should be the same package (and hence module) since it's the same hash | |
| 351 | // TODO: dedup multiple versions of the same package | |
| 352 | assert(other_sub == mod); | |
| 353 | } else { | |
| 354 | try deps_pkg.add(gpa, dep.hash.?, mod); | |
| 355 | } | |
| 356 | } else if (!sub.found_existing) { | |
| 357 | const pkg_dir_sub_path = "p" ++ fs.path.sep_str ++ (dep.hash.?)[0..hex_multihash_len]; | |
| 358 | const build_root = try global_cache_directory.join(arena, &.{pkg_dir_sub_path}); | |
| 359 | try dependencies_source.writer().print( | |
| 360 | \\ pub const {} = struct {{ | |
| 361 | \\ pub const build_root = "{}"; | |
| 362 | \\ pub const deps: []const struct {{ []const u8, []const u8 }} = &.{{}}; | |
| 363 | \\ }}; | |
| 364 | \\ | |
| 365 | , .{ | |
| 366 | std.zig.fmtId(dep.hash.?), | |
| 367 | std.zig.fmtEscapes(build_root), | |
| 368 | }); | |
| 354 | 369 | } |
| 355 | 370 | } |
| 356 | 371 | |
| ... | ... | @@ -480,7 +495,10 @@ const MultiHashHexDigest = [hex_multihash_len]u8; |
| 480 | 495 | /// This is to avoid creating multiple modules for the same build.zig file. |
| 481 | 496 | /// If the value is `null`, the package is a known dependency, but has not yet |
| 482 | 497 | /// been fetched. |
| 483 | pub const AllModules = std.AutoHashMapUnmanaged(MultiHashHexDigest, ?*Package); | |
| 498 | pub const AllModules = std.AutoHashMapUnmanaged(MultiHashHexDigest, ?union(enum) { | |
| 499 | zig_pkg: *Package, | |
| 500 | non_zig_pkg: void, | |
| 501 | }); | |
| 484 | 502 | |
| 485 | 503 | fn ProgressReader(comptime ReaderType: type) type { |
| 486 | 504 | return struct { |
| ... | ... | @@ -535,7 +553,7 @@ fn fetchAndUnpack( |
| 535 | 553 | /// This does not have to be any form of canonical or fully-qualified name: it |
| 536 | 554 | /// is only intended to be human-readable for progress reporting. |
| 537 | 555 | name_for_prog: []const u8, |
| 538 | ) !struct { mod: *Package, found_existing: bool } { | |
| 556 | ) !struct { mod: ?*Package, found_existing: bool } { | |
| 539 | 557 | const gpa = http_client.allocator; |
| 540 | 558 | const s = fs.path.sep_str; |
| 541 | 559 | |
| ... | ... | @@ -556,13 +574,27 @@ fn fetchAndUnpack( |
| 556 | 574 | const gop = try all_modules.getOrPut(gpa, hex_digest.*); |
| 557 | 575 | if (gop.found_existing) { |
| 558 | 576 | if (gop.value_ptr.*) |mod| { |
| 559 | return .{ | |
| 560 | .mod = mod, | |
| 561 | .found_existing = true, | |
| 577 | return switch (mod) { | |
| 578 | .zig_pkg => |pkg| .{ | |
| 579 | .mod = pkg, | |
| 580 | .found_existing = true, | |
| 581 | }, | |
| 582 | .non_zig_pkg => .{ | |
| 583 | .mod = null, | |
| 584 | .found_existing = true, | |
| 585 | }, | |
| 562 | 586 | }; |
| 563 | 587 | } |
| 564 | 588 | } |
| 565 | 589 | |
| 590 | pkg_dir.access(build_zig_basename, .{}) catch { | |
| 591 | gop.value_ptr.* = .non_zig_pkg; | |
| 592 | return .{ | |
| 593 | .mod = null, | |
| 594 | .found_existing = false, | |
| 595 | }; | |
| 596 | }; | |
| 597 | ||
| 566 | 598 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); |
| 567 | 599 | errdefer gpa.free(build_root); |
| 568 | 600 | |
| ... | ... | @@ -583,7 +615,7 @@ fn fetchAndUnpack( |
| 583 | 615 | .root_src_path = owned_src_path, |
| 584 | 616 | }; |
| 585 | 617 | |
| 586 | gop.value_ptr.* = ptr; | |
| 618 | gop.value_ptr.* = .{ .zig_pkg = ptr }; | |
| 587 | 619 | return .{ |
| 588 | 620 | .mod = ptr, |
| 589 | 621 | .found_existing = false, |
| ... | ... | @@ -722,8 +754,22 @@ fn fetchAndUnpack( |
| 722 | 754 | return error.PackageFetchFailed; |
| 723 | 755 | } |
| 724 | 756 | |
| 757 | const build_zig_path = try std.fs.path.join(gpa, &.{ pkg_dir_sub_path, build_zig_basename }); | |
| 758 | defer gpa.free(build_zig_path); | |
| 759 | ||
| 760 | global_cache_directory.handle.access(build_zig_path, .{}) catch |err| switch (err) { | |
| 761 | error.FileNotFound => { | |
| 762 | try all_modules.put(gpa, actual_hex, .non_zig_pkg); | |
| 763 | return .{ | |
| 764 | .mod = null, | |
| 765 | .found_existing = false, | |
| 766 | }; | |
| 767 | }, | |
| 768 | else => return err, | |
| 769 | }; | |
| 770 | ||
| 725 | 771 | const mod = try createWithDir(gpa, global_cache_directory, pkg_dir_sub_path, build_zig_basename); |
| 726 | try all_modules.put(gpa, actual_hex, mod); | |
| 772 | try all_modules.put(gpa, actual_hex, .{ .zig_pkg = mod }); | |
| 727 | 773 | return .{ |
| 728 | 774 | .mod = mod, |
| 729 | 775 | .found_existing = false, |