跳转到主要内容

通用的编译工具包装器

项目描述

blight

CI PyPI version Downloads

blight 是一个用于包装和监视构建工具和构建系统的框架。它包含

  1. 一系列针对各种常见构建工具的高保真模型(例如,C和C++编译器、标准链接器、预处理器等);
  2. 各种可以在每个构建工具或特定工具类上运行的“操作”(例如,“当构建系统调用 $CC 时,添加此标志”);
  3. 用于监视构建的命令行包装器(blight-envblight-exec)。

安装

blight 可在PyPI上使用,并通过 pip 安装

python -m pip install blight

需要Python 3.7或更高版本。

使用方法

blight 有两个主要入口点

  • blight-exec:在 blight 监视环境中直接执行命令
  • blight-env:将 sh 兼容的环境定义写入 stdout,shell或其他工具可以消费它以进入 blight 监视环境

在大多数情况下,你可能想使用 blight-exec。可以将 blight-env 理解为“高级”或“管道”接口。

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.

快速入门

开始使用 blight 的最简单方法是使用 blight-exec--guess-wrapped--swizzle-path 标志。这些标志告诉 blight 使用一些常识性的默认设置配置环境。

  • --guess-wrapped:猜测从当前 PATH 和其他运行时环境调用适当的基本工具;
  • --swizzle-path:重新编写 PATH,将一些常见的构建工具模拟器放在最前面,例如将 cc 重定向到 blight-cc

例如,以下命令将在 blight 的工具中运行 cc -v,并使用 演示 动作

blight-exec --action Demo --swizzle-path --guess-wrapped -- cc -v

应该产生类似以下内容

[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

我们还可以通过在 blight 下运行 which cc 来看到 --swizzle-path 的影响,并观察到它指向一个临时模拟器,而不是正常的 cc 位置

$ blight-exec --swizzle-path --guess-wrapped -- which cc
/var/folders/zj/hy934vnj5xs68zv6w4b_f6s40000gn/T/tmp5uahp6tg@blight-swizzle@/cc

$ which cc
/usr/bin/cc

Demo 动作所做的只是在每个工具运行前后打印一条消息,让你能够诊断工具是否被正确地进行了工具化。有关使用和配置更多有趣动作的信息,请参阅下面的 动作文档

食谱

针对基于 make 的构建运行 blight

大多数基于 make 的构建使用 $(CC)$(CXX) 等,这意味着它们应该能够与 blight-exec 无缝工作。

blight-exec --guess-wrapped -- make

在某些情况下,编写不佳的构建可能将 ccclanggcc 等硬编码,而不是使用它们的符号等价物。对于这些情况,你可以使用 --swizzle-path 来插入模拟器,将那些硬编码的工具调用重定向回 blight 的包装器。

blight-exec --guess-wrapped --swizzle-path -- make

有关处理编写不佳的构建系统的更高级技术,请参阅 使用模拟器和存根驯服不合作的构建

启用动作

动作是 blight 真正发光的地方:它们允许你在每次构建工具调用前后运行任意 Python 代码。

blight 内置了动作,这些动作在此处进行了文档说明。有关每个动作的 Python 模块的文档,请参阅该动作。

动作可以通过两种不同的方式启用

  • 使用 --action 标志,可以多次传递。例如,--action SkipStrip --action Record 启用了 SkipStripRecord 动作。

  • 使用 BLIGHT_ACTIONS 环境变量,它可以包含多个动作,这些动作由冒号分隔。例如,BLIGHT_ACTIONS=SkipStrip:Record--action SkipStrip --action Record 等效。

动作按指定顺序运行,重复项将被删除,这意味着 BLIGHT_ACTIONS=Foo:Bar:FooBLIGHT_ACTIONS=Foo:Bar 等效,但 等效于 BLIGHT_ACTIONS=Bar:Foo。如果动作有副作用,这是很重要的(例如,修改工具的标志)。

动作配置

一些动作接受或需要额外的配置,该配置通过 BLIGHT_ACTION_{ACTION} 环境变量传递,格式为 key=value,其中 {ACTION} 是动作的名称的大写。

例如,要配置 Record 的输出文件

BLIGHT_ACTION_RECORD="output=/tmp/output.jsonl"

动作输出

blight 中的动作有两种获取输出的方式

  • 许多动作支持一个 output 配置值,它应该是一个要写入的文件名。这允许每个动作写入自己的输出文件。
  • blight 支持一种“日志记录”模式,其中所有动作输出都写入一个文件,键为动作名称。

“日志记录”模式通常优于单独的输出,可以使用环境中的 BLIGHT_JOURNAL_PATH=/path/to/output.jsonlblight-exec --journal-path /path/to/output.jsonl 启用。

使用 blight-env 配置环境

blight-env 的行为与 blight-exec 完全相同,区别在于它在实际执行任何操作之前会停止。您可以使用它来为多个构建系统运行设置环境。

默认情况下,blight-env 将仅导出适当的环境变量,以替换 CC 等,用它们的 blight 包装器。

$ 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 通过为每个包装器添加最佳猜测的底层工具来增强此功能。

$ 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 还会尊重环境中的 CC 等。

$ 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 通过重写 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

通过其 @blight-swizzle@ 目录名称可以识别出混合添加的内容。

使用模拟和存根驯服不合作的构建

有时构建系统需要比 --guess-wrapped--swizzle-path 更多的协调。常见的例子包括

  • 直接编写特定工具或工具版本(而不是使用符号名称),例如使用 clang-7 example.c 而不是 $(CC) example.c
  • 运行大量可以抑制的“垃圾”命令(例如,大量的 echo 调用)

您可以使用 shimsstubs 来平滑这些情况

  • shimsblight 知道的构建工具替换命令,例如用 cc 替换 clang-3.8
  • stubs 用对 true 的调用替换命令,这意味着它什么都不做,永远不会失败。

使用 --shim cmd:tool 指定 shims,使用 --stub cmd 指定 stubs。两者都需要 --swizzle-path,因为必须重写 PATH 以注入额外的命令。

例如,要检测一个在所有地方都硬编码 tcc 且使用 echo 输出大量输出的构建系统

blight-exec --guess-wrapped --swizzle-path --shim tcc:cc --stub echo -- make

目标

  • 包装 CCCXXCPPLDASARSTRIPINSTALL
  • 为上述操作提供预执行和后执行的访问者式 API。
  • 提供一组默认操作。
  • 尽可能不侵入。

非目标

  • 使用 LD_PRELOAD 捕获构建系统中的每个 exec,类似于 Bear
  • 支持 cl.exe
  • 对非 C/C++ 语言提供详细支持。

贡献

查看我们的 CONTRIBUTING.md

由以下支持