apache/mynewt-newt

Circular dependencies may cause extraneous packages to get pulled into build

Closed this issue · 0 comments

During dependency resolution, newt adds packages to the builds as dependencies are discovered. Less commonly, newt also removes packages from the build when a dependency is nullified. When a syscfg setting's value changes, dependencies conditional on the setting may be nullified. For example:

Package A

# pkg.yml
pkg.deps.!FOO:
    - pkgb

Target

# syscfg.yml
syscfg.vals:
    FOO: 1

Initially, the FOO setting is unknown, so it defaults to 0. When package A is being processed, the conditional dependency on package B is considered valid, and B is added to the build. When the target is processed, it is discovered that FOO is actually 1, so A's dependency on B is nullified, and B must be removed from the build (assuming no other packages depend on B).

Newt handles the above case without issue. The issue is illustrated below:

Package B

# pkg.yml
pkg.deps:
    - pkgc

Package C

# pkg.yml
pkg.deps:
    - pkgb

B and C depend on each other. When B is initially pulled into the build, this also pulls in C, since B depends on C. When B is later removed from the build, C should also get removed (again, assuming no other packages depend on C).

The bug is: in this example, neither B nor C actually gets removed from the build. Newt uses references counting to determine when a package can be removed. When a package is found to have no dependents (a reference count of 0), newt removes it. Due to the circular dependency between B and C, neither package's reference count ever reaches 0.