news 2026/10/7 2:02:04

Bear 项目开发指南:从工作区架构到编译数据库生成的全链路解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Bear 项目开发指南:从工作区架构到编译数据库生成的全链路解析
  • 开发工具
  • CLI

【免费下载链接】Bear

Generate compile_commands.json for any C or C++ build

项目地址:https://gitcode.com/gh_mirrors/be/Bear
点击查看免费下载

本文基于仓库根目录 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 test
  • cargo 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-preloadLD_PRELOAD/DYLD_INSERT_LIBRARIES共享库(intercept-preload/)
platform-checks构建期平台能力探测(platform-checks/)
bear-codegen编译器旗标表的代码生成器(bear-codegen/)
integration-tests端到端集成测试(integration-tests/)
bear-completionsshell 补全二进制(根 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 YAMLbear/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 的运行时数据流:

  1. Interception(拦截):通过LD_PRELOAD(Linux/macOS 及其他 BSD 系)或 wrapper 可执行文件(其他平台)捕获编译器调用;
  2. Semantic analysis(语义分析):使用 interpreter YAML 定义过滤掉非编译器命令;
  3. Configuration(配置):应用用户配置以决定输出格式;
  4. 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)两部分,理由有二:

  1. 稳定版 Rust 无法处理 C 变参(execl家族);
  2. 在 FreeBSD 上,将所有导出符号放在 C 中可避免通过dlsym(RTLD_NEXT, ...)造成的递归拦截。

各平台机制与符号可见性策略如下:

平台机制符号可见性
Linux、FreeBSD、OpenBSD、NetBSD、DragonFly BSDLD_PRELOADELF version scripts
macOSDYLD_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_preprocessing
4.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 用"三层"概括工作区构建顺序——在链接用户可见的二进制之前,构建分三阶段进行:

  1. bear-codegen生成 interpreter 表:由bear/build.rs调用(详见 bear/CLAUDE.md 与 bear-codegen/CLAUDE.md);
  2. platform-checks探测主机:其build.rs对头文件与符号探测一次,消费者通过platform_checks::emit_cfg()/emit_check_cfg()回放结果;
  3. 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")门控)的职责:

  1. 经platform_checks::emit_cfg()/emit_check_cfg()回放平台探测结果;
  2. cc 编译 src/c/shim.c 为libshim.a,为每个探测到的拦截族符号加-Dhas_symbol_X;
  3. 将符号导出清单(Linux 为exports.map、macOS 为exports.txt)写入OUT_DIR;
  4. 发射 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。

这也是主机要求中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 规定,架构性变更或新功能必须遵守决策协议:

  1. 先检查 requirements/ 是否已有对应需求规格(如output-json-compilation-database.md、output-append.md、interception-preload-mechanism.md等);
  2. 若无则先撰写需求规格(见 requirements/CLAUDE.md);
  3. 写代码前提供 Decision Log:拟采用方案、备选方案、权衡(性能 vs 简洁);
  4. 等待 "GO" 之后再实现;
  5. 编写引用该需求的集成测试。

需求与测试的双向绑定由 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,使本地无法复现的平台失败也携带完整诊断上下文。

九、给开发者的实操清单

将以上机制汇总为一条可直接照做的开发路径:

  1. 改 CLI / 输出→ 先读 bear/CLAUDE.md,改完同步 man 手册(man/CLAUDE.md);
  2. 改编译器定义→ 编辑 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 的六步流程);
  3. 改拦截库→ 先读 intercept-preload/CLAUDE.md,保持 C shim 与 Rust 拆分,改动导出符号时同步INTERCEPT_FAMILY与 shim 本体;
  4. 加需求或改架构→ 走 requirements/ 需求规格 + Decision Log + 引用需求的集成测试;
  5. 提交前→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

项目地址:https://gitcode.com/gh_mirrors/be/Bear
点击查看免费下载

相关推荐

上一篇:终极Dio文件下载指南:实现智能下载队列与优先级管理
下一篇:如何设置Kazumi播放倍速:个性化视频观看体验完全指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 1:58:57

TCP/IP客户端服务端源码实战:三次握手、状态机与跨平台调试

简介&#xff1a;本资源是一套基于C#实现的TCP/IP网络通信完整示例工程&#xff0c;面向初学者及中级网络编程学习者&#xff0c;旨在帮助理解TCP连接建立、数据收发与双端协同机制等核心概念。压缩包含38个文件&#xff0c;主体为11个C#源码文件&#xff08;如Server.cs、Clie…

作者头像 李华
网站建设 2026/10/7 1:53:37

题解:洛谷 P4427 [BJOI2018] 求和

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大家订阅我的专栏:算法…

作者头像 李华
网站建设 2026/10/7 1:53:15

嵌入式驱动开发实战:从寄存器到Linux内核的完整指南

1. 嵌入式驱动开发到底在做什么很多人刚接触嵌入式&#xff0c;听到“驱动开发”四个字就觉得门槛高得离谱&#xff0c;觉得那是内核大神才碰的东西。其实把话说透&#xff0c;驱动开发本质上就是写代码让硬件能干活。你手里那块板子上有屏幕、有按键、有网卡、有传感器&#x…

作者头像 李华