Package: fdbuild
FDBuildConfigurable and extensible CLI tool
to fulfill tasks sequentially on a list of projects or vast project hierarchies.
Most commonly used for compiling many projects at once.FeaturesDefine ProjectsDefine projects in a hierarchy of directories. Settings are inherited.Pick plugins to work on these projects.Simple YAML syntax allows to easily define projects and share settings.
For example a toplevel settings fileprojects:-drm-kwinftsource:plugin:gitbuild:plugin:ninjathreads:maxwith the specific project settings filedrm/fdbuild.yaml:source:branch:mainorigin:https://gitlab.freedesktop.org/mesa/drm.gitconfigure:plugin:mesoninstall:path:/opt/drmsudo:falseCustomize settings in anfdbuild.yamlfile next to each project and subtree.ConvenienceWork all projects with a single command:fdbuildDepending on your working directory work a subtree with the very same command.Bootstrap a single project or whole hierarchies of projects via templates:fdbuild --init-with-template drmExtensibilitySeveral templates of popular open source projects are included.Work plugins for building most C and C++ software are included.Additional templates and work plugins can be installed as Python packages
that are automatically discovered.Getting StartedGet the latest release via:pip install fdbuild.Create a project from a template:fdbuild --init-with-template linux-desktop-meta.Change into the new directory and runfdbuild.Advanced UsageStep SelectionYou may skip steps in projects by the--noflag or do subset of steps with the--onlyflag.ExampleWith the stepssource, configure, build, installthe following two commands are equivalent:fdbuild --no source,buildfdbuild --only configure,installSettings OverrideUp to four key-value pairs may be overridden on invokation.
This overrides the value for any project independent of its position in the projects hierarchy.ExampleIn theabove examplewe may override the install path and sudo usage
as well as set the clear flag to do a clean build with:fdbuild --set install:path:/usr/local --set1 install:sudo:true --set2 build:clear:trueSettings HierarchiesWithout settings override through command line
a subproject always adheres to the nearest available settings value
in anfdbuild.yamlfile of its hierarchy.ExampleTake the following project tree:PRJ_A
│   fdbuild.yaml
│
└───PRJ_B
|   │   fdbuild.yaml
|   └───PRJ_C
|   │       fdbuild.yaml
|   └───PRJ_D
|           fdbuild.yaml
│
└───PRJ_E
        fdbuild.yamlTo query a specific settings value for projectPRJ_CFDBuild will first look inPRJ_A/PRJ_B/PRJ_C/fdbuild.yaml.
If this settings file defines the value FDBuild will use it on projectPRJ_C.Otherwise FDBuild will look intoPRJ_A/PRJ_B/fdbuild.yaml.
And if this settings file also does not provide the value
FDBuild will look intoPRJ_A/fdbuild.yaml.Likewise, for a settings value of projectPRJ_D, FDBuild will first check its settings filePRJ_A/PRJ_B/PRJ_D/fdbuild.yaml,
next the settings filePRJ_A/PRJ_B/fdbuild.yamland lastPRJ_A/fdbuild.yaml.For projectPRJ_EFDBuild will first look intoPRJ_A/PRJ_E/fdbuild.yaml,
and if the value is not found there look intoPRJ_A/fdbuild.yaml.If FDBuild is run in some directory the hierarchy unfolds recursively
according to theprojectslists in the working directory and all adjacent directories.
For example assume that in the above tree FDBuild is run from directoryPRJ_B,
then the settings file ofPRJ_Awill be considered
if and only ifPRJ_Bis listed in theprojectsentry of settings filePRJ_A/fdbuild.yaml.Assume further that the parent directory ofPRJ_Adoes not feature a FDBuild settings file listingPRJ_Aas one of its projects.
Then the lookup will stop here
andPRJ_Abecomes the toplevel directory of this project hierarchy
defined through the settings files.Settings ReferencesBesides common YAML syntax
you can use the following syntax for referencing other entries
in the same settings file or in another settings file within the project hierarchy:@{path_to_other_entry}.
If you need to use the sequence@{without declaring a reference you have to write@@{.The path to the other reference follows a certain syntax as well:
a section or entry in a settings file is denoted by one leading$,
project hierarchies are divided by/.Example$section$entry- take value from same settings file at labelssection: entry.prjA/prjB$entry- take value from labelentryin settings file of projectprjA/prjBrelative to the settings file of the reference./prjC/prjD$entry- take value from labelentryin the settings file of projectprjC/prjD,
whereasprjCis a subproject at the toplevel of the project hierarchy.Work DependenciesUsually projects are being worked on in the order defined by the projects hierarchy
and their position in theprojectskey.This can be bypassed by setting dependencies between projects via thedependskey
in thefdbuild.yamlfile of the project that should only be worked on after another one.Example:In theabove examplewriting additionallydepends:-kwinftto thedrm/fdbuild.yamlfile ensures
that the "kwinft" project is processed before the "drm" project.ExtensionsWith templates, stages, steps, and structurizers,
FDBuild can adapt to any work flow.
For users this means just installing another Python package.For developers this means hooking into FDBuild's defined entry points
and making their set of templates or plugin a Python package.TemplatesFDBuild can be made aware of additional templates by defining apaths()function for the
entry point groupfdbuild.templates.Thepaths()function should then return a list of paths,
where the template files of the package are stored.ExampleThe official template collection of FDBuild provides:an entry pointhooking upa paths() functionreturning a list with the path toa directory containing the templatesPluginsStage, step and structurizer plugins allow to extend FDBuild
in order to organize work for any project imaginable.StagesA stage provides an abstract view on a task.Defining a custom stage means finding a unique name describing its purpose
and then creating for it an entry hook in thefdbuild.stagesgroup.The entry point must be a class inheritingfdbuild.core.stage.Stage.
Its constructor should take an object of typefdbuild.core.step.Stepas argument
and forward it to the super constructor.
The abstract functionality of the stage can then be declared at will
as member functions of the class.StepsA step implements a stage.
They may access the abstract functionality of a certain stage
to conduct specific operations to fulfil the task at hand.Defining a custom step means finding a unique name
and then creating for it an entry hook in thefdbuild.stepsgroup.The entry point must be a class
with its constructor taking an object of typefdbuild.core.step.Stepas argument.
The class must provide awork()member function
that is then called by FDBuild to work on the stage.StructurizersA structurizer allows creating and updating complex project structures
before the actual work starts on them.Defining a custom structurizer means finding a unique name
and then creating for it an entry hook in thefdbuild.structurizersgroup.The entry point must be a class
with its constructor taking an object of typefdbuild.core.structurizer.Structurizeras argument.
The class must provide astructure(..)member function
that takes an object of typefdbuild.core.log.StructureLogas argument
and returns a map that describes all settings files of projects being structurized.StatusThis software has been used actively in production already for several years but without a proper release.
Now we first release an unstable version to gather feedback and in particular stabilize the extensions API.
Long-term the goal is a 1.0 release with stable settings syntax and extension API. But until then both may still change in backwards incompatible ways. Such changes will be listed in the changelog though.DevelopmentThere are a number of openfeature tickets.
If you are interested in working on one, comment in the ticket or contact us in ourGitter/Matrixroom.