Introduction

Edifice is a package manager and build automation tool adapted to the hardware industry. Edifice has ambition to be an language-agnostique and rust-powered package manager and automation tool. Its goal is to bring a scalable solution (1000+ IP management) to the hardware industry. Edifice is born to answer to scalability limations of the open source projects Fusesoc and Edalize.

Contributing

License

Limitations of Fusesoc

Python project Fusesoc is not able to efficiently load thousants modules from a registry:

  • Python is very slow
  • Fusesoc resolve the dependency three for each command
  • The fileset is not flexible enough
  • Compilation options are common to the whole dependency three
  • Module API and backend tools are not versionned as module
  • Flags has an impact on module dependencies
  • Build are not lockable which prevent reproducibility

Limitations of Edalize

  • Python is very slow
  • Backend API is common to all tools
  • Filesets three is flatenized before being send to backend tool

Configuration files

Module

A module is defined by a file module.toml in a versionned directory.

# module.toml

module_api = "0.1.0"

[module]
name = "module_a"
version = "0.1.0"

[dependencies]
rule_eda = "^1.2.3"
module_b = ">0.2.4"
module_c = "^0.6.1"
module_d = "~1.7.3"
module_e = "2.3.*"

The module version has to respect the semver version syntaxe and the version constraints have to respect the semver containts syntaxe.

Dataset

The transitive data management is done through the file dataset.toml of each module in the tree.

# dataset.toml of module_b

[eda.dataset.dataset_a]
sources = [
  "file_e",
  "file_f",
]
include_directories = []
compilation_options = [
  "+opt_c",
]
prepend = []

# dataset.toml of module_a

[eda.dataset.dataset_a]
sources = [
  "file_a",
  "file_b",
]
include_directories = [
  "include/",
]
compilation_options = [
  "+opt_a",
]
prepend = [
  "module_c.dataset_a",
]

[eda.dataset.dataset_b]
sources = [
  "file_c",
  "file_d",
]
include_directories = [
  "include/",
]
compilation_options = [
  "+opt_a",
]
prepend = [
  "module_b.dataset_a",
  "dataset_a",
]

Target

  • TODO

Dependencies management

Fetch registry

Add dependencies to module

Check module satisfability

Update dependencies version into lock file

Install modules localy

Build generation

Langage agnostique

Remotly cachable artifact

Edifice containes many tools and features:

  • A package manager (like Fusesoc, npm, composert ... etc)
  • A build automation tool (like Edalize, CMake ... etc)
  • Three configurations concept and files:
    • The module (module.toml): The name, the version and the dependencies of the package
    • The dataset (dataset.toml): The management of the transitives data along the dependencies tree
    • The targets (target.toml): The rules to produce the build

Inspirations

The main inspirations of Edifice are:

Installation

Requirements

Use Cargo

Run the following command to install:

cargo install --git https://github.com/Annrtl/Edifice

Environement

Variables

  • EDIFICE_BUILD: The path where the build directories are created. By default, the build is created in the current modude directory next to module.toml.
  • EDIFICE_CACHE: The path where the remote registries and the remote module sources are downloaded. By default, the cache is located in ~/.cache/edifice.
  • EDIFICE_REGISTRY: The URI of the registries separated with a colon (:).

Workspace configuration

# edifice.toml
[config]
EDIFICE_BUILD = '/local/build'
EDIFICE_CACHE = '~/.cache/edifice'
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

User configuration

# ~/.config/edifice/edifice.toml
EDIFICE_BUILD = '/local/build'
EDIFICE_CACHE = '~/.cache/edifice'
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

Global configuration

# /etc/edifice/edifice.toml
EDIFICE_BUILD = '/local/build'
EDIFICE_CACHE = '~/.cache/edifice'
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

Add a Registry

Description

The registry is used to index all released versions of the modules. It may be a local directory or a remote git repository. A remote registry may be updated in the cache using the command edifice fetch.

Use a registry

Update your environement variables

export EDIFICE_REGISTRY="/project/registry:${EDIFICE_REGISTRY}"
export EDIFICE_REGISTRY="git@github.com:Annrtl/Edifice_registry.git:${EDIFICE_REGISTRY}"

Add a edifice.toml configuration locally

# edifice.toml
[config]
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

Add a edifice.toml user configuration

# ~/.config/edifice/edifice.toml
[config]
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

Add a edifice.toml global configuration

# /etc/edifice/edifice.toml
[config]
EDIFICE_REGISTRY = 'git@github.com:Annrtl/Edifice_registry.git:/project/registry'

Create your own registry

Remote repository

  1. Create a new repository
  2. For each module to index add a module.toml anywhere in the repository.

It is recommanded to put a file module.toml in a a folder name/version/module.toml

Local directory

  1. Create a new directory
  2. For each module to index add a module.toml anywhere in the repository.

It is recommanded to put a file module.toml in a a folder name/version/module.toml

Workspace files

Principle

The modules definition is split in tree files: module.toml, dataset.toml and target.toml. This methode optimize the execution time of Edifice commands.

module.toml

The registries index only module.toml. This file required only to have a name, version, description and dependencies constraints. When the registry is fetched and analysed, Edifice has to read little files. The dataset.toml has to be known only at build time and target.toml only when the specified module is built.

dataset.toml

This file is accessible in the cache after the resolution of the dependencies tree. Edifice has to read this file only to get transitive data, to create the build.

target.toml

This file is only used when developer work on the specified module (E.g. running test). Edifice doesn't need to read the content of each dependencies's target.toml.

Commands depending on the files

Commandmodule.tomldataset.tomltarget.toml
addx
buildxx
checkx
clean
exportx
fetch
help
infox
install
listx
new
prune
publishx
runxx
searchx
updatex
version

Create your Module

The file module.toml defines the name, the version and the dependencies of your module.. The sections name and versions are already defines.

Find a depedency

To find the dependency you need you can use the command edifice search as follow:

edifice search <name>

or

edifice search <description>

The full list of the registry modules is available with the command edifice list

edifice list

To list locker module only add the option --locked

edifice list --locked

Add depedency

To add a dependency from the registry you need to use the command edifice add as follow:

edifice add <dependency_name>

Create your dataset

The dataset handle the current module files and its children's dataset. The dataset are not used in the tree resolution. We need it at build time to provide the data to the top level module. At each level user sould have as much control as possible on every lower level dataset.

Dataset containing files

# dataset.toml

[eda.dataset.dataset_a]
sources = [
  "file_e",
  "file_f",
]
include_directories = []
compilation_options = [
  "+opt_c",
]
prepend = []

Create your target

Build your project

Module

File

Purpose

The file module.toml is used to identify the root directory of a module and define its name and version.

Example

[module]
name = "demo"
version = "0.1.0"

API

Name

A String that describe the module

Version

A 3-digits version that complies the standard Semantic Versioning 2.0.0.

Directed Acyclic Graph

Deep First Search

Dataset

File

Rules

API

Target

File

Rules

API

Commands

Add

Description

Add a dependency to the current directory module.

Synopsys

edifice add [option] name

  • Where name is a String.

edifice add [option] name@version_requirement

  • Where name is a String.
  • Where version_requirement is a String with respecting the format of VersionReq.

Options

--dry-run: Look for an available version of the module but do not modify module.toml.

--help: Display command description and options.

Examples

edifice add dff

edifice add dff@0.1.4

edifice add dff@^0.1.0

Build

Description

Generate the build directory with a Makefile to run target. This generation depends on the backend rules used by the module.

Synopsys

edifice build [option]

Options

--build-dir: Location of the generate build directory. By default the location is the current directory. This option overwrite the environment variable EDIFICE_BUILD_DIR.

--help: Display command description and options.

Examples

edifice build

edifice build --build-dir /local/edifice

Check

Description

Check the requirements of the module is satisfiable.

Synopsys

edifice check [option]

Options

--unique: Requiere en unique version of each module in the dependency tree.

--help: Display command description and options.

Examples

edifice build

edifice build --unique

Clean

Description

Remove the module build directory

Synopsys

edifice clean [option]

Options

--help: Display command description and options.

Examples

edifice clean

Export

Description

Create a compressed directory allowing anyone to run the targets without edifice tool. This file is generated in the module directory next to module.toml. If no build directory exists yet, edifice build is implicitly ran and then compressed.

The compressed directory contains:

  • Makefile / Script
  • Sources
  • Artifacts (If some targets was already ran in build directory before the export)

Synopsys

edifice export [option]

Options

--format: Compression format. Default format is gz

  • gz: module_version.tar.gz
  • zip: module_version.zip

--name name: Name of the compressed file: name.tar.gz

--help: Display command description and options.

Examples

edifice export

edifice export --format zip

edifice export --name issue_1234

Fetch

Description

Update the cache of remote registries. This command should no be used if the registry is a local directory.

Synopsys

edifice fetch [option]

Options

--help: Display command description and options.

Examples

edifice fetch

Help

Description

Display the commands and global options of Edifice.

Synopsys

edifice help [option]

Options

--help: Display command description and options.

Examples

edifice help

Info

Description

Display informations about the module:

  • Name
  • Version
  • Dependencies
  • Datasets
  • Targets

You can specifiy a name and version to get informations of a module in registries.

Synopsys

edifice info [option] [name[@version]]

Options

--help: Display command description and options.

Examples

edifice info

edifice info dff

edifice info dff@0.1.4

Install

Description

Clone the dependencies directory in a new directory modules located in the module directory (next to module.toml).

Synopsys

edifice install

Options

--help: Display command description and options.

Examples

edifice install

List

Description

Display the list of available modules and their versions. If no regex pattern is specificed in argument, list all modules.

Synopsys

edifice list [option] [regex pattern]

Options

--locked: List only modules of the lockfile

--help: Display command description and options.

Examples

edifice list

edifice list '.*_model'

edifice list --locked

edifice list --locked '.*_model'

New

Description

Create a new project directory containing the minimal configuration files to run a first build.

my_project/
├── .gitignore
├── dataset.toml
├── module.toml
├── README.md
├── src
└── target.toml

Synopsys

edifice new [option] name

Options

--help: Display command description and options.

Examples

edifice new my_project

Prune

Description

Remove the cache of the remote registry.

Synopsys

edifice prune [option]

Options

--help: Display command description and options.

Examples

edifice prune

Publish

Description

Generate a copy of your module file with a registry section.

Two registry type are available:

  • Git
# $EDIFICE_REGISTRY/module/module.toml with git registry
[registry]
uri = "git@github.com:edifice/module.git"
commit = "fad83baa880db7b3ba61b88fdafdde2a666da05f"
  • Local
# $EDIFICE_REGISTRY/module/module.toml with local registry
[registry]
uri = "/absolute/path/to/local/module/directory"

If .git directory doesn't exists in the module directory, local registry is used.

Synopsys

edifice publish [option]

Options

--type: Type of registry:

  • git: Git uri
  • local: Local path

--help: Display command description and options.

Examples

edifice publish

edifice publish --type local

Run

Description

Run targets of the build specified in target.toml

Synopsys

edifice run [option] [target name regex]

Options

--help: Display command description and options.

Examples

edifice run

edifice run '.*-lint'

edifice run 'test_.*'

Search

Description

Search for a module according its name and its description.

Synopsys

edifice search [option] words

Options

--locked: Search only for modules of the lockfile

--help: Display command description and options.

Examples

edifice search

edifice search 'primitive component'

edifice search --locked

edifice search --locked 'primitive component'

Update

Description

Implictly run edifice check to get a satisfiable dependencies tree and write a lockfile module.lock which memorize the solution and guarantee the reproductibility of the build.

Synopsys

edifice update [option]

Options

--help: Display command description and options.

Examples

edifice update

Version

Description

Display the version of Edifice

Synopsys

edifice version [option]

Options

--help: Display command description and options.

Examples

edifice version