Skip to main content

A dependency-driven build manager based on xeno.

Project description

# Bakery: A Python build system straight out of the oven

Bakery is a dependency driven build system atop the
[Xeno]( injection framework. Bakery
allows you to define the structure and flow of your build process using plain
Python code. Bakery mixes the expressiveness of Makefiles with the power and
utility of the Python programming language.

### Note
Bakery is still in early development. There may be some rough edges or major
bugs. You are encouraged to try it out now and have fun, but keep in mind that
this is a living project and there's plenty more to come!

# Installation

Installation is simple. With python3-pip, do the following:

$ sudo pip install -e .

Or, to install the latest version available on PyPI:

$ sudo pip install bakery-build

Bakery is now available via the `bake` command:

$ bake

# Usage
The first step to using Bakery is to create a `` in your project.
This is a Python script that is executed via the `bake` command and contains
your *build module* definition. This module establishes the setup methods,
inputs, outputs, temporary resources and targets that are needed to build your

Via Xeno, dependencies are declared via the parameters provided to each target
method. Each target, input, output, and temporary resource may be defined as a
normal function or a coroutine. When coroutines are used this way, bakery will
schedule them in the current event loop. Using `asyncio` and the built-in
`shell` coroutine, it becomes easy to define a build workflow that can run
multiple concurrent tasks, such as compiling source files, in parallel.

## Example

This simple example defines a `` for a simple C project containing
number of source files which are linked into a resulting executable.

import as CXX
import as File
import os

CXX.CXX = 'clang++'
CXX.LDFLAGS = ['-lSDL2', '-lSDL2_image']

class LostLevels:
def demo_sources(self):
return File.glob('demo/*.cpp')

def build_dir(self):

def demo_resources(self, build_dir, demo_sources):
resource_paths = []
for source in demo_sources:
resource_dir = File.basename(File.drop_ext(source)) + '-rc'
File.join('demo', resource_dir),
File.join(build_dir, resource_dir)))
return resource_paths

def demo_objects(self, build_dir, demo_resources, demo_sources):
objects = []
for source in demo_sources:
object_file = File.join(build_dir, File.basename(File.swap_ext(source, 'o')))
objects.append(CXX.compile(source, object_file))
return objects

def demos(self, demo_objects):
return [, File.drop_ext(obj)) for obj in demo_objects]


In the above example, the following Bakery patterns are used:

- `@build` wraps the module so that it is evaluated by Bakery as a build module.
More than one module may be decorated with `@build`, but no more than one
target may be marked as `@default` among them.

- `@provide` is an annotation from
[Xeno](, marking the given
method as a named resource that can be injected into other resources (and
build targets) via their parameter name.

- `@target` is a Bakery annotation that marks a method as providing a target that
can be specified with the `bake` command.

- `@default` marks the method as a valid nameable target and the default target
to be executed when no other targets are specified with the `bake` command.

A few other useful Bakery patterns and tools to consider in your projects:

- `@recipe` marks a given function as defining a recipe for creating files.
The modification time of the input files is compared to the output if it
exists to determine if the recipe needs to be executed. Recipes should
generally return the name or names of the output files generated by the
recipe. The decorator takes the following arguments:
- `*args`: Names of parameters to the decorated function that represent
the outputs generated by the recipe.
- `check`: A string or list of strings indicating parameters containing
filenames or list of filenames that represent inputs to the
recipe. Bakery uses the modification time on these files
to determine if the recipe should be run.
- `temp`: Refers to parameters containing files that should be cleaned up
once the recipe finishes running.
Additionally, the decorated function may define annotated variables into which
special values are injected as follows:
- `log`: This parameter is provided with a logger specific to the recipe run.
Note that recipes can be defined inside or outside of your build module, this
choice is up to you.

- `shell`: This is a coroutine wrapper to `asyncio.create_subprocess_exec` which
captures and returns the output from the command as well as printing its
output and error output to the bakery logger. Prefer this function for
executing other programs such as compilers, unless the program requires a tty.

### Note
To make the most out of Bakery, you should first read up on
[Xeno]( *Build modules* in Bakery
are Xeno modules as well, allowing you to require and use resources defined in
other Xeno modules, such as the runtime parts of your Xeno-based project.

## Change Log
### Bakery v0.3.0 - May 4 2018
- Added `@noclean` decorator for resources which should not be cleaned when
`bake -c` is run.
- Fixed bug which prevented usage of namespaced or aliased resources.
- Due to the above bug fix, Bakery now depends on `xeno>=3.0.0`.

### Bakery v0.2.0 - May 3 2018
- First stable working version.

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for bakery-build, version 0.3.5
Filename, size File type Python version Upload date Hashes
Filename, size bakery-build-0.3.5.tar.gz (13.8 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page