| ... | @@ -80,7 +80,11 @@ pub const Graph = struct { | ... | @@ -80,7 +80,11 @@ pub const Graph = struct { |
| 80 | system_package_mode: bool = false, | 80 | system_package_mode: bool = false, |
| 81 | zig_exe: []const u8, | 81 | zig_exe: []const u8, |
| 82 | environ_map: process.Environ.Map, | 82 | environ_map: process.Environ.Map, |
| 83 | needed_lazy_dependencies: std.array_hash_map.String(void) = .empty, | 83 | /// Managed by: |
| | 84 | /// * `Build.declareDependency` |
| | 85 | /// * `Build.dependency` |
| | 86 | /// * `Build.dependencyLazy` |
| | 87 | unlazy_deps: std.array_hash_map.Auto(Configuration.String, void) = .empty, |
| 84 | /// Information about the native target. Computed before build() is invoked. | 88 | /// Information about the native target. Computed before build() is invoked. |
| 85 | host: ResolvedTarget, | 89 | host: ResolvedTarget, |
| 86 | dependency_cache: PackageInstanceMap = .empty, | 90 | dependency_cache: PackageInstanceMap = .empty, |
| ... | @@ -1934,7 +1938,9 @@ inline fn findImportPkgHashOrFatal(b: *Build, comptime asking_build_zig: type, c | ... | @@ -1934,7 +1938,9 @@ inline fn findImportPkgHashOrFatal(b: *Build, comptime asking_build_zig: type, c |
| 1934 | } | 1938 | } |
| 1935 | | 1939 | |
| 1936 | fn markNeededLazyDep(b: *Build, pkg_hash: []const u8) void { | 1940 | fn markNeededLazyDep(b: *Build, pkg_hash: []const u8) void { |
| 1937 | b.graph.needed_lazy_dependencies.put(b.graph.arena, pkg_hash, {}) catch @panic("OOM"); | 1941 | const graph = b.graph; |
| | 1942 | const interned_hash = graph.wip_configuration.addString(pkg_hash) catch @panic("OOM"); |
| | 1943 | graph.unlazy_deps.put(graph.arena, interned_hash, {}) catch @panic("OOM"); |
| 1938 | } | 1944 | } |
| 1939 | | 1945 | |
| 1940 | /// Deprecated in favor of `dependencyLazy`. | 1946 | /// Deprecated in favor of `dependencyLazy`. |
| ... | @@ -1944,21 +1950,76 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { | ... | @@ -1944,21 +1950,76 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { |
| 1944 | }; | 1950 | }; |
| 1945 | } | 1951 | } |
| 1946 | | 1952 | |
| 1947 | /// Declares that the current configuration does in fact require a potentially | 1953 | /// Indicates that the current configuration needs a potentially lazy dependency. |
| 1948 | /// lazy dependency. | 1954 | /// |
| | 1955 | /// Related: |
| | 1956 | /// * `declareDependencyStep` |
| | 1957 | /// * `dependency` |
| | 1958 | /// * `dependencyLazy` |
| | 1959 | /// * `dependencyStep` |
| | 1960 | pub fn declareDependency(b: *Build, name: []const u8) void { |
| | 1961 | const pkg_hash = findPkgHashOrFatal(b, name); |
| | 1962 | markNeededLazyDep(b, pkg_hash); |
| | 1963 | } |
| | 1964 | |
| | 1965 | /// Indicates that the current configuration needs a potentially lazy dependency for the provided `Step`. |
| | 1966 | /// |
| | 1967 | /// Related: |
| | 1968 | /// * `declareDependency` |
| | 1969 | /// * `dependency` |
| | 1970 | /// * `dependencyLazy` |
| | 1971 | /// * `dependencyStep` |
| | 1972 | pub fn declareDependencyStep(b: *Build, s: *Step, name: []const u8) void { |
| | 1973 | const graph = b.graph; |
| | 1974 | const pkg_hash = findPkgHashOrFatal(b, name); |
| | 1975 | const interned_hash = graph.wip_configuration.addString(pkg_hash) catch @panic("OOM"); |
| | 1976 | s.unlazy_deps.put(graph.arena, interned_hash, {}) catch @panic("OOM"); |
| | 1977 | } |
| | 1978 | |
| | 1979 | /// Indicates that the current configuration needs a potentially lazy dependency for the provided `Step`. |
| | 1980 | /// |
| | 1981 | /// If the dependency is already fetched, it is returned, otherwise `null` is returned. After configuration |
| | 1982 | /// completes, if the dependency is needed after all, it will be fetched and configuration will re-run. |
| 1949 | /// | 1983 | /// |
| 1950 | /// If the dependency is already fetched, it is returned. However if the | 1984 | /// For non-lazy dependencies, this never returns `null`. |
| 1951 | /// dependency is not yet fetched, then when the build script is finished | 1985 | /// |
| 1952 | /// running, the toolchain will not proceed to the make phase. Instead, the | 1986 | /// Related: |
| 1953 | /// parent process will additionally fetch all the lazy dependencies that were | 1987 | /// * `dependency` |
| 1954 | /// actually required by running the build script, recompile the build script, | 1988 | /// * `dependencyLazy` |
| 1955 | /// and then run it again. In other words, if this function returns | 1989 | /// * `declareDependency` |
| 1956 | /// `error.LazyDependencyNeeded` it means that the only purpose of completing | 1990 | /// * `declareDependencyStep` |
| 1957 | /// the configure phase is to find out all the other lazy dependencies that are | 1991 | pub fn dependencyStep(b: *Build, s: *Step, name: []const u8, args: anytype) ?*Dependency { |
| 1958 | /// also required. In this case, one must propagate the error all the way up | 1992 | const pkg_hash = findPkgHashOrFatal(b, name); |
| 1959 | /// and return it from the main build function. | 1993 | const graph = b.graph; |
| | 1994 | const arena = graph.arena; |
| | 1995 | const entry = package_map.get(pkg_hash).?; |
| | 1996 | if (!entry.available) { |
| | 1997 | const interned_hash = graph.wip_configuration.addString(pkg_hash) catch @panic("OOM"); |
| | 1998 | s.unlazy_deps.put(arena, interned_hash, {}) catch @panic("OOM"); |
| | 1999 | return null; |
| | 2000 | } |
| | 2001 | var map: PackageOptions.Map = .empty; |
| | 2002 | PackageOptions.fromArgs(arena, &map, args); |
| | 2003 | return dependencyResolved(b, name, entry, &map); |
| | 2004 | } |
| | 2005 | |
| | 2006 | /// Declares that the current configuration does in fact require a potentially lazy dependency. |
| | 2007 | /// |
| | 2008 | /// If the dependency is already fetched, it is returned. However if the dependency is not yet fetched, then |
| | 2009 | /// when the build script is finished running, the toolchain will not proceed to the make phase. Instead, the |
| | 2010 | /// parent process will additionally fetch all the lazy dependencies that were actually required by running the |
| | 2011 | /// build script, recompile the build script, and then run it again. In other words, if this function returns |
| | 2012 | /// `error.LazyDependencyNeeded` it means that the only purpose of completing the configure phase is to find |
| | 2013 | /// out all the other lazy dependencies that are also required. In this case, one must propagate the error all |
| | 2014 | /// the way up and return it from the main build function. |
| 1960 | /// | 2015 | /// |
| 1961 | /// For non-lazy dependencies, this always succeeds. | 2016 | /// For non-lazy dependencies, this always succeeds. |
| | 2017 | /// |
| | 2018 | /// Related: |
| | 2019 | /// * `dependency` |
| | 2020 | /// * `dependencyStep` |
| | 2021 | /// * `declareDependency` |
| | 2022 | /// * `declareDependencyStep` |
| 1962 | pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDependencyNeeded}!*Dependency { | 2023 | pub fn dependencyLazy(b: *Build, name: []const u8, args: anytype) error{LazyDependencyNeeded}!*Dependency { |
| 1963 | const pkg_hash = findPkgHashOrFatal(b, name); | 2024 | const pkg_hash = findPkgHashOrFatal(b, name); |
| 1964 | const entry = package_map.get(pkg_hash) orelse unreachable; | 2025 | const entry = package_map.get(pkg_hash) orelse unreachable; |
| ... | @@ -2018,7 +2079,7 @@ pub const package_map: std.StaticStringMap(PackageEntry) = blk: { | ... | @@ -2018,7 +2079,7 @@ pub const package_map: std.StaticStringMap(PackageEntry) = blk: { |
| 2018 | pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { | 2079 | pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| 2019 | return dependencyLazy(b, name, args) catch |err| switch (err) { | 2080 | return dependencyLazy(b, name, args) catch |err| switch (err) { |
| 2020 | error.LazyDependencyNeeded => { | 2081 | error.LazyDependencyNeeded => { |
| 2021 | assert(b.graph.needed_lazy_dependencies.count() != 0); | 2082 | assert(b.graph.unlazy_deps.count() != 0); |
| 2022 | serializeConfigurationExiting(b); | 2083 | serializeConfigurationExiting(b); |
| 2023 | }, | 2084 | }, |
| 2024 | }; | 2085 | }; |
| ... | @@ -2143,7 +2204,7 @@ fn dependencyResolved( | ... | @@ -2143,7 +2204,7 @@ fn dependencyResolved( |
| 2143 | pub inline fn runPackageScript(b: *Build, comptime build_zig: anytype) void { | 2204 | pub inline fn runPackageScript(b: *Build, comptime build_zig: anytype) void { |
| 2144 | const result: anyerror!void = build_zig.build(b); | 2205 | const result: anyerror!void = build_zig.build(b); |
| 2145 | result catch |err| switch (err) { | 2206 | result catch |err| switch (err) { |
| 2146 | error.LazyDependencyNeeded => assert(b.graph.needed_lazy_dependencies.count() != 0), | 2207 | error.LazyDependencyNeeded => assert(b.graph.unlazy_deps.count() != 0), |
| 2147 | else => { | 2208 | else => { |
| 2148 | if (b.dep_prefix.len == 0) { | 2209 | if (b.dep_prefix.len == 0) { |
| 2149 | log.err("package {q} configuration failed: {t}", .{ b.dep_prefix, err }); | 2210 | log.err("package {q} configuration failed: {t}", .{ b.dep_prefix, err }); |
| ... | @@ -2151,7 +2212,7 @@ pub inline fn runPackageScript(b: *Build, comptime build_zig: anytype) void { | ... | @@ -2151,7 +2212,7 @@ pub inline fn runPackageScript(b: *Build, comptime build_zig: anytype) void { |
| 2151 | log.err("configuration failed: {t}", .{err}); | 2212 | log.err("configuration failed: {t}", .{err}); |
| 2152 | } | 2213 | } |
| 2153 | if (@errorReturnTrace()) |trace| std.debug.dumpErrorReturnTrace(trace); | 2214 | if (@errorReturnTrace()) |trace| std.debug.dumpErrorReturnTrace(trace); |
| 2154 | const lazy_count = b.graph.needed_lazy_dependencies.count(); | 2215 | const lazy_count = b.graph.unlazy_deps.count(); |
| 2155 | if (lazy_count == 0) process.exit(1); | 2216 | if (lazy_count == 0) process.exit(1); |
| 2156 | log.info("{d} lazy dependencies detected; fetching and retrying configuration", .{lazy_count}); | 2217 | log.info("{d} lazy dependencies detected; fetching and retrying configuration", .{lazy_count}); |
| 2157 | }, | 2218 | }, |