- 开发工具
- CLI
【免费下载链接】Bear
Generate compile_commands.json for any C or C++ build
本文基于仓库根目录 CLAUDE.md 展开,系统梳理 Bear("Build EAR")在开发与构建阶段的强制性检查流程、多 crate 工作区结构、四阶段数据流架构、三层构建流水线,以及为编译器语义分析生成旗标表(flag table)的完整机制。读者将掌握:如何干净地通过
cargo fmt/clippy/test三关检查、INTERCEPT_LIBDIR等跨切割构建环境变量的来龙去脉、Linux/macOS 下拦截库的链接约束(lld为何必须)、以及新增编译器/旗标时从 YAML 定义到集成测试的完整开发闭环。
一、Bear 是什么:为 Clang 工具链生成编译数据库
Bear 的核心使命是为不支持原生导出编译数据库的构建系统生成 JSON compilation database(compile_commands.json)。它通过在构建过程中拦截编译器调用并记录它们,让基于 Clang 的工具链(如 clangd、clang-tidy)能够理解每个翻译单元(translation unit)的编译参数、头文件搜索路径与构建设置。
从仓库 README.md 的使用入口可以看到它的典型用法:
bear -- <your-build-command>--之前是 Bear 自身的选项,之后全部交给真实构建命令。构建结束后,compile_commands.json会写入当前工作目录。若构建系统本身已支持生成编译数据库(如 CMake、Meson、Bazel),官方建议优先使用其内置导出,Bear 面向的是那些无法直接产出的系统。
支持平台包括 Linux、macOS、FreeBSD、OpenBSD、NetBSD、DragonFly BSD 与 Windows。项目以 Rust 2024 edition 编写,版本号由工作区统一管理(Cargo.toml 中version = "4.1.3",license 为 GPL-3.0-or-later)。
二、开发前的强制检查:三关验证不可跳过
仓库根 CLAUDE.md 首先强调了一条强制性的提交前检查(Pre-commit checks),任何提交之前,以下三个命令必须全部通过:
cargo fmt --check cargo clippy --all-targets -- -D warnings cargo testcargo fmt --check:验证整个工作区代码是否严格遵循rustfmt格式化规范;cargo clippy --all-targets -- -D warnings:对全部目标(含测试与示例)运行 clippy,并将任何警告视为错误(-D warnings),保证零警告;cargo test:运行全部单元测试与集成测试。
文档明确写道:"Do not commit unless all three pass. Fix issues before committing."(三项全部通过后才能提交,先修问题再提交。)这条纪律配合后文提到的 ASCII-only 输出规范(文件中禁止 em dash、smart quotes、Unicode 项目符号,一律使用连字符、直引号、三个点、星号/连字符列表),共同构成了本仓库的代码风格底线。
三、工作区结构:六个 crate 各司其职
仓库是一个 Cargo workspace(Cargo.toml 的members列表),包含六个成员 crate。根 CLAUDE.md 给出的职责分工如下:
| Crate | 职责 |
|---|---|
bear | 主驱动程序、CLI、语义分析、输出(bear/ 目录,即本文主线所在的 crate) |
intercept-preload | LD_PRELOAD/DYLD_INSERT_LIBRARIES共享库(intercept-preload/) |
platform-checks | 构建期平台能力探测(platform-checks/) |
bear-codegen | 编译器旗标表的代码生成器(bear-codegen/) |
integration-tests | 端到端集成测试(integration-tests/) |
bear-completions | shell 补全二进制(根 CLAUDE.md 的 Routing 表中提及,见 bear-completions/) |
bearcrate 内部进一步按职责划分目录(bear/CLAUDE.md):
| 目录 | 职责 |
|---|---|
src/bin/ | 入口点:driver.rs(主程序)、wrapper.rs(wrapper 拦截) |
src/modes/ | 运行模式 |
src/intercept/ | 命令拦截编排(environment、reporter、supervise、tcp、wrapper 等) |
src/output/ | 输出生成(JSON 编译数据库、统计信息、过滤/原子写入等) |
src/semantic/ | 语义分析——编译器识别与旗标解析 |
src/config/ | 配置加载、验证与类型定义 |
interpreters/ | 编译器定义 YAML 文件 |
bear的二进制产物由 bear/Cargo.toml 声明为两个:bear-driver(src/bin/driver.rs)与bear-wrapper(src/bin/wrapper.rs)。
3.1 Routing 规则:改代码前先读对应 CLAUDE.md
根 CLAUDE.md 明确规定,修改任何子目录代码之前,必须首先阅读该目录下的CLAUDE.md,其中包含了防止回归的约束:
| 当你将要…… | 先阅读 |
|---|---|
| 修改 CLI 参数或输出格式 | bear/CLAUDE.md |
| 编辑或新增编译器 interpreter YAML | bear/interpreters/CLAUDE.md |
| 编辑 YAML 到 Rust 的代码生成器 | bear-codegen/CLAUDE.md |
| 新增或修改主机能力探测 | platform-checks/CLAUDE.md |
| 触碰 preload 拦截库 | intercept-preload/CLAUDE.md |
| 触碰 shell 补全二进制 | bear-completions/CLAUDE.md |
| 编写或修改集成测试 | integration-tests/CLAUDE.md |
| 编辑或重新生成 man 手册 | man/CLAUDE.md |
| 新增、修改或评审需求 | requirements/CLAUDE.md |
这套"按区域分治 + 局部约束文档"的设计,确保了改动不会越界引发回归。
四、四阶段数据流架构
根 CLAUDE.md 用一条清晰的流水线概括了 Bear 的运行时数据流:
- Interception(拦截):通过
LD_PRELOAD(Linux/macOS 及其他 BSD 系)或 wrapper 可执行文件(其他平台)捕获编译器调用; - Semantic analysis(语义分析):使用 interpreter YAML 定义过滤掉非编译器命令;
- Configuration(配置):应用用户配置以决定输出格式;
- Output(输出):写出
compile_commands.json。
这条链路在源码结构中有着一一对应的体现:src/intercept/(拦截编排)→src/semantic/(编译器检测与旗标解析)→src/config/(配置加载与验证)→src/output/(编译数据库与统计输出)。下面结合各子系统的CLAUDE.md与实现细节逐层展开。
4.1 拦截层:preload 库的 C/Rust 强制拆分
intercept-preload/CLAUDE.md 揭示了拦截库的架构约束:库被强制拆分为 C shim(src/c/shim.c)与 Rust(src/implementation.rs)两部分,理由有二:
- 稳定版 Rust 无法处理 C 变参(
execl家族); - 在 FreeBSD 上,将所有导出符号放在 C 中可避免通过
dlsym(RTLD_NEXT, ...)造成的递归拦截。
各平台机制与符号可见性策略如下:
| 平台 | 机制 | 符号可见性 |
|---|---|---|
| Linux、FreeBSD、OpenBSD、NetBSD、DragonFly BSD | LD_PRELOAD | ELF version scripts |
| macOS | DYLD_INSERT_LIBRARIES | -exported_symbols_list |
代码以cfg(target_os = "macos")vscfg(not(target_os = "macos"))区分,因此所有非 macOS 的 Unix 平台走LD_PRELOAD路径;不支持的平台(如 Windows)构建时仅告警并跳过库的生成。被拦截的函数包括exec家族、posix_spawn、popen、system——仅拦截构建期探测到的主机上可用的函数(由platform-checks提供依据)。拦截到的报告经由 TCP 收集器送往bear侧,改动协议时必须同步更新收集器。
4.2 语义分析层:interpreter YAML 决定一切
语义分析的核心是 bear/interpreters/ 下的编译器定义 YAML。根 CLAUDE.md 概括为"使用 interpreter YAML 定义过滤非编译器命令"。每个文件对应一个编译器或编译器家族,其模式(pattern)语法、result语义值、ignore_when过滤条件、extends继承与environment环境变量映射的完整 schema,记录在 bear/interpreters/README.md。
一个典型的定义骨架如下:
# 可选:继承另一文件的所有旗标(按文件名 stem 引用) extends: gcc # 必填:对应 CompilerType 变体(gcc, clang, flang, cuda, ...) type: gcc # 该编译器被识别的可执行文件名 recognize: - executables: ["gcc", "g++", "gfortran"] cross_compilation: true # 匹配交叉编译前缀,如 arm-linux-gnu-gcc versioned: true # 匹配版本后缀,如 gcc-11, gcc11 - executables: ["cc", "c++"] cross_compilation: true versioned: false # 可选:是否将 '/' 开头的参数视为旗标(默认 false) slash_prefix: false # 可选:识别成功后仍需忽略的调用条件 ignore_when: executables: ["cc1", "cc1plus", "f951"] # 内部可执行文件名 flags: ["-cc1"] # 内部旗标 flags: - match: {pattern: "-o{ }*"} result: output - match: {pattern: "-c"} result: stops_at_compiling - match: {pattern: "-I{ }*"} result: configures_preprocessing4.2.1 模式语法:如何描述"旗标如何消费参数"
pattern字符串同时编码旗标名与参数消费方式,bear/interpreters/README.md 给出的对照表是理解一切旗标表的基础:
| 语法 | 示例 | 含义 |
|---|---|---|
-flag | -c | 精确匹配,无附加参数 |
-flag+ count | -xcount: 1 | 精确匹配,后跟 N 个独立参数 |
-flag* | -W* | 前缀匹配(任何以-W开头) |
-flag*+ count | -Xarch*count: 1 | 前缀匹配,后跟 N 个独立参数 |
-flag{ }* | -D{ }* | 精确匹配,值可粘连或作为独立参数 |
-flag=* | -specs=* | 精确匹配,值跟在=后 |
-flag{=}* | --std{=}* | 精确匹配,值在=后或作为独立参数 |
-flag:* | /std:* | 精确匹配,值跟在:后 |
-flag{:}* | /Fe{:}* | 精确匹配,值在:后或作为独立参数 |
{}对表示分隔符可选:{ }表示空格可选(-Dfoo粘连或-D foo分离均可)、{=}表示=可选(--std=c99或--std c99)、{:}表示:可选(/std:c++20或/std c++20)。代码生成侧由 bear-codegen/src/codegen.rs 的pattern_to_rust负责将这些模式编译为 Rust 匹配逻辑。
4.2.2 result 语义值:旗标对编译过程的影响
result字段描述旗标的语义影响,完整词汇表如下:
| 值 | 含义 |
|---|---|
output | 输出文件指定 |
configures_preprocessing | 影响预处理阶段 |
configures_compiling | 影响编译阶段 |
configures_assembling | 影响汇编阶段 |
configures_linking | 影响链接阶段 |
stops_at_preprocessing | 预处理后停止编译 |
stops_at_compiling | 编译后停止编译 |
stops_at_assembling | 汇编后停止编译 |
info_and_exit | 打印信息后退出(如--version) |
driver_option | 驱动程序/工具链行为旗标 |
pass_through | 停止解析,其余参数交给链接器 |
none | 无特定语义效果 |
这些语义值决定了 Bear 如何把编译器调用归类为"配置预处理/编译/汇编/链接",从而在生成的编译数据库条目中恰当地呈现参数。
4.2.3 ignore_when:剔除内部调用
ignore_when定义了"被识别为编译器但属于内部调用"的过滤条件:
executables:可执行文件名的匹配列表(如 GCC 的cc1、collect2等内部可执行文件);flags:参数串匹配列表(如 Clang 的-cc1前端调用)。
两个字段均可选、默认为空。使用extends时,ignore 过滤器仅在扩展文件未定义该字段自身列表时继承(即按字段整体覆盖,而非按条目合并)。值得注意的细节:ignore_when.executables中列出的可执行文件名会被自动添加为recognize条目(cross_compilation: false, versioned: false),确保识别器先将它们路由到正确的编译器类型,再由 interpreter 将其忽略——无需手工重复列入recognize。
4.2.4 继承与排序:extends 链的确定性合并
extends: gcc的文件会继承 GCC 的全部旗标与(未被覆盖的)ignore 过滤器。构建脚本将自身旗标拼接在基类旗标之前,随后按旗标名长度降序排序(最长优先),保证更具体的旗标先于更短的前缀匹配;排序是稳定的,因此同长度的旗标中自身旗标优先于基类旗标。这一逻辑实现在 bear-codegen/src/lib.rs 的ResolvedTable::new中:flags.sort_by_key(|b| std::cmp::Reverse(b.match_.name_len()))。环境变量同样沿extends链传递继承,同名变量时自身条目覆盖继承条目(如armclang.yaml→clang.yaml→gcc.yaml的链条);不读取 GCC 环境变量的编译器(如 NVIDIA HPC SDK)则不得extends: gcc,其环境表为空。
4.2.5 environment 段:环境变量映射为命令行参数
编译器还会从环境变量读取配置,environment段声明这些变量及其到命令行参数的映射:
environment: - variable: CPATH effect: configures_preprocessing mapping: flag: "-I" separator: path - variable: CL effect: configures_compiling mapping: expand: prepend separator: space映射类型有两种:Flag(flag+separator,按分隔符切分值并为每个元素发射<flag> <entry>)与Expand(expand+separator: space,按 shell 词法切分值并作为原始参数插入)。分隔符支持path(Unix 用:、Windows 用;)、固定";"、以及用于 Expand 的space。展开位置有prepend(插入命令行参数之前,如 MSVC 的CL)与append(插入之后,如 MSVC 的_CL_)。若变量只是被编译器读取而 Bear 无法解析(如配置文件路径),可声明为effect: none的记录性条目,代码生成时跳过但保留给后续贡献者参考。变量名必须匹配[A-Za-z_][A-Za-z0-9_]*。
4.3 配置层:加载、类型与验证
src/config/承担配置的加载(loader.rs)、类型(types.rs)与验证(validation.rs)。bear/CLAUDE.md 特别提醒:对 types.rs 的改动会影响 YAML 配置解析,必须同步更新 validation.rs。用户配置在此阶段被应用到输出格式上(如路径格式、重复条目过滤、追加/原子写入等行为,详见 requirements/ 下的需求规格,如output-path-format.md、output-append.md、output-atomic-write.md)。
4.4 输出层:JSON 编译数据库与统计
输出层位于 src/output/,包含 JSON 序列化(json.rs、clang 兼容的 converter 与 path_format)、写入器(支持过滤/去重、追加、原子写、校验,见 src/output/writers/)以及统计信息(statistics.rs)。所有输出格式相关改动必须先检查 integration-tests/ 中的既有测试以防回归——这是 bear/CLAUDE.md 明确的纪律。
五、三层构建流水线:先代码生成,再平台探测,最后链接拦截库
根 CLAUDE.md 用"三层"概括工作区构建顺序——在链接用户可见的二进制之前,构建分三阶段进行:
bear-codegen生成 interpreter 表:由bear/build.rs调用(详见 bear/CLAUDE.md 与 bear-codegen/CLAUDE.md);platform-checks探测主机:其build.rs对头文件与符号探测一次,消费者通过platform_checks::emit_cfg()/emit_check_cfg()回放结果;intercept-preload编译 C shim:其build.rs用 cc 编译 src/c/shim.c 并输出 cdylib 链接指令。
5.1 bear/build.rs:环境变量与旗标表代码生成
bear/build.rs 承担两件事。其一,验证INTERCEPT_LIBDIR(相对路径,默认lib)并发射cargo:rustc-env=变量:DRIVER_NAME、WRAPPER_NAME、PRELOAD_NAME、INTERCEPT_LIBDIR;这些值由 src/installation.rs 通过env!()消费,用于解析运行时安装布局。DRIVER_NAME/WRAPPER_NAME在 Windows 下带.exe后缀,PRELOAD_NAME在 macOS 下为libexec.dylib、其余平台为libexec.so。
其二,调用bear_codegen::generate(flags_dir, out_dir)读取 interpreters/*.yaml 并把静态 Rust 数组写入OUT_DIR。生成的代码经include!()纳入 interpreter 与 recognition 模块(bear/CLAUDE.md 指明)。因此编辑 YAML 后必须重新运行cargo build以重新生成,再运行cargo test验证——bear/interpreters/CLAUDE.md 将"编辑 YAML 后忘记cargo build(残留过期生成代码)"列为最常见的错误之一。
5.1.1 INTERCEPT_LIBDIR 的验证规则
validate_intercept_libdir接受两类合法值:非空相对路径(如lib、lib64、lib/x86_64-linux-gnu),以及字面量"$LIB"(将目录选择推迟到运行时/平台约定,常见解释为lib或lib64视系统而定)。空值或绝对路径直接 panic。
5.1.2 安装布局:相对路径定位兄弟组件
src/installation.rs 记录的安装布局如下:
<prefix>/ ├── bin/ │ └── bear ← shell 脚本,按绝对路径调用 bear-driver └── <out_of_path>/ ├── bin/ │ ├── bear-driver ← current_executable │ └── bear-wrapper ← bear-driver 的兄弟 └── <INTERCEPT_LIBDIR>/ └── libexec.so ← 从 bin/ 上一层再进入 INTERCEPT_LIBDIR/bear-driver仅用相对路径定位兄弟组件:bear-wrapper在同一bin/目录;libexec.so相对bin/经../<INTERCEPT_LIBDIR>/libexec.so到达。INTERCEPT_LIBDIR构建期设定(默认lib);在基于 glibc 的 Linux 上,打包者可将其设为$LIB,由动态链接器在运行时展开。
5.2 bear-codegen:YAML schema 到 Rust 表的生成器
bear-codegen/CLAUDE.md 说明这是一个常规库而非build.rs本身,由bear/build.rs以bear_codegen::generate(flags_dir, out_dir)调用:读取 bear/interpreters/*.yaml 并写出 Rust 源码到消费者的OUT_DIR,bearcrate 再经include!()纳入 src/semantic/interpreters/。
生成的模块名集合与输入形态对应(当前清单见src/lib.rs::generate);YAML schema 校验位于 yaml_types.rs,tests/snapshots/ 下的快照测试锁定生成输出,防止 schema 意外漂移——这正是根 CLAUDE.md 中"快照测试验证排序与不变式"的依据。继承解析(resolve_flags、resolve_ignore_when、resolve_slash_prefix、resolve_environment)集中在 resolve.rs。
5.3 platform-checks:一次探测,处处回放
platform-checks/CLAUDE.md 描述该 crate 的工作方式:build.rs在OUT_DIR内用cc::Build::try_compile编译微型 C 探针,结果写入OUT_DIR/detected.rs,库以include!()引入。消费者(intercept-preload、integration-tests)把platform-checks声明为[build-dependencies]——Cargo 保证它的build.rs在任一消费者之前运行、且每次cargo build恰好一次。
公开 API 包括:
| 条目 | 用途 |
|---|---|
DETECTED_HEADERS: &[&str] | 本主机可编译的头文件(如"dlfcn_h") |
DETECTED_SYMBOLS: &[&str] | 本主机可链接的符号(如"execve") |
KNOWN_HEADERS: &[&str] | 所有被探测的头文件(含未找到者) |
KNOWN_SYMBOLS: &[&str] | 所有被探测的符号(含未找到者) |
emit_cfg() | 为所有探测成功项发射cargo:rustc-cfg=has_*_X |
emit_check_cfg() | 为所有探测项发射cargo:rustc-check-cfg=cfg(has_*_X) |
新增探针只需向build.rs的HEADER_PROBES/SYMBOL_PROBES加条目,再从消费者源码引用cfg(has_*_X);只要消费者build.rs调用了emit_check_cfg(),lint 白名单即自动覆盖。该 crate 只探测主机能力、不决定消费者行为:preload C shim 实际导出的符号清单以 intercept-preload/src/c/shim.c 为准(INTERCEPT_FAMILY与之保持同步)。
5.4 intercept-preload 构建:链接指令与 lld 的硬性要求
intercept-preload/CLAUDE.md 列出build.rs(以cfg(target_family = "unix")门控)的职责:
- 经
platform_checks::emit_cfg()/emit_check_cfg()回放平台探测结果; - cc 编译 src/c/shim.c 为
libshim.a,为每个探测到的拦截族符号加-Dhas_symbol_X; - 将符号导出清单(Linux 为
exports.map、macOS 为exports.txt)写入OUT_DIR; - 发射 cdylib 链接参数:
- Linux:
-Wl,--whole-archive、-Wl,--version-script=...、-Wl,-rpath,$ORIGIN、-fuse-ld=lld; - macOS:
-Wl,-force_load,...、-Wl,-exported_symbols_list,...、-Wl,-rpath,@loader_path。
- Linux:
这也是主机要求中lld的由来:ELF version script 使用了多个版本标签,GNU ld 不支持,Linux 上缺 lld 则链接失败;macOS 使用系统链接器(见根 CLAUDE.md 的 Host requirements)。
六、主机要求与可选依赖
根 CLAUDE.md 列出构建 Bear 的主机要求:
cc工具链(gcc 或 clang);lld链接器(仅 Linux):如前述,ELF version script 多版本标签需要 lld;ccache(可选):当其存在于 PATH 时,集成测试会额外演练一条 ccache-masquerade 感知的测试路径(integration-tests/build.rs会搜索已知路径寻找 ccache masquerade 目录,命中时发射cargo:rustc-cfg=host_has_ccache_masquerade)。
构建命令(debug 与 release 两种):
cargo build --verbose # debug cargo build --release # release(LTO、strip)根 CLAUDE.md 特别提示:集成测试要求先存在 debug 构建再运行cargo test(integration-tests/CLAUDE.md 同样强调"先cargo build")。release profile 在 Cargo.toml 中配置为strip = true、lto = true、opt-level = 3、codegen-units = 1。
七、变更决策协议:需求先行
根 CLAUDE.md 规定,架构性变更或新功能必须遵守决策协议:
- 先检查 requirements/ 是否已有对应需求规格(如
output-json-compilation-database.md、output-append.md、interception-preload-mechanism.md等); - 若无则先撰写需求规格(见 requirements/CLAUDE.md);
- 写代码前提供 Decision Log:拟采用方案、备选方案、权衡(性能 vs 简洁);
- 等待 "GO" 之后再实现;
- 编写引用该需求的集成测试。
需求与测试的双向绑定由 integration-tests/CLAUDE.md 落实:测试以// Requirements: <id>标签引用需求 ID(以 requirements/ 中去除.md后缀的文件名为准),这是测试-需求关联的唯一事实来源;requirements/check-coverage.sh 会校验每个implemented需求至少有一条打了标签的测试。
八、集成测试:回归防护的第一道防线
integration-tests/CLAUDE.md 明确:集成测试是 Bear 的主要回归防护机制——每个已实现需求应至少有一条集成测试,修复 bug 时须补一条复现原失败的测试,平台特定行为需要#[cfg(...)]平台特定测试。
典型测试模式(使用bear_test!宏):
bear_test!(test_name, |env| { env.create_source_files(&[("test.c", "int main() { return 0; }")])?; env.create_build_script("gcc -c test.c")?; let output = env.run_bear(&["--output", "db.json", "--", "sh", "build.sh"])?; let db = env.load_compilation_database("db.json")?; db.assert_count(1)?; db.assert_contains_file("test.c")?; Ok(()) });带需求引用的形式:
// Requirements: output-json-compilation-database, output-append #[test] fn append_works_as_expected() -> Result<()> { ... }测试基础设施位于 tests/fixtures/(TestEnvironment、BearOutput、CompilationDatabase、常量与外部依赖),用例按功能域分组在 tests/cases/(compilation_output、config、exit_codes、hardened_intercept、intercept、intercept_posix、semantic 等)。integration-tests/build.rs除转发INTERCEPT_LIBDIR与产物路径外,还探测主机上固定的可执行文件清单(shell、make、compiler_c、compiler_cxx、compiler_fortran、compiler_cuda等分组),发射cargo:rustc-cfg=has_executable_<name>供测试以#[cfg(has_executable_make)]条件编译。
8.1 调试技巧
测试 panic 时,fixture 会把最后一次捕获的 bear stdout/stderr 转储到测试二进制 stderr。run_bear继承RUST_LOG(未设置时默认info)。推荐调试组合:
cargo test # 失败时输出 info 级日志转储 RUST_LOG=debug cargo test # 全量逐事件追踪(本地排查推荐) BEAR_TEST_PRESERVE_FAILURES=1 cargo test # 同时保留临时目录于 /tmp/bear-test-<name>-<pid> RUST_LOG=debug BEAR_TEST_PRESERVE_FAILURES=1 cargo test # 两者兼得CI 设置RUST_LOG=debug,使本地无法复现的平台失败也携带完整诊断上下文。
九、给开发者的实操清单
将以上机制汇总为一条可直接照做的开发路径:
- 改 CLI / 输出→ 先读 bear/CLAUDE.md,改完同步 man 手册(man/CLAUDE.md);
- 改编译器定义→ 编辑 bear/interpreters/*.yaml,遵循 bear/interpreters/README.md 的模式语法与 result 词汇表,然后
cargo build && cargo test;新增编译器还需在 bear/build.rs 加TableConfig、在config.rs加CompilerType变体并映射到compiler_recognition.rs::parse_compiler_type、在CompilerInterpreter::new_with_config注册FlagBasedInterpreter(bear/interpreters/CLAUDE.md 的六步流程); - 改拦截库→ 先读 intercept-preload/CLAUDE.md,保持 C shim 与 Rust 拆分,改动导出符号时同步
INTERCEPT_FAMILY与 shim 本体; - 加需求或改架构→ 走 requirements/ 需求规格 + Decision Log + 引用需求的集成测试;
- 提交前→
cargo fmt --check、cargo clippy --all-targets -- -D warnings、cargo test三关全绿,且确保先有 debug 构建。
这套约束体系的最终目的,是让 Bear 在"拦截 → 语义分析 → 配置 → 输出"这条核心数据流上保持稳定、可回归、可扩展——无论是为 Clang 工具链产出准确的compile_commands.json,还是向新编译器、新平台演进,都有一条清晰可控的开发路径可循。
- 开发工具
- CLI
【免费下载链接】Bear
Generate compile_commands.json for any C or C++ build
相关推荐
Bear 主 crate(bear)源码架构指南:CLI 驱动、语义分析与编译数据库生成
Bear 主 crate(bear)源码架构指南:CLI 驱动、语义分析与编译数据库生成 Bear 是一个为 Clang 工具链生成 JSON 编译数据库( c
开发工具CLIBear编译数据库生成工具完整使用指南
Bear编译数据库生成工具完整使用指南 编译数据库是现代C++开发中不可或缺的重要工具,而Bear正是专门为clang工具链设计的高效编译数据库生成工具。无论你
开发工具CLIBear完整指南:掌握编译数据库生成工具
Bear是一款专为clang工具链设计的编译数据库生成工具,能够自动捕获构建过程中的编译命令并生成标准化的JSON格式文件。对于C++开发者而言,Bear编译数
开发工具CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考