Skip to content

use an additional, project-local copy of dependency trees #14283

Closed as not planned
@andrewrk

Description

@andrewrk

Extracted from #14265.

Terminology clarification:

  • A project is a directory of files, uniquely identified by their hash. Dependencies can export any number of artifacts and packages.
  • A dependency is a directed edge between projects. A project may depend on any number of projects. A project may be a dependency of any number of projects.
  • A package is a directory of files, along with a root source file that identifies the file referred to when the package is used with @import.
  • An artifact is a static library, a dynamic library, an executable, or an object file.

Currently, zig puts all fetched dependencies in the global zig cache, like this:

$GLOBAL_ZIG_CACHE/p/$DEPENDENCY_HASH/*

Then, dependencies are used directly from this directory, and shared among all projects.

This proposal is for zig build to additionally copy each dependency from the global cache into a project-local directory, like this:

$PROJECT_ROOT/zig-deps/$DEPENDENCY_NAME/*

A transitive dependency would look like this:

$PROJECT_ROOT/zig-deps/$NAME1/zig-deps/$NAME2/*

This would be similar to the node_modules directory from npm.

Motivations:

  • whether a build requires network access is independent from the state of the global cache system
  • it would be possible to wipe the global cache without forcing projects to re-fetch their dependencies. Similarly adding GC or LRU to the global cache would not sometimes delete dependencies for a particular project.
  • it would be possible to wipe a project's dependencies without wiping the global cache
  • it is easier to find dependencies by name, and locally patch them to test changes
  • temporary patches to dependencies would affect only one project; not the entire system globally
  • it would become an option to commit the zig-deps directory into source control, or to distribute a tarball that includes the dependencies
  • better compile errors when the lines point to dependencies; instead of getting a hash in the file name, you get the package name

Downsides:

  • multiple copies of things on disk, wasting disk space
  • somebody's going to suggest symlinking and all sorts of complicated stuff to go along with it
  • an additional directory alongside zig-out and zig-cache: zig-deps.

Open question: where to store the hash? It's nice to use the dependency name instead of the hash for the directory name, but it does leave the problem of how zig build should detect whether a dependency needs to be updated or not. It can always recompute hashes, but it should not be recomputing hashes on every zig build. Ideally, it would be only one open() call to open the directory of a dependency and find out whether the desired hash is present or not.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementSolving this issue will likely involve adding new logic or components to the codebase.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.zig build systemstd.Build, the build runner, `zig build` subcommand, package management

    Type

    No type

    Projects

    Status

    Proposals

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions