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:
- Bazel (website, github)
- Versionned rules
- Flexibility of the flow
- Npm (website, github)
- Commands
- Usage
- Semver
- Orbit (website, github)
- Usage of Rust language
- Commands
- Cargo (website, github)
- Commands
- DFS algorithm
- Fusesoc (website, github)
- Semver
- DAG (Directed Acyclic Graph)
- Generators
- Edalize (website, github)
- Tools
- Modular backend
Installation
Requirements
- Cargo, you can install it using this instructions.
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 tomodule.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
- Create a new repository
- For each module to index add a
module.tomlanywhere in the repository.
It is recommanded to put a file module.toml in a a folder name/version/module.toml
Local directory
- Create a new directory
- For each module to index add a
module.tomlanywhere 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
| Command | module.toml | dataset.toml | target.toml |
|---|---|---|---|
| add | x | ||
| build | x | x | |
| check | x | ||
| clean | |||
| export | x | ||
| fetch | |||
| help | |||
| info | x | ||
| install | |||
| list | x | ||
| new | |||
| prune | |||
| publish | x | ||
| run | x | x | |
| search | x | ||
| update | x | ||
| 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.gzzip: 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 urilocal: 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