Skip to content

Automatically resolve module dependencies #76

@foip

Description

@foip

Feature Request: Automatically resolve module dependencies

This approach would be a drastic change to the direction of this project.
But I think it would be a nice approach, so I want to discuss it before trying to implement it.

What

At the moment the user has to declare all source modules and their dependencies inside zork.toml.
It would be nice if Zork could take care of that.

Why

All the alternative C++ build systems use some sort of scripting language for build configuration.
Zork uses a more declarative way with TOML.

The problem with that is, that we can never match the configurability of a full blown scripting language.
And I don't think we have to.
Cargo for example also doesn' t allow full configuration for all source files, it allows just enough.
This is a tradeoff between configurability and usability, and usability is what makes cargo so great.
I think the usability route would be the right way for Zork.

Having to explicitly and correctly specify all source files and dependencies puts the burden onto the user.
The user also has to change zork.toml potentially every time he makes code changes or refactorings.

How could it be implemented

We would have to scan the source files for import statements after Loading the configuration file.
Then we could fill the dependencies properties in the project model.

We could put the dependencies in a subdirectory of the cache, so we only have to scan the source file, if the code changed.
It could look something like that:

|-out
  |-dependencies
    | - math.deps
    | - math2.deps
    | - ...

Where a deps file could just be a plain text list of the dependencies

// math2.deps
math

Tradeoffs

As mentioned above, the tradeoff is having to scan each changed source file once per build.
But I would argue that having Zork scan the source files and determining the dependencies is still way faster than the user having to change the configuration manually (and less error prone for the user).

Taking it a step further

This might be taking it a bit too far, but here goes.

We could also take the full Cargo route, where the user only has to specify the entry point of the application (or entry points of the library).
We simply scan the "entry" source file and only compile dependencies if needed.

But there is only one way I could think of to make this work.
We would have to mandate that the source file location of modules correspond to the module name.
For example the package com.github.zork would need to have the path src/com/github/zork.cppm or src/com/github/zork/mod.cppm or something like that.
Module partitions could live in that directory too:

|-src
  |-com
    |-github
      |-zork
        |-mod.cppm
        |-some_partition.cppm
        |-some_implementation.cpp

If some other module depends on this module we could simply compile the entire directory, where mod.cppm is the main module file, other cppm files are module partitions and .cpp files are implementation files.
Of course you could make the extensions configurable.

You could again argue that this would take a lot of configurability from the user, but if we look around in ecosystems of other languages as well, we find that classical C++ build systems are the only ones where you have no standardised source directory structure.

Most of the configuration inside zork.toml is done once and then never changed (like name or authors).
So the source file configuration is the largest burden on the user.
With these changes that burden would disappear almost completely.

The cache strategy from above would also work with these more drastic changes, if we are concerned with performance.

Again, this is a very radical direction so I would like to hear your opinion.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestfeatureSomething new in the application or library

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions