API Documentation

This part of the documentation contains the API reference of the functions and classes that can be used in Craftfiles.

craftr.session

A Proxy to the current Session object that is being used for the current Craftr build session.

Note

If you’ve used Flask before: It’s similar to the Flask request object.

craftr.module = <Proxy unbound>

This werkzeug.LocalProxy subclass returns the current object when called instead of forwarding the call to the current object.

A Proxy of the Craftr module that is currently being executed. Modules are standard Python module objects. When a Craftr extension module is being executed, this proxy points to exactly that module.

# craftr_module(test)
# A stupid example
from craftr import module
import sys
assert project_name == module.project_name
assert sys.modules[__name__] is module()

Logging

The logging functions implement the print() interface.

craftr.debug(*args, stacklevel=1, verbosity=None, **kwargs)[source]
craftr.info(*args, stacklevel=1, **kwargs)[source]
craftr.warn(*args, stacklevel=1, **kwargs)[source]
craftr.error(*args, stacklevel=1, raise_=True, **kwargs)[source]

Tasks

craftr.task(func=None, *args, **kwargs)[source]

Create a task Target that uses the Craftr RTS feature. If func is None, this function returns a decorator that finally creates the Target, otherwise the task is created instantly.

The wrapped function must either

  • take no parameters, this is when both the inputs and outputs of the task are None, or
  • take two parameters being the inputs and outputs of the task
@task
def hello():  # note: no parameters
  info("Hello, World!")

@task(inputs = another_target, outputs = 'some/output/file')
def make_some_output_file(inputs, outputs):  # note: two parameters!
  # ...

yat = task(some_function, inputs = yet_another_target,
           name = 'yet_another_task')

Important

Be aware that tasks executed through Ninja (and thus via RTS) are executed in a seperate thread!

Note that unlike normal targets, a task is explicit by default, meaning that it must explicitly be specified on the command line or be required as an input to another target to be executed.

Parameters:
  • func – The callable function to create the RTS target with or None if you want to use this function as a decorator.
  • args – Additional args for the Target constructor.
  • kwargs – Additional kwargs for the Target constructor.
Returns:

Target or a decorator that returns Target

Helpers

craftr.return_()[source]

Raise a ModuleReturn exception, causing the module execution to be aborted and returning back to the parent module. Note that this function can only be called from a Craftr modules global stack frame, otherwise a RuntimeError will be raised.

craftr.expand_inputs(inputs, frameworks=None)[source]

Expands a list of inputs into a list of filenames. An input is a string (filename) or a Target object from which the Target.outputs are used. Returns a list of strings.

If frameworks is specified, it must be a list to which the frameworks of all input Target objects will be appended. The frameworks need to be expanded with expand_frameworks().

craftr.expand_frameworks(frameworks, result=None)[source]

Given a list of Framework objects, this function creates a new list that contains all objects of frameworks and additionally all objects that are listed in each of the frameworks "frameworks" key recursively. Duplicates are also elimated.

craftr.import_file(filename)[source]

Import a Craftr module by filename. The Craftr module identifier must be determinable from this file either by its #craftr_module(..) identifier or filename.

craftr.import_module(modname, globals=None, fromlist=None)[source]

Similar to importlib.import_module(), but this function can also imports contents of modname into globals. If globals is specified, the module will be directly imported into the dictionary. If fromlist list is *, a wildcard import into globals will be performed, otherwise fromlist must be None or a list of names to import.

This function always returns the root module.

craftr.craftr_min_version(version_string)[source]

Ensure the current version of Craftr is at least the version specified with version_string, otherwise call error().

Session Objects

class craftr.Session(cwd=None, path=None, server_bind=None, verbosity=0, strace_depth=3, export=False, buildtype='standard')[source]

This class manages a build session and encapsulates all Craftr modules and Targets.

cwd

The original working directory from which Craftr was invoked, or the directory specified with the -p command-line option. This is different than the current working directory since Craftr changes to the build directory immediately.

env

A dictionary of environment variables, initialized as a copy of os.environ. In a Craftfile, you can use os.environ or the alias craftr.environ instead, which is more convenient than accessing session.env.

path

A list of search paths for Craftr extension modules. See ext.

modules

A dictionary of Craftr extension modules. Key is the module name without the craftr.ext. prefix.

targets

A dictionary mapping the full identifier to Target objects that have been declared during the build session. When the Session is created, a clean Target which calls ninja -t clean is always created automatically.

files_to_targets

New in v1.1.0 Maps the files produced by all targets to their producing Target object. This dictionary is used for speeding up find_target_for_file() and to check if any file would be produced by multiple targets.

All keys in this dictionary are absolute filenames normalized with path.normpath().

server

An rts.CraftrRuntimeServer object that is started when the session context is entered with magic.enter_context() and stopped when the context is exited. See on_context_enter().

server_bind

A tuple of (host, port) which the server will be bound to when it is started. Defaults to None, in which case the server is bound to the localhost on a random port.

ext_importer

A ext.CraftrImporter object that handles the importing of Craftr extension modules. See ext.

var

A dictionary of variables that will be exported to the Ninja manifest.

verbosity

The logging verbosity level. Defaults to 0. Used by the logging functions debug(), info(), warn() and error().

strace_depth

The logging functions may print a stack trace of the log call when the verbosity is high enough. This defines the depth of the stack trace. Defaults to 3.

export

This is set to True when the -e option was specified on the command-line, meaning that a Ninja manifest will be exported. Some projects eventually need to export additional files before running Ninja, for example with TargetBuilder.write_command_file().

buildtype

The buildtype that was specified with the --buildtype command-line option. This attribute has two possible values: 'standard' and 'external'. Craftfiles and rule functions must take the buildtype into consideration. In 'external' mode, rule functions should consider external options wherever applicable, for example the CFLAGS environment variables instead or additionally to the standard flags for C source file compilation.

finalized

True if the Session was finalized with finalize().

exec_if_exists(filename)[source]

Executes filename if it exists. Used for running the Craftr environment files before the modules are loaded. Returns None if the file does not exist, a types.ModuleType object if it was executed.

finalize()[source]

Finalize the session, setting up target dependencies based on their input/output files to simplify verifying dependencies inside of Craftr. The session will no longer accept target registrations.

find_target_for_file(filename)[source]

Finds a target that outputs the specified filename.

on_context_enter(prev)[source]

Called when entering the Session context with magic.enter_context(). Does the following things:

Note

A copy of the original os.environ is saved and later restored in on_context_leave(). The os.environ object can not be replaced by another object, that is why we change its values in-place.

on_context_leave()[source]

Called when the context manager entered with magic.enter_context() is exited. Undos all of the stuff that on_context_enter() did and more.

register_target(target)[source]

This function is used by the Target constructor to register itself to the Session. This will add the target to the target dictionary and also update the files_to_targets mapping.

Parameters:

target – A Target object

Raises:
  • ValueError – If the name of the target is already reserved.
  • RuntimeError – If this target produces a file that is already produced by another arget.
start_server()[source]

Start the Craftr RTS server (see Session.server). It will automatically be stopped when the session context is exited.

Target Objects

class craftr.Target(command, inputs=None, outputs=None, implicit_deps=None, order_only_deps=None, requires=None, foreach=False, description=None, pool=None, var=None, deps=None, depfile=None, msvc_deps_prefix=None, explicit=False, frameworks=None, meta=None, module=None, name=None)[source]

This class is a direct representation of a Ninja rule and the corresponding in- and output files. Will be rendered into a rule and one or many build statements in the Ninja manifest.

New in v1.1.0: A target object can also represent a Python function as a target in the Ninja manifest. This is called an RTS task. Use the task() function to create tasks or pass a function for the command parameter of the Target constructor. The function must accept no parameters if inputs and outputs are both None or accept these two values as parameters.

name

The name of the target. This is usually deduced from the variable the target is assigned to if no explicit name was passed to the Target constructor. Note that the actual name of the generated Ninja rule must be read from fullname.

module

The Craftr extension module this target belongs to. Defaults to the currently executed module (retrieved from the thread-local module). Can be None, but only if there is no module currently being executed.

command

A list of strings that represents the command to execute. A string can be passed to the constructor in which case it is parsed with shell.split().

inputs

A list of filenames that are listed as inputs to the target and that are substituted for $in and $in_newline during the Ninja execution. Can be None. The Target constructor expands the passed argument with expand_inputs(), thus also accepts a single filename, Target or a list with Targets and/or filenames.

This attribute can also be None.

outputs

A list of filenames that are listed as outputs of the target and that are substituted for $out during the Ninja execution. Can be None. The Target constructor accepts a list of filenames or a single filename for this attribute.

This attribute can also be None.

implicit_deps

A list of filenames that are required to build the Target, additionally to the inputs, but are not expanded by the $in variable in Ninja. See “Implicit dependencies” in the Ninja Manual.

order_only_deps

See “Order-only dependencies” in the Ninja Manual.

requires

A list of targets that are to be built before this target is. This is useful for speciying task dependencies that don’t have input and/or output files.

The constructor accepts None, a Target object or a list of targets and will convert it to a list of targets.

@task
def hello():
  info("Hello!")

@task(requires = [hello])
def ask_name():
  info("What's your name?")
foreach

If this is set to True, the number of inputs must match the number of outputs. Instead of generating a single build instruction in the Ninja manifest, an instruction for each input/output pair will be created instead. Defaults to False.

description

A description of the Target. Will be added to the generated Ninja rule. Defaults to None.

pool

The name of the build pool. Defaults to None. Can be "console" for Targets that don’t actually build files but run a program. Craftr will treat Targets in that pool as if explicit is True.

deps

The mode for automatic dependency detection for C/C++ targets. See the “C/C++ Header Depenencies” section in the Ninja Manual.

depfile

A filename that contains additional dependencies.

msvc_deps_prefix

The MSVC dependencies prefix to be used for the rule.

frameworks

A list of Frameworks that are used by the Target. Rule functions that take other Targets as inputs can include this list. For example, a C++ compiler might add a Framework with libs = ['c++'] to a Target so that the Linker to which the C++ object files target is passed automatically knows to link with the c++ library.

Usually, a rule function uses the TargetBuilder (which internally uses expand_inputs()) to collect all Frameworks used in the input targets.

explicit

If True, the target will only be built by Ninja if it is explicitly specified on the command-line or if it is required by another target. Defaults to False.

meta

A dictionary of meta variables that can be set from anywhere. Usually, rule functions use this dictionary to promote additional information to the caller, for example what the actual computed output filename of a compilation is.

graph

Initially None. After finalize() is called, this is a namedtuple of Graph which has input and output sets of targets of the dependencies in the Target.

__lshift__(other)[source]

Shift operator to add to the list of implicit_deps.

Note

If other is or contains a Target, the targets frameworks are not added to this Target’s framework list!

class Graph(inputs, outputs)

Type for Target.graph

inputs

Alias for field number 0

outputs

Alias for field number 1

Target.RTS_Mixed = 'mixd'

The target and/or its dependencies are a mix of command-line targets and tasks

Target.RTS_None = 'none'

The target and its dependencies are plain command-line targets

Target.RTS_Plain = 'plain'

The target and all its dependencies are plain task targets

Target.as_explicit()[source]

Sets :attr`explicit` to True and retunrs self.

Target.execute_task(exec_state=None)[source]

Execute the rts_func of the target. This calls the function with the inputs and outputs of the target (if any of these are not None) or with no arguments (if both is None).

This function catches all exceptions that the wrapped function might raise and prints the traceback to stdout and raises a TaskError with status-code 1.

Parameters:

exec_state – If this parameter is not None, it must be a dictionary where the task can check if it already executed. Also, inputs of this target will be executed if the parameter is a dictionary.

Raises:
  • RuntimeError – If the target is not an RTS task.
  • TaskError – If this task (or any of the dependent tasks, only if exec_state is not None) exits with a not-None, non-zero exit code.
Target.finalize(session)[source]

Gather the inputs and outputs of the target and create a new Graph to fill the graph attribute.

Target.fullname

The full identifier of the Target. If the Target is assigned to a module, this is the module name and the Target.name, otherwise the same as Target.name.

Target.get_rts_mode()[source]

Returns the RTS information for this target:

  • RTS_None if this target and none of its dependencies
  • RTS_Plain if this target and all of its dependencies are tasks
  • RTS_Mixed if this target or any of its dependencies are tasks but there is at least one normal target

TargetBuilder Objects

class craftr.TargetBuilder(inputs, frameworks=(), kwargs=None, meta=None, module=None, name=None, stacklevel=1)[source]

This is a helper class to make it easy to implement rule functions that create a Target. Rule functions usually depend on inputs (being files or other Targets that can also contain additional frameworks), rule-level settings and Frameworks. The TargetBuilder takes all of this into account and prepares the data conveniently.

The following example shows how to make a simple rule function that compiles C/C++ source files into object files with GCC. The actual compiler name can be overwritten and additional flags can be specified by passing them directly to the rule function or via frameworks (accumulative).

#craftr_module(test)

from craftr import TargetBuilder, Framework, path
from craftr.ext import platform
from craftr.ext.compiler import gen_output

def compile(sources, frameworks=(), **kwargs):
  """
  Simple rule to compile a number of source files into an
  object files using GCC.
  """

  builder = TargetBuilder(sources, frameworks, kwargs)
  outputs = gen_output(builder.inputs, suffix = platform.obj)
  command = [builder.get('program', 'gcc'), '-c', '$in', '-o', '$out']
  command += builder.merge('additional_flags')
  return builder.create_target(command, outputs = outputs)

copts = Framework(
  additional_flags = ['-pedantic', '-Wall'],
)

objects = compile(
  sources = path.glob('src/**/*.c'),
  frameworks = [copts],
  additional_flags = ['-std=c11'],
)
Parameters:
  • inputs – Inputs for the target. Processed by expand_inputs(), the resulting frameworks are then processed by expand_frameworks(). The expanded inputs are saved in the inputs attribute of the TargetBuilder. Use this attribute instead of the original value passed to this parameter! It is guaruanteed to be a list of filenames only.
  • frameworks – A list of frameworks to take into account additionally.
  • kwargs – Additional options that will be turned into their own Framework object, but it will not be passed to the Target that is created with create_target() as these options should not be inherited by rules that will receive the target as input.
  • module – Override the module that will receive the target.
  • name – Override the target name. If not specified, the target name is retrieved using Craftr’s target name deduction from the name the target is assigned to.
  • stacklevel – The stacklevel which the calling rule function is at. This defaults to 1, which is fine for rule functions that directly create the TargetBuilder.
caller

Name of the calling function.

def my_rule(*args, **kwargs):
  builder = TargetBuilder(None)
  assert builder.caller == 'my_rule'
inputs

None or a pure list of filenames that have been passed via the inputs parameter of the TargetBuilder.

frameworks

A list of frameworks compiled from the frameworks of Target objects in the inputs parameter of the constructor and the frameworks that have been specified directly with the frameworks parameter.

kwargs

The additional options that have been passed with the kwargs argument. These are turned into their own Framework which is only taken into account for the options but it is not passed to the Target created with create_target().

options

A FrameworkJoin object that is used to read settings from the list of frameworks collected from the input Targets, the additional frameworks specified to the TargetBuilder constructor and the specified kwargs dictionary.

module
name

The name of the Target that is being built.

target_attrs

A dictonary of arguments that are set to the target after construction in create_target(). Can only set attributes that are already attributes of the Target.

meta

Meta data for the Target that is passed directly to Target.meta.

__getitem__(key)[source]

Alias for FrameworkJoin.__getitem__() on the options.

add_framework(fw, local=False, front=False)[source]

Adds the Framework “fw” to the builder and also to the target if “local” is False. The framework will be appended to the end of the chain, thus is has the lowest priority unless you pass “front” to True.

Parameters:
  • fw – The framwork to add.
  • local – If this is False, the framework will also be added to the target created by the builder.
  • front – If this is True, the framework will be added to the front of the frameworks list and thus will be treated with high priority.
create_target(command, inputs=None, outputs=None, **kwargs)[source]

Create a Target and return it.

Parameters:
  • command – The command-line for the Target.
  • inputs – The inputs for the Target. If None, the TargetBuilder.inputs will be used instead.
  • outputs – THe outputs for the Target.
  • kwargs – Additional keyword arguments for the Target constructor. Make sure that none conflicts with the target dictionary.

Note

This function will yield a warning when there are any keys in the kwargs dictionary that have not been read from the options.

expand_inputs(inputs)[source]

Wrapper for expand_inputs() that will add the Frameworks extracted from the inputs to options and frameworks.

fullname

The full name of the Target that is being built.

get(key, default=None)[source]

Alias for FrameworkJoin.get().

invalid_option(option_name, option_value=<object object>, cause=None)[source]

Use this method in a rule function if you found the value of an option has an invalid option. You should raise a ValueError on a fatal error instead.

log(level, *args, stacklevel=1, **kwargs)[source]

Log function that includes the fullname.

merge(key)[source]

Alias for FrameworkJoin.merge().

mkname(name)[source]

Create a unique target identifier which based on this target builders name and an incrementing index.

setdefault(key, value)[source]

Sets a value in the fwdefaults framework.

target

A dictonary of arguments that are set to the target after construction in create_target(). Can only set attributes that are already attributes of the Target.

Deprecated since version Use: target_attrs instead.

write_command_file(arguments, suffix=None, always=False)[source]

Writes a file to the CMDDIR folder in the build directory (ie. the current directory) that contains the command-line arguments specified in arguments. The name of that file is the name of the Target that is created with this builder. Optionally, a suffix for that file can be specified to be able to write multiple such files. Returns the filename of the generated file. If always is set to True, the file will always be created even if Session.export is set to False.

write_multicommand_file(commands, cwd=None, exit_on_error=True, suffix=None, always=False)[source]

Write a platform dependent script that executes the specified commands in order. If exit_on_error is True, the script will exit if an error is encountered while executing the commands.

Returns a list representing the command-line to run the script.

Parameters:
  • commands – A list of strings or command lists that are written into the script file.
  • cwd – Optionally, the working directory to change to when the script is executed.
  • exit_on_error – If this is True, the script will exit immediately if any command returned a non-zero exit code.
  • suffix – An optional file suffix. Note that on Windows, .cmd is added to the filename after that suffix.
  • always – If this is true, the file is always created, not only if a Ninja manifest is being exported (see Session.export).
Returns:

A tuple of two elements. The first element is a command list that represents the command used to invoke the created script. The second element is the actual command file that was written.

Framework Objects

class craftr.Framework(_Framework__fw_name=None, _Framework__init_dict=None, **kwargs)[source]

A Framework represents a set of options that are to be taken into account by compiler classes. Eg. you might create a framework that contains the additional information and options required to compile code using OpenCL and pass that to the compiler interface.

Compiler interfaces may also add items to Target.frameworks that can be taken into account by other target rules. expand_inputs() returns a list of frameworks that are being used in the inputs.

Use the FrameworkJoin class to create an object to process the data from multiple frameworks.

Parameters:
  • __fw_name – The name of the Framework. If omitted, the assigned name of the calling module will be used.
  • __init_dict – A dictionary to initialize the Framework with.
  • kwargs – Additional key/value pairs for the Framework.

FrameworkJoin Objects

class craftr.FrameworkJoin(*frameworks)[source]

This class is used to process a set of Frameworks and retreive relevant information from it. For some options, you might want to read the first value that is specified in any of the frameworks, for another you may want to create a list of all values in the frameworks. This is what the FrameworkJoin allows you to do.

Note

The FrameworkJoin does not use expand_frameworks() but uses the list of frameworks passed to the constructor as-is.

>>> fw1 = Framework('fw2', defines=['DEBUG'])
>>> fw2 = Framework(defines=['DO_STUFF'])
>>> print(fw2.name)
'fw2'
>>> FrameworkJoin(fw1, fw2).merge('defines')
['DEBUG', 'DO_STUFF']
used_keys

A set of keys that have been accessed via __getitem__(), get() and merge().

frameworks

The list of Framework objects.

defaults

An additional framework that can be used to set default values. This framework will always be checked last.

__iadd__(frameworks)[source]
get(key, default=None)[source]

Get the first available value of key from the frameworks.

keys()[source]

Returns a set of all keys in all frameworks.

merge(key)[source]

Merge all values of key in the frameworks into one list, assuming that every key is a non-string sequence and can be appended to a list.