| author | |
| committer | |
| log | 94529ffb621fa633437ac48d8f90003e26e8ce5b |
| tree | 9454170d72caac01866caef3c25a0affa1dcb6de |
| parent | 1a0e6bcdb140c844384d62b78a7f4247753f9ffd |
The new `@depedencies` module contains generated code like the
following (where strings like "abc123" represent hashes):
```zig
pub const root_deps = [_]struct { []const u8, []const u8 }{
.{ "foo", "abc123" },
};
pub const packages = struct {
pub const abc123 = struct {
pub const build_root = "/home/mlugg/.cache/zig/blah/abc123";
pub const build_zig = @import("abc123");
pub const deps = [_]struct { []const u8, []const u8 }{
.{ "bar", "abc123" },
.{ "name", "ghi789" },
};
};
};
```
Each package contains a build root string, the build.zig import, and a
mapping from dependency names to package hashes. There is also such a
mapping for the root package dependencies.
In theory, we could now remove the `dep_prefix` field from `std.Build`,
since its main purpose is now handled differently. I believe this is a
desirable goal, as it doesn't really make sense to assign a single FQN
to any package (because it may appear in many different places in the
package hierarchy). This commit does not remove that field, as it's used
non-trivially in a few places in the build runner and compiler tests:
this will be a future enhancement.
Resolves: #16354
Resolves: #171355 files changed, 115 insertions(+), 57 deletions(-)
lib/build_runner.zig+1| ... | @@ -81,6 +81,7 @@ pub fn main() !void { | ... | @@ -81,6 +81,7 @@ pub fn main() !void { |
| 81 | global_cache_directory, | 81 | global_cache_directory, |
| 82 | host, | 82 | host, |
| 83 | &cache, | 83 | &cache, |
| 84 | dependencies.root_deps, | ||
| 84 | ); | 85 | ); |
| 85 | defer builder.destroy(); | 86 | defer builder.destroy(); |
| 86 | 87 |
lib/std/Build.zig+26-15| ... | @@ -132,6 +132,10 @@ modules: std.StringArrayHashMap(*Module), | ... | @@ -132,6 +132,10 @@ modules: std.StringArrayHashMap(*Module), |
| 132 | /// A map from build root dirs to the corresponding `*Dependency`. This is shared with all child | 132 | /// A map from build root dirs to the corresponding `*Dependency`. This is shared with all child |
| 133 | /// `Build`s. | 133 | /// `Build`s. |
| 134 | initialized_deps: *InitializedDepMap, | 134 | initialized_deps: *InitializedDepMap, |
| 135 | /// A mapping from dependency names to package hashes. | ||
| 136 | available_deps: AvailableDeps, | ||
| 137 | |||
| 138 | const AvailableDeps = []const struct { []const u8, []const u8 }; | ||
| 135 | 139 | ||
| 136 | const InitializedDepMap = std.HashMap(InitializedDepKey, *Dependency, InitializedDepContext, std.hash_map.default_max_load_percentage); | 140 | const InitializedDepMap = std.HashMap(InitializedDepKey, *Dependency, InitializedDepContext, std.hash_map.default_max_load_percentage); |
| 137 | const InitializedDepKey = struct { | 141 | const InitializedDepKey = struct { |
| ... | @@ -248,6 +252,7 @@ pub fn create( | ... | @@ -248,6 +252,7 @@ pub fn create( |
| 248 | global_cache_root: Cache.Directory, | 252 | global_cache_root: Cache.Directory, |
| 249 | host: NativeTargetInfo, | 253 | host: NativeTargetInfo, |
| 250 | cache: *Cache, | 254 | cache: *Cache, |
| 255 | available_deps: AvailableDeps, | ||
| 251 | ) !*Build { | 256 | ) !*Build { |
| 252 | const env_map = try allocator.create(EnvMap); | 257 | const env_map = try allocator.create(EnvMap); |
| 253 | env_map.* = try process.getEnvMap(allocator); | 258 | env_map.* = try process.getEnvMap(allocator); |
| ... | @@ -308,6 +313,7 @@ pub fn create( | ... | @@ -308,6 +313,7 @@ pub fn create( |
| 308 | .host = host, | 313 | .host = host, |
| 309 | .modules = std.StringArrayHashMap(*Module).init(allocator), | 314 | .modules = std.StringArrayHashMap(*Module).init(allocator), |
| 310 | .initialized_deps = initialized_deps, | 315 | .initialized_deps = initialized_deps, |
| 316 | .available_deps = available_deps, | ||
| 311 | }; | 317 | }; |
| 312 | try self.top_level_steps.put(allocator, self.install_tls.step.name, &self.install_tls); | 318 | try self.top_level_steps.put(allocator, self.install_tls.step.name, &self.install_tls); |
| 313 | try self.top_level_steps.put(allocator, self.uninstall_tls.step.name, &self.uninstall_tls); | 319 | try self.top_level_steps.put(allocator, self.uninstall_tls.step.name, &self.uninstall_tls); |
| ... | @@ -319,14 +325,15 @@ fn createChild( | ... | @@ -319,14 +325,15 @@ fn createChild( |
| 319 | parent: *Build, | 325 | parent: *Build, |
| 320 | dep_name: []const u8, | 326 | dep_name: []const u8, |
| 321 | build_root: Cache.Directory, | 327 | build_root: Cache.Directory, |
| 328 | pkg_deps: AvailableDeps, | ||
| 322 | user_input_options: UserInputOptionsMap, | 329 | user_input_options: UserInputOptionsMap, |
| 323 | ) !*Build { | 330 | ) !*Build { |
| 324 | const child = try createChildOnly(parent, dep_name, build_root, user_input_options); | 331 | const child = try createChildOnly(parent, dep_name, build_root, pkg_deps, user_input_options); |
| 325 | try determineAndApplyInstallPrefix(child); | 332 | try determineAndApplyInstallPrefix(child); |
| 326 | return child; | 333 | return child; |
| 327 | } | 334 | } |
| 328 | 335 | ||
| 329 | fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Directory, user_input_options: UserInputOptionsMap) !*Build { | 336 | fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Directory, pkg_deps: AvailableDeps, user_input_options: UserInputOptionsMap) !*Build { |
| 330 | const allocator = parent.allocator; | 337 | const allocator = parent.allocator; |
| 331 | const child = try allocator.create(Build); | 338 | const child = try allocator.create(Build); |
| 332 | child.* = .{ | 339 | child.* = .{ |
| ... | @@ -393,6 +400,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc | ... | @@ -393,6 +400,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc |
| 393 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), | 400 | .dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }), |
| 394 | .modules = std.StringArrayHashMap(*Module).init(allocator), | 401 | .modules = std.StringArrayHashMap(*Module).init(allocator), |
| 395 | .initialized_deps = parent.initialized_deps, | 402 | .initialized_deps = parent.initialized_deps, |
| 403 | .available_deps = pkg_deps, | ||
| 396 | }; | 404 | }; |
| 397 | try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls); | 405 | try child.top_level_steps.put(allocator, child.install_tls.step.name, &child.install_tls); |
| 398 | try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls); | 406 | try child.top_level_steps.put(allocator, child.uninstall_tls.step.name, &child.uninstall_tls); |
| ... | @@ -1705,20 +1713,22 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { | ... | @@ -1705,20 +1713,22 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { |
| 1705 | const build_runner = @import("root"); | 1713 | const build_runner = @import("root"); |
| 1706 | const deps = build_runner.dependencies; | 1714 | const deps = build_runner.dependencies; |
| 1707 | 1715 | ||
| 1708 | inline for (@typeInfo(deps.imports).Struct.decls) |decl| { | 1716 | const pkg_hash = for (b.available_deps) |dep| { |
| 1709 | if (mem.startsWith(u8, decl.name, b.dep_prefix) and | 1717 | if (mem.eql(u8, dep[0], name)) break dep[1]; |
| 1710 | mem.endsWith(u8, decl.name, name) and | 1718 | } else { |
| 1711 | decl.name.len == b.dep_prefix.len + name.len) | 1719 | const full_path = b.pathFromRoot("build.zig.zon"); |
| 1712 | { | 1720 | std.debug.print("no dependency named '{s}' in '{s}'. All packages used in build.zig must be declared in this file.\n", .{ name, full_path }); |
| 1713 | const build_zig = @field(deps.imports, decl.name); | 1721 | process.exit(1); |
| 1714 | const build_root = @field(deps.build_root, decl.name); | 1722 | }; |
| 1715 | return dependencyInner(b, name, build_root, build_zig, args); | 1723 | |
| 1724 | inline for (@typeInfo(deps.packages).Struct.decls) |decl| { | ||
| 1725 | if (mem.eql(u8, decl.name, pkg_hash)) { | ||
| 1726 | const pkg = @field(deps.packages, decl.name); | ||
| 1727 | return dependencyInner(b, name, pkg.build_root, pkg.build_zig, pkg.deps, args); | ||
| 1716 | } | 1728 | } |
| 1717 | } | 1729 | } |
| 1718 | 1730 | ||
| 1719 | const full_path = b.pathFromRoot("build.zig.zon"); | 1731 | unreachable; // Bad @dependencies source |
| 1720 | std.debug.print("no dependency named '{s}' in '{s}'. All packages used in build.zig must be declared in this file.\n", .{ name, full_path }); | ||
| 1721 | process.exit(1); | ||
| 1722 | } | 1732 | } |
| 1723 | 1733 | ||
| 1724 | pub fn anonymousDependency( | 1734 | pub fn anonymousDependency( |
| ... | @@ -1737,7 +1747,7 @@ pub fn anonymousDependency( | ... | @@ -1737,7 +1747,7 @@ pub fn anonymousDependency( |
| 1737 | '/', '\\' => byte.* = '.', | 1747 | '/', '\\' => byte.* = '.', |
| 1738 | else => continue, | 1748 | else => continue, |
| 1739 | }; | 1749 | }; |
| 1740 | return dependencyInner(b, name, build_root, build_zig, args); | 1750 | return dependencyInner(b, name, build_root, build_zig, &.{}, args); |
| 1741 | } | 1751 | } |
| 1742 | 1752 | ||
| 1743 | fn userValuesAreSame(lhs: UserValue, rhs: UserValue) bool { | 1753 | fn userValuesAreSame(lhs: UserValue, rhs: UserValue) bool { |
| ... | @@ -1792,6 +1802,7 @@ pub fn dependencyInner( | ... | @@ -1792,6 +1802,7 @@ pub fn dependencyInner( |
| 1792 | name: []const u8, | 1802 | name: []const u8, |
| 1793 | build_root_string: []const u8, | 1803 | build_root_string: []const u8, |
| 1794 | comptime build_zig: type, | 1804 | comptime build_zig: type, |
| 1805 | pkg_deps: AvailableDeps, | ||
| 1795 | args: anytype, | 1806 | args: anytype, |
| 1796 | ) *Dependency { | 1807 | ) *Dependency { |
| 1797 | const user_input_options = userInputOptionsFromArgs(b.allocator, args); | 1808 | const user_input_options = userInputOptionsFromArgs(b.allocator, args); |
| ... | @@ -1810,7 +1821,7 @@ pub fn dependencyInner( | ... | @@ -1810,7 +1821,7 @@ pub fn dependencyInner( |
| 1810 | process.exit(1); | 1821 | process.exit(1); |
| 1811 | }, | 1822 | }, |
| 1812 | }; | 1823 | }; |
| 1813 | const sub_builder = b.createChild(name, build_root, user_input_options) catch @panic("unhandled error"); | 1824 | const sub_builder = b.createChild(name, build_root, pkg_deps, user_input_options) catch @panic("unhandled error"); |
| 1814 | sub_builder.runBuild(build_zig) catch @panic("unhandled error"); | 1825 | sub_builder.runBuild(build_zig) catch @panic("unhandled error"); |
| 1815 | 1826 | ||
| 1816 | if (sub_builder.validateUserInputDidItFail()) { | 1827 | if (sub_builder.validateUserInputDidItFail()) { |
lib/std/Build/Step/Options.zig+1| ... | @@ -314,6 +314,7 @@ test Options { | ... | @@ -314,6 +314,7 @@ test Options { |
| 314 | .{ .path = "test", .handle = std.fs.cwd() }, | 314 | .{ .path = "test", .handle = std.fs.cwd() }, |
| 315 | host, | 315 | host, |
| 316 | &cache, | 316 | &cache, |
| 317 | &.{}, | ||
| 317 | ); | 318 | ); |
| 318 | defer builder.destroy(); | 319 | defer builder.destroy(); |
| 319 | 320 |
src/Package.zig+78-29| ... | @@ -214,6 +214,8 @@ pub fn getName(target: *const Package, gpa: Allocator, mod: Module) ![]const u8 | ... | @@ -214,6 +214,8 @@ pub fn getName(target: *const Package, gpa: Allocator, mod: Module) ![]const u8 |
| 214 | 214 | ||
| 215 | pub const build_zig_basename = "build.zig"; | 215 | pub const build_zig_basename = "build.zig"; |
| 216 | 216 | ||
| 217 | /// Fetches a package and all of its dependencies recursively. Writes the | ||
| 218 | /// corresponding datastructures for the build runner into `dependencies_source`. | ||
| 217 | pub fn fetchAndAddDependencies( | 219 | pub fn fetchAndAddDependencies( |
| 218 | pkg: *Package, | 220 | pkg: *Package, |
| 219 | deps_pkg: *Package, | 221 | deps_pkg: *Package, |
| ... | @@ -224,11 +226,11 @@ pub fn fetchAndAddDependencies( | ... | @@ -224,11 +226,11 @@ pub fn fetchAndAddDependencies( |
| 224 | global_cache_directory: Compilation.Directory, | 226 | global_cache_directory: Compilation.Directory, |
| 225 | local_cache_directory: Compilation.Directory, | 227 | local_cache_directory: Compilation.Directory, |
| 226 | dependencies_source: *std.ArrayList(u8), | 228 | dependencies_source: *std.ArrayList(u8), |
| 227 | build_roots_source: *std.ArrayList(u8), | ||
| 228 | name_prefix: []const u8, | ||
| 229 | error_bundle: *std.zig.ErrorBundle.Wip, | 229 | error_bundle: *std.zig.ErrorBundle.Wip, |
| 230 | all_modules: *AllModules, | 230 | all_modules: *AllModules, |
| 231 | root_prog_node: *std.Progress.Node, | 231 | root_prog_node: *std.Progress.Node, |
| 232 | /// null for the root package | ||
| 233 | this_hash: ?[]const u8, | ||
| 232 | ) !void { | 234 | ) !void { |
| 233 | const max_bytes = 10 * 1024 * 1024; | 235 | const max_bytes = 10 * 1024 * 1024; |
| 234 | const gpa = thread_pool.allocator; | 236 | const gpa = thread_pool.allocator; |
| ... | @@ -242,6 +244,28 @@ pub fn fetchAndAddDependencies( | ... | @@ -242,6 +244,28 @@ pub fn fetchAndAddDependencies( |
| 242 | ) catch |err| switch (err) { | 244 | ) catch |err| switch (err) { |
| 243 | error.FileNotFound => { | 245 | error.FileNotFound => { |
| 244 | // Handle the same as no dependencies. | 246 | // Handle the same as no dependencies. |
| 247 | if (this_hash) |hash| { | ||
| 248 | const pkg_dir_sub_path = "p" ++ fs.path.sep_str ++ hash[0..hex_multihash_len]; | ||
| 249 | const build_root = try global_cache_directory.join(arena, &.{pkg_dir_sub_path}); | ||
| 250 | try dependencies_source.writer().print( | ||
| 251 | \\ pub const {} = struct {{ | ||
| 252 | \\ pub const build_root = "{}"; | ||
| 253 | \\ pub const build_zig = @import("{}"); | ||
| 254 | \\ pub const deps: []const struct {{ []const u8, []const u8 }} = &.{{}}; | ||
| 255 | \\ }}; | ||
| 256 | \\ | ||
| 257 | , .{ | ||
| 258 | std.zig.fmtId(hash), | ||
| 259 | std.zig.fmtEscapes(build_root), | ||
| 260 | std.zig.fmtEscapes(hash), | ||
| 261 | }); | ||
| 262 | } else { | ||
| 263 | try dependencies_source.writer().writeAll( | ||
| 264 | \\pub const packages = struct {}; | ||
| 265 | \\pub const root_deps: []const struct { []const u8, []const u8 } = &.{}; | ||
| 266 | \\ | ||
| 267 | ); | ||
| 268 | } | ||
| 245 | return; | 269 | return; |
| 246 | }, | 270 | }, |
| 247 | else => |e| return e, | 271 | else => |e| return e, |
| ... | @@ -284,23 +308,23 @@ pub fn fetchAndAddDependencies( | ... | @@ -284,23 +308,23 @@ pub fn fetchAndAddDependencies( |
| 284 | 308 | ||
| 285 | root_prog_node.setEstimatedTotalItems(all_modules.count()); | 309 | root_prog_node.setEstimatedTotalItems(all_modules.count()); |
| 286 | 310 | ||
| 311 | if (this_hash == null) { | ||
| 312 | try dependencies_source.writer().writeAll("pub const packages = struct {\n"); | ||
| 313 | } | ||
| 314 | |||
| 287 | const deps_list = manifest.dependencies.values(); | 315 | const deps_list = manifest.dependencies.values(); |
| 288 | for (manifest.dependencies.keys(), 0..) |name, i| { | 316 | for (manifest.dependencies.keys(), 0..) |name, i| { |
| 289 | const dep = deps_list[i]; | 317 | const dep = deps_list[i]; |
| 290 | 318 | ||
| 291 | const sub_prefix = try std.fmt.allocPrint(arena, "{s}{s}.", .{ name_prefix, name }); | ||
| 292 | const fqn = sub_prefix[0 .. sub_prefix.len - 1]; | ||
| 293 | |||
| 294 | const sub = try fetchAndUnpack( | 319 | const sub = try fetchAndUnpack( |
| 295 | thread_pool, | 320 | thread_pool, |
| 296 | http_client, | 321 | http_client, |
| 297 | global_cache_directory, | 322 | global_cache_directory, |
| 298 | dep, | 323 | dep, |
| 299 | report, | 324 | report, |
| 300 | build_roots_source, | ||
| 301 | fqn, | ||
| 302 | all_modules, | 325 | all_modules, |
| 303 | root_prog_node, | 326 | root_prog_node, |
| 327 | name, | ||
| 304 | ); | 328 | ); |
| 305 | 329 | ||
| 306 | if (!sub.found_existing) { | 330 | if (!sub.found_existing) { |
| ... | @@ -313,11 +337,10 @@ pub fn fetchAndAddDependencies( | ... | @@ -313,11 +337,10 @@ pub fn fetchAndAddDependencies( |
| 313 | global_cache_directory, | 337 | global_cache_directory, |
| 314 | local_cache_directory, | 338 | local_cache_directory, |
| 315 | dependencies_source, | 339 | dependencies_source, |
| 316 | build_roots_source, | ||
| 317 | sub_prefix, | ||
| 318 | error_bundle, | 340 | error_bundle, |
| 319 | all_modules, | 341 | all_modules, |
| 320 | root_prog_node, | 342 | root_prog_node, |
| 343 | dep.hash.?, | ||
| 321 | ); | 344 | ); |
| 322 | } | 345 | } |
| 323 | 346 | ||
| ... | @@ -329,10 +352,47 @@ pub fn fetchAndAddDependencies( | ... | @@ -329,10 +352,47 @@ pub fn fetchAndAddDependencies( |
| 329 | } else { | 352 | } else { |
| 330 | try deps_pkg.add(gpa, dep.hash.?, sub.mod); | 353 | try deps_pkg.add(gpa, dep.hash.?, sub.mod); |
| 331 | } | 354 | } |
| 355 | } | ||
| 332 | 356 | ||
| 333 | try dependencies_source.writer().print(" pub const {s} = @import(\"{}\");\n", .{ | 357 | if (this_hash) |hash| { |
| 334 | std.zig.fmtId(fqn), std.zig.fmtEscapes(dep.hash.?), | 358 | const pkg_dir_sub_path = "p" ++ fs.path.sep_str ++ hash[0..hex_multihash_len]; |
| 359 | const build_root = try global_cache_directory.join(arena, &.{pkg_dir_sub_path}); | ||
| 360 | try dependencies_source.writer().print( | ||
| 361 | \\ pub const {} = struct {{ | ||
| 362 | \\ pub const build_root = "{}"; | ||
| 363 | \\ pub const build_zig = @import("{}"); | ||
| 364 | \\ pub const deps: []const struct {{ []const u8, []const u8 }} = &.{{ | ||
| 365 | \\ | ||
| 366 | , .{ | ||
| 367 | std.zig.fmtId(hash), | ||
| 368 | std.zig.fmtEscapes(build_root), | ||
| 369 | std.zig.fmtEscapes(hash), | ||
| 335 | }); | 370 | }); |
| 371 | for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| { | ||
| 372 | try dependencies_source.writer().print( | ||
| 373 | " .{{ \"{}\", \"{}\" }},\n", | ||
| 374 | .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(dep.hash.?) }, | ||
| 375 | ); | ||
| 376 | } | ||
| 377 | try dependencies_source.writer().writeAll( | ||
| 378 | \\ }; | ||
| 379 | \\ }; | ||
| 380 | \\ | ||
| 381 | ); | ||
| 382 | } else { | ||
| 383 | try dependencies_source.writer().writeAll( | ||
| 384 | \\}; | ||
| 385 | \\ | ||
| 386 | \\pub const root_deps: []const struct { []const u8, []const u8 } = &.{ | ||
| 387 | \\ | ||
| 388 | ); | ||
| 389 | for (manifest.dependencies.keys(), manifest.dependencies.values()) |name, dep| { | ||
| 390 | try dependencies_source.writer().print( | ||
| 391 | " .{{ \"{}\", \"{}\" }},\n", | ||
| 392 | .{ std.zig.fmtEscapes(name), std.zig.fmtEscapes(dep.hash.?) }, | ||
| 393 | ); | ||
| 394 | } | ||
| 395 | try dependencies_source.writer().writeAll("};\n"); | ||
| 336 | } | 396 | } |
| 337 | } | 397 | } |
| 338 | 398 | ||
| ... | @@ -470,10 +530,11 @@ fn fetchAndUnpack( | ... | @@ -470,10 +530,11 @@ fn fetchAndUnpack( |
| 470 | global_cache_directory: Compilation.Directory, | 530 | global_cache_directory: Compilation.Directory, |
| 471 | dep: Manifest.Dependency, | 531 | dep: Manifest.Dependency, |
| 472 | report: Report, | 532 | report: Report, |
| 473 | build_roots_source: *std.ArrayList(u8), | ||
| 474 | fqn: []const u8, | ||
| 475 | all_modules: *AllModules, | 533 | all_modules: *AllModules, |
| 476 | root_prog_node: *std.Progress.Node, | 534 | root_prog_node: *std.Progress.Node, |
| 535 | /// This does not have to be any form of canonical or fully-qualified name: it | ||
| 536 | /// is only intended to be human-readable for progress reporting. | ||
| 537 | name_for_prog: []const u8, | ||
| 477 | ) !struct { mod: *Package, found_existing: bool } { | 538 | ) !struct { mod: *Package, found_existing: bool } { |
| 478 | const gpa = http_client.allocator; | 539 | const gpa = http_client.allocator; |
| 479 | const s = fs.path.sep_str; | 540 | const s = fs.path.sep_str; |
| ... | @@ -484,25 +545,17 @@ fn fetchAndUnpack( | ... | @@ -484,25 +545,17 @@ fn fetchAndUnpack( |
| 484 | const hex_digest = h[0..hex_multihash_len]; | 545 | const hex_digest = h[0..hex_multihash_len]; |
| 485 | const pkg_dir_sub_path = "p" ++ s ++ hex_digest; | 546 | const pkg_dir_sub_path = "p" ++ s ++ hex_digest; |
| 486 | 547 | ||
| 487 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); | ||
| 488 | errdefer gpa.free(build_root); | ||
| 489 | |||
| 490 | var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) { | 548 | var pkg_dir = global_cache_directory.handle.openDir(pkg_dir_sub_path, .{}) catch |err| switch (err) { |
| 491 | error.FileNotFound => break :cached, | 549 | error.FileNotFound => break :cached, |
| 492 | else => |e| return e, | 550 | else => |e| return e, |
| 493 | }; | 551 | }; |
| 494 | errdefer pkg_dir.close(); | 552 | errdefer pkg_dir.close(); |
| 495 | 553 | ||
| 496 | try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{ | ||
| 497 | std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root), | ||
| 498 | }); | ||
| 499 | |||
| 500 | // The compiler has a rule that a file must not be included in multiple modules, | 554 | // The compiler has a rule that a file must not be included in multiple modules, |
| 501 | // so we must detect if a module has been created for this package and reuse it. | 555 | // so we must detect if a module has been created for this package and reuse it. |
| 502 | const gop = try all_modules.getOrPut(gpa, hex_digest.*); | 556 | const gop = try all_modules.getOrPut(gpa, hex_digest.*); |
| 503 | if (gop.found_existing) { | 557 | if (gop.found_existing) { |
| 504 | if (gop.value_ptr.*) |mod| { | 558 | if (gop.value_ptr.*) |mod| { |
| 505 | gpa.free(build_root); | ||
| 506 | return .{ | 559 | return .{ |
| 507 | .mod = mod, | 560 | .mod = mod, |
| 508 | .found_existing = true, | 561 | .found_existing = true, |
| ... | @@ -510,6 +563,9 @@ fn fetchAndUnpack( | ... | @@ -510,6 +563,9 @@ fn fetchAndUnpack( |
| 510 | } | 563 | } |
| 511 | } | 564 | } |
| 512 | 565 | ||
| 566 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); | ||
| 567 | errdefer gpa.free(build_root); | ||
| 568 | |||
| 513 | root_prog_node.completeOne(); | 569 | root_prog_node.completeOne(); |
| 514 | 570 | ||
| 515 | const ptr = try gpa.create(Package); | 571 | const ptr = try gpa.create(Package); |
| ... | @@ -534,7 +590,7 @@ fn fetchAndUnpack( | ... | @@ -534,7 +590,7 @@ fn fetchAndUnpack( |
| 534 | }; | 590 | }; |
| 535 | } | 591 | } |
| 536 | 592 | ||
| 537 | var pkg_prog_node = root_prog_node.start(fqn, 0); | 593 | var pkg_prog_node = root_prog_node.start(name_for_prog, 0); |
| 538 | defer pkg_prog_node.end(); | 594 | defer pkg_prog_node.end(); |
| 539 | pkg_prog_node.activate(); | 595 | pkg_prog_node.activate(); |
| 540 | pkg_prog_node.context.refresh(); | 596 | pkg_prog_node.context.refresh(); |
| ... | @@ -666,13 +722,6 @@ fn fetchAndUnpack( | ... | @@ -666,13 +722,6 @@ fn fetchAndUnpack( |
| 666 | return error.PackageFetchFailed; | 722 | return error.PackageFetchFailed; |
| 667 | } | 723 | } |
| 668 | 724 | ||
| 669 | const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path}); | ||
| 670 | defer gpa.free(build_root); | ||
| 671 | |||
| 672 | try build_roots_source.writer().print(" pub const {s} = \"{}\";\n", .{ | ||
| 673 | std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root), | ||
| 674 | }); | ||
| 675 | |||
| 676 | const mod = try createWithDir(gpa, global_cache_directory, pkg_dir_sub_path, build_zig_basename); | 725 | const mod = try createWithDir(gpa, global_cache_directory, pkg_dir_sub_path, build_zig_basename); |
| 677 | try all_modules.put(gpa, actual_hex, mod); | 726 | try all_modules.put(gpa, actual_hex, mod); |
| 678 | return .{ | 727 | return .{ |
src/main.zig+9-13| ... | @@ -4708,7 +4708,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4708,7 +4708,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4708 | .root_src_directory = build_directory, | 4708 | .root_src_directory = build_directory, |
| 4709 | .root_src_path = build_zig_basename, | 4709 | .root_src_path = build_zig_basename, |
| 4710 | }; | 4710 | }; |
| 4711 | if (!build_options.only_core_functionality) { | 4711 | if (build_options.only_core_functionality) { |
| 4712 | const deps_pkg = try Package.createFilePkg(gpa, local_cache_directory, "dependencies.zig", | ||
| 4713 | \\pub const packages = struct {}; | ||
| 4714 | \\pub const root_deps: []const struct { []const u8, []const u8 } = &.{}; | ||
| 4715 | \\ | ||
| 4716 | ); | ||
| 4717 | try main_pkg.add(gpa, "@dependencies", deps_pkg); | ||
| 4718 | } else { | ||
| 4712 | var http_client: std.http.Client = .{ .allocator = gpa }; | 4719 | var http_client: std.http.Client = .{ .allocator = gpa }; |
| 4713 | defer http_client.deinit(); | 4720 | defer http_client.deinit(); |
| 4714 | 4721 | ||
| ... | @@ -4717,12 +4724,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4717,12 +4724,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4717 | // access dependencies by name, since `@import` requires string literals. | 4724 | // access dependencies by name, since `@import` requires string literals. |
| 4718 | var dependencies_source = std.ArrayList(u8).init(gpa); | 4725 | var dependencies_source = std.ArrayList(u8).init(gpa); |
| 4719 | defer dependencies_source.deinit(); | 4726 | defer dependencies_source.deinit(); |
| 4720 | try dependencies_source.appendSlice("pub const imports = struct {\n"); | ||
| 4721 | |||
| 4722 | // This will go into the same package. It contains the file system paths | ||
| 4723 | // to all the build.zig files. | ||
| 4724 | var build_roots_source = std.ArrayList(u8).init(gpa); | ||
| 4725 | defer build_roots_source.deinit(); | ||
| 4726 | 4727 | ||
| 4727 | var all_modules: Package.AllModules = .{}; | 4728 | var all_modules: Package.AllModules = .{}; |
| 4728 | defer all_modules.deinit(gpa); | 4729 | defer all_modules.deinit(gpa); |
| ... | @@ -4746,11 +4747,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4746,11 +4747,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4746 | global_cache_directory, | 4747 | global_cache_directory, |
| 4747 | local_cache_directory, | 4748 | local_cache_directory, |
| 4748 | &dependencies_source, | 4749 | &dependencies_source, |
| 4749 | &build_roots_source, | ||
| 4750 | "", | ||
| 4751 | &wip_errors, | 4750 | &wip_errors, |
| 4752 | &all_modules, | 4751 | &all_modules, |
| 4753 | root_prog_node, | 4752 | root_prog_node, |
| 4753 | null, | ||
| 4754 | ); | 4754 | ); |
| 4755 | if (wip_errors.root_list.items.len > 0) { | 4755 | if (wip_errors.root_list.items.len > 0) { |
| 4756 | var errors = try wip_errors.toOwnedBundle(""); | 4756 | var errors = try wip_errors.toOwnedBundle(""); |
| ... | @@ -4760,10 +4760,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -4760,10 +4760,6 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 4760 | } | 4760 | } |
| 4761 | try fetch_result; | 4761 | try fetch_result; |
| 4762 | 4762 | ||
| 4763 | try dependencies_source.appendSlice("};\npub const build_root = struct {\n"); | ||
| 4764 | try dependencies_source.appendSlice(build_roots_source.items); | ||
| 4765 | try dependencies_source.appendSlice("};\n"); | ||
| 4766 | |||
| 4767 | const deps_pkg = try Package.createFilePkg( | 4763 | const deps_pkg = try Package.createFilePkg( |
| 4768 | gpa, | 4764 | gpa, |
| 4769 | local_cache_directory, | 4765 | local_cache_directory, |