Dependency Sets

Dependency sets are named collections of package dependencies that let you maintain different profiles for different scenarios – development vs release, different build targets, or different feature sets. For a conceptual overview, see Core Concepts.

Defining Dependency Sets

Basic Structure

Define dependency sets in your ivpm.yaml:

package:
  name: my-project
  default-dep-set: default-dev  # Default when not specified

  dep-sets:
    - name: default           # Release dependencies
      deps:
        - name: runtime-lib
          url: https://github.com/org/runtime-lib.git

    - name: default-dev       # Development dependencies
      deps:
        - name: runtime-lib
          url: https://github.com/org/runtime-lib.git
        - name: pytest
          src: pypi
        - name: test-framework
          url: https://github.com/org/test-framework.git

Standard Names

While you can use any names, IVPM recognizes these standard names:

default

Release/runtime dependencies. Use this for packages you’re distributing.

default-dev

Development dependencies. Includes everything from default plus development tools. This is no longer special - any name can be used.

Dep-Set Inheritance with uses

The uses field lets a dep-set inherit all packages from another dep-set defined in the same ivpm.yaml. This avoids duplicating shared entries across multiple sets.

Merge rules

  • Every package from the base dep-set is copied into the child dep-set.

  • If the same package name appears in both, the child’s definition wins.

  • Inheritance is resolved at parse time, so there is no runtime overhead.

  • Chains of any depth are supported (a uses b uses c …).

  • Cycles are detected and raise an error.

  • Definition order does not matter; the base may be defined after the child.

Basic exampledefault-dev extends default:

package:
  name: my-project
  default-dep-set: default-dev

  dep-sets:
    - name: default
      deps:
        - name: runtime-lib
          url: https://github.com/org/runtime-lib.git

    - name: default-dev
      uses: default          # inherit runtime-lib from above
      deps:
        - name: pytest
          src: pypi
        - name: test-framework
          url: https://github.com/org/test-framework.git

Running ivpm update -d default-dev installs runtime-lib, pytest, and test-framework. Running ivpm update -d default installs only runtime-lib.

Overriding an inherited package — pin a different version in the child:

dep-sets:
  - name: default
    deps:
      - name: mylib
        url: https://github.com/org/mylib.git
        branch: v1.0

  - name: default-dev
    uses: default
    deps:
      - name: mylib
        url: https://github.com/org/mylib.git
        branch: dev   # overrides the v1.0 branch from 'default'
      - name: pytest
        src: pypi

Multi-level inheritance:

dep-sets:
  - name: base
    deps:
      - name: core-lib
        src: pypi

  - name: dev
    uses: base
    deps:
      - name: pytest
        src: pypi

  - name: ci
    uses: dev
    deps:
      - name: coverage
        src: pypi
      # inherits core-lib (from base via dev) and pytest (from dev)

Using Dependency Sets

Selecting a Set

On the command line:

# Use default dep-set (from default-dep-set or first dep-set)
ivpm update

# Explicitly use development dependencies
ivpm update -d default-dev

# Use release dependencies
ivpm update -d default

# Use custom dependency set
ivpm update -d fpga-build

Setting the default:

package:
  name: my-project
  default-dep-set: default-dev

If default-dep-set is specified, that set is used when no -d option is given to ivpm update. If default-dep-set is not specified, the first dep-set listed in the file is used as the default.

Complete Examples

Example 1: Simple Dev/Release Split

package:
  name: uart-ip
  default-dep-set: default-dev

  dep-sets:
    - name: default
      deps:
        - name: wishbone-if
          url: https://github.com/vendor/wishbone.git
          branch: v1.0

    - name: default-dev
      deps:
        - name: wishbone-if
          url: https://github.com/vendor/wishbone.git
          branch: v1.0
        - name: cocotb
          src: pypi
        - name: vcd-tools
          url: https://github.com/tools/vcd.git

Example 2: Multiple Build Targets

package:
  name: soc-design
  default-dep-set: sim

  dep-sets:
    - name: sim
      deps:
        - name: cpu-core
          url: https://github.com/org/cpu.git
        - name: verilator
          url: https://github.com/verilator/verilator.git

    - name: fpga
      deps:
        - name: cpu-core
          url: https://github.com/org/cpu.git
        - name: xilinx-ips
          url: https://github.com/org/xilinx.git

    - name: asic
      deps:
        - name: cpu-core
          url: https://github.com/org/cpu.git
        - name: pdk-libs
          url: https://github.com/org/pdk.git

Hierarchical Dependency Sets

When a dependency has its own ivpm.yaml, you can control which of its dependency sets is loaded.

Dependency Set Inheritance

By default, sub-packages inherit the parent’s dependency set name:

Root Project
  dep-set: "default-dev"
    ↓
  Dependency A (uses "default-dev")
    ↓
  Sub-dependency A1 (uses "default-dev")

Example:

# Root project
package:
  name: root-project
  dep-sets:
    - name: default-dev
      deps:
        - name: sub-package
          url: https://github.com/org/sub.git
          # No dep-set specified → inherits "default-dev"

When ivpm update -d default-dev runs:

  1. Loads root-project with default-dev

  2. Fetches sub-package

  3. Loads sub-package with default-dev (inherited)

Overriding Dependency Sets

You can explicitly specify which dependency set a sub-package should use:

package:
  name: root-project
  dep-sets:
    - name: default-dev
      deps:
        - name: library-a
          url: https://github.com/org/library-a.git
          dep-set: default  # Use release deps from library-a

        - name: test-tools
          url: https://github.com/org/tools.git
          dep-set: default-dev  # Use dev deps from tools

Use case: Include a third-party library’s release dependencies even when developing, to avoid pulling in all their development tools.

Default Dependency Set for Sub-Packages

You can set a default dep-set that all sub-packages will use:

package:
  name: root-project
  dep-sets:
    - name: default-dev
      default-dep-set: default  # All sub-packages use "default"
      deps:
        - name: library-a
          url: https://github.com/org/library-a.git
          # Uses "default" (from default-dep-set)

        - name: library-b
          url: https://github.com/org/library-b.git
          dep-set: default-dev  # Override: use dev deps

Dependency Set Diagram

┌──────────────────────────────────────────────────┐
│ Root Project: ivpm update -d default-dev         │
│   default-dep-set in dep-set: default            │
└────────┬─────────────────────────────────────────┘
         │
         ├─ Library A (dep-set: not specified)
         │    → Uses "default" (from parent's default-dep-set)
         │    ├─ Sub-dep A1 → Uses "default" (inherited)
         │    └─ Sub-dep A2 → Uses "default" (inherited)
         │
         ├─ Library B (dep-set: default-dev)
         │    → Uses "default-dev" (explicitly overridden)
         │    └─ Sub-dep B1 → Uses "default-dev" (inherited)
         │
         └─ Tool C (dep-set: not specified)
              → Uses "default" (from parent's default-dep-set)

Common Patterns

Pattern 1: Shared Dependencies

Include common dependencies in both sets:

dep-sets:
  - name: default
    deps:
      - name: core-lib
        url: https://github.com/org/core.git

  - name: default-dev
    deps:
      - name: core-lib
        url: https://github.com/org/core.git
      - name: pytest
        src: pypi

Pattern 2: Development Tools Only

Keep development tools completely separate:

dep-sets:
  - name: default
    deps:
      - name: runtime-lib
        url: https://github.com/org/runtime.git

  - name: tools
    deps:
      - name: linter
        src: pypi
      - name: formatter
        src: pypi

Usage: ivpm update -d default && ivpm update -d tools

Pattern 3: Conditional Dependencies

Use different dependency sets for optional features:

dep-sets:
  - name: minimal
    deps:
      - name: core
        url: https://github.com/org/core.git

  - name: with-gui
    deps:
      - name: core
        url: https://github.com/org/core.git
      - name: gui-toolkit
        url: https://github.com/org/gui.git

  - name: with-plugins
    deps:
      - name: core
        url: https://github.com/org/core.git
      - name: plugin-system
        url: https://github.com/org/plugins.git

Best Practices

  1. Use standard names (default, default-dev) for consistency

  2. Set default-dep-set in your project root for developer convenience

  3. Keep release deps minimal - only include what’s needed at runtime

  4. Document custom sets - explain when to use each set

  5. Control sub-dependencies - use dep-set override to avoid pulling excess deps

  6. Test both profiles - ensure default works without dev tools

See Also