A catch-all compile-tool wrapper
Project description
blight
blight is a framework for wrapping and instrumenting build tools and build
systems. It contains:
- A collection of high-fidelity models for various common build tools (e.g. the C and C++ compilers, the standard linker, the preprocessor, etc.);
- A variety of "actions" that can be run on each build tool or specific
classes of tools (e.g. "whenever the build system invokes
$CC, add this flag"); - Command-line wrappers (
blight-envandblight-exec) for instrumenting builds.
Installation
blight is available on PyPI and is installable via pip:
python -m pip install blight
Python 3.7 or newer is required.
Usage
blight comes with two main entrypoints:
blight-exec: directly execute a command within ablight-instrumented environmentblight-env: write ash-compatible environment definition tostdout, which the shell or other tools can consume to enter ablight-instrumented environment
In most cases, you'll probably want blight-exec. blight-env can be thought
of as the "advanced" or "plumbing" interface.
Usage: blight-exec [OPTIONS] TARGET [ARGS]...
Options:
--guess-wrapped Attempt to guess the appropriate programs to wrap
--swizzle-path Wrap via PATH swizzling
--stub STUB Stub a command out while swizzling
--shim SHIM Add a custom shim while swizzling
--action ACTION Enable an action
--journal-path PATH The path to use for action journaling
--help Show this message and exit.
Usage: blight-env [OPTIONS]
Options:
--guess-wrapped Attempt to guess the appropriate programs to wrap
--swizzle-path Wrap via PATH swizzling
--stub TEXT Stub a command out while swizzling
--shim TEXT Add a custom shim while swizzling
--unset Unset the tool variables instead of setting them
--help Show this message and exit.
Quickstart
The easiest way to get started with blight is to use blight-exec with
--guess-wrapped and --swizzle-path. These flags tell blight to configure
the environment with some common-sense defaults:
--guess-wrapped: guess the appropriate underlying tools to invoke from the currentPATHand other runtime environment;--swizzle-path: rewrite thePATHto put some common build tool shims first, e.g. redirectingcctoblight-cc.
For example, the following will run cc -v under blight's instrumentation,
with the Demo
action:
blight-exec --action Demo --swizzle-path --guess-wrapped -- cc -v
which should produce something like:
[demo] before-run: /usr/bin/cc
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: x86_64-apple-darwin22.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
[demo] after-run: /usr/bin/cc
We can also see the effect of --swizzle-path by running which cc under
blight, and observing that it points to a temporary shim rather than the
normal cc location:
$ blight-exec --swizzle-path --guess-wrapped -- which cc
/var/folders/zj/hy934vnj5xs68zv6w4b_f6s40000gn/T/tmp5uahp6tg@blight-swizzle@/cc
$ which cc
/usr/bin/cc
All the Demo action does is print a message before and after each tool run,
allowing you to diagnose when a tool is or isn't correctly instrumented.
See the actions documentation below for information on
using and configuring more interesting actions.
Cookbook
Running blight against a make-based build
Most make-based builds use $(CC), $(CXX), etc., which means that they
should work out of the box with blight-exec:
blight-exec --guess-wrapped -- make
In some cases, poorly written builds may hard-code cc, clang, gcc, etc.
rather than using their symbolic counterparts. For these, you can use
--swizzle-path to interpose shims that redirect those hardcoded tool
invocations back to blight's wrappers:
blight-exec --guess-wrapped --swizzle-path -- make
See Taming an uncooperative build with shims and stubs for more advanced techniques for dealing with poorly written build systems.
Enabling actions
Actions are where blight really shines: they allow you to run arbitrary Python
code before and after each build tool invocation.
blight comes with built-in actions, which are
documented here.
See each action's Python module for its documentation.
Actions can be enabled in two different ways:
-
With the
--actionflag, which can be passed multiple times. For example,--action SkipStrip --action Recordenables both theSkipStripandRecordactions. -
With the
BLIGHT_ACTIONSenvironment variable, which can take multiple actions delimited by:. For example,BLIGHT_ACTIONS=SkipStrip:Recordis equivalent to--action SkipStrip --action Record.
Actions are run in the order of specification with duplicates removed, meaning
that BLIGHT_ACTIONS=Foo:Bar:Foo is equivalent to BLIGHT_ACTIONS=Foo:Bar
but not BLIGHT_ACTIONS=Bar:Foo. This is important if actions have side
effects, which they may (such as modifying the tool's flags).
Action configuration
Some actions accept or require additional configuration, which is passed
through the BLIGHT_ACTION_{ACTION} environment variable in key=value
format, where {ACTION} is the uppercased name of the action.
For example, to configure Record's output file:
BLIGHT_ACTION_RECORD="output=/tmp/output.jsonl"
Action outputs
There are two ways to get output from actions under blight:
- Many actions support an
outputconfiguration value, which should be a filename to write to. This allows each action to write its own output file. blightsupports a "journaling" mode, in which all action outputs are written to a single file, keyed by action name.
The "journaling" mode is generally encouraged over individual outputs,
and can be enabled with either BLIGHT_JOURNAL_PATH=/path/to/output.jsonl
in the environment or blight-exec --journal-path /path/to/output.jsonl.
Configuring an environment with blight-env
blight-env behaves exactly the same as blight-exec, except that it
stops before actually executing anything. You can use it to set up an
environment for use across multiple build system runs.
By default, blight-env will just export the appropriate environment
for replacing CC, etc., with their blight wrappers:
$ blight-env
export CC=blight-cc
export CXX=blight-c++
export CPP=blight-cpp
export LD=blight-ld
export AS=blight-as
export AR=blight-ar
export STRIP=blight-strip
export INSTALL=blight-install
--guess-wrapped augments this by adding a best-guess underlying tool for
each wrapper:
$ blight-env --guess-wrapped
export BLIGHT_WRAPPED_CC=/usr/bin/cc
export BLIGHT_WRAPPED_CXX=/usr/bin/c++
export BLIGHT_WRAPPED_CPP=/usr/bin/cpp
export BLIGHT_WRAPPED_LD=/usr/bin/ld
export BLIGHT_WRAPPED_AS=/usr/bin/as
export BLIGHT_WRAPPED_AR=/usr/bin/ar
export BLIGHT_WRAPPED_STRIP=/usr/bin/strip
export BLIGHT_WRAPPED_INSTALL=/usr/bin/install
export CC=blight-cc
export CXX=blight-c++
export CPP=blight-cpp
export LD=blight-ld
export AS=blight-as
export AR=blight-ar
export STRIP=blight-strip
export INSTALL=blight-install
--guess-wrapped also respects CC, etc. in the environment:
$ CC=/some/custom/cc blight-env --guess-wrapped
export BLIGHT_WRAPPED_CC=/some/custom/cc
export BLIGHT_WRAPPED_CXX=/usr/bin/c++
export BLIGHT_WRAPPED_CPP=/usr/bin/cpp
export BLIGHT_WRAPPED_LD=/usr/bin/ld
export BLIGHT_WRAPPED_AS=/usr/bin/as
export BLIGHT_WRAPPED_AR=/usr/bin/ar
export BLIGHT_WRAPPED_STRIP=/usr/bin/strip
export BLIGHT_WRAPPED_INSTALL=/usr/bin/install
export CC=blight-cc
export CXX=blight-c++
export CPP=blight-cpp
export LD=blight-ld
export AS=blight-as
export AR=blight-ar
export STRIP=blight-strip
export INSTALL=blight-install
--swizzle-path further modifies the environment by rewriting PATH:
$ blight-env --guess-wrapped-swizzle-path
export BLIGHT_WRAPPED_CC=/usr/bin/cc
export BLIGHT_WRAPPED_CXX=/usr/bin/c++
export BLIGHT_WRAPPED_CPP=/usr/bin/cpp
export BLIGHT_WRAPPED_LD=/usr/bin/ld
export BLIGHT_WRAPPED_AS=/usr/bin/as
export BLIGHT_WRAPPED_AR=/usr/bin/ar
export BLIGHT_WRAPPED_STRIP=/usr/bin/strip
export BLIGHT_WRAPPED_INSTALL=/usr/bin/install
export PATH='/var/folders/zj/hy934vnj5xs68zv6w4b_f6s40000gn/T/tmpxh5ryu22@blight-swizzle@:/bin:/usr/bin:/usr/local/bin'
export CC=blight-cc
export CXX=blight-c++
export CPP=blight-cpp
export LD=blight-ld
export AS=blight-as
export AR=blight-ar
export STRIP=blight-strip
export INSTALL=blight-install
The swizzled addition can be identified by its @blight-swizzle@ directory name.
Taming an uncooperative build with shims and stubs
Sometimes build systems need more coaxing than just --guess-wrapped and
--swizzle-path. Common examples include:
- Hard-coding a particular tool or tool version rather than using the symbolic
name (e.g.
clang-7 example.cinstead of$(CC) example.c); - Running lots of "junk" commands that can be suppressed (e.g. lots of
echoinvocations)
You can use shims and stubs to smooth out these cases:
- shims replace a command with a build tool that
blightknows about, e.g.clang-3.8withcc. - stubs replace a command with an invocation of
true, meaning that it does nothing and never fails.
Shims are specified with --shim cmd:tool, while stubs are specified with
--stub cmd. Both require --swizzle-path, since the PATH must be rewritten
to inject additional commands.
For example, to instrument a build system that hardcodes tcc everywhere
and that spews way too much output with echo:
blight-exec --guess-wrapped --swizzle-path --shim tcc:cc --stub echo -- make
Goals
- Wrapping
CC,CXX,CPP,LD,AS,AR,STRIP, andINSTALL. - Providing a visitor-style API for each of the above, pre- and post-execution.
- Providing a nice set of default actions.
- Being as non-invasive as possible.
Anti-goals
- Using
LD_PRELOADto capture everyexecin a build system, a la Bear. - Supporting
cl.exe. - Detailed support for non C/C++ languages.
Contributing
Check out our CONTRIBUTING.md!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blight-0.0.53.tar.gz.
File metadata
- Download URL: blight-0.0.53.tar.gz
- Upload date:
- Size: 36.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/4.0.1 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
151f9373373e73a5a5f4be10cc656250ac6c0a024552840b1e5531075f390c10
|
|
| MD5 |
8e1dd89c5742e46af52410ee129824c3
|
|
| BLAKE2b-256 |
311e2b5cd9503a5d995d5c6a511c5e4608816b7a8f7452f28da1f8eeaf101002
|
File details
Details for the file blight-0.0.53-py3-none-any.whl.
File metadata
- Download URL: blight-0.0.53-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/4.0.1 CPython/3.11.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c1a7cd92b2ab76d14b00e5c395046b84acb8809f25c8f7b77f74cb72a2cabd5
|
|
| MD5 |
3a4559e53a0d093da18386cffd6b704d
|
|
| BLAKE2b-256 |
1ce9bd50da7540ce92bfa191098efb18d20ff20e63273a0781fdc6186b3f0eab
|