Skip to content

Conversation

@plajjan
Copy link
Contributor

@plajjan plajjan commented Dec 8, 2025

In order to compile a project with dependencies (and in turn their dependencies) we used to invoke ourselves, i.e. start another actonc process to first compile the dependency projects (which in turn would invoke a sub-compiler in case they had dependencies). Once done, by carefully assembling a search-path, we could reach all the .ty files and in the final build step, the build.zig and generated C source code of all dependencies necessary in order to link the final binaries.

We now perform all that work the proper way, staying within a single compiler instance, by first constructing a total build graph; a DAG that includes the modules of all projects. Just like before, we compile modules concurrently up to the maximum number of capabilities (Haskell speak for worker threads) and our critical-path cost approximation is still active, but can now track the cost along the whole path, from the cost of modules within dependencies of dependencies, which should yield a better total order potentially. It's also interesting to note that in dependency projects, we won't necessarily compile all modules - only those that have been chased down by an import. Pure test files for example, should not be needed and thus won't be compiled.

Some of the output has been updated to reflect in which project a module is to make it easier to distinguish. I've left it at this point though - I think we should do a major revamp of this now that we do concurrent compilation across projects. It deserves some proper love!

In order to compile a project with dependencies (and in turn their
dependencies) we used to invoke ourselves, i.e. start another actonc
process to first compile the dependency projects (which in turn would
invoke a sub-compiler in case they had dependencies). Once done, by
carefully assembling a search-path, we could reach all the .ty files and
in the final build step, the build.zig and generated C source code of
all dependencies necessary in order to link the final binaries.

We now perform all that work the proper way, staying within a single
compiler instance, by first constructing a total build graph; a DAG that
includes the modules of all projects. Just like before, we compile
modules concurrently up to the maximum number of capabilities (Haskell
speak for worker threads) and our critical-path cost approximation is
still active, but can now track the cost along the whole path, from the
cost of modules within dependencies of dependencies, which should yield
a better total order potentially. It's also interesting to note that in
dependency projects, we won't necessarily compile all modules - only
those that have been chased down by an import. Pure test files for
example, should not be needed and thus won't be compiled.

Some of the output has been updated to reflect in which project a module
is to make it easier to distinguish. I've left it at this point though -
I think we should do a major revamp of this now that we do concurrent
compilation across projects. It deserves some proper love!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants