开发工具CLI【免费下载链接】BearGenerate compile_commands.json for any C or C build项目地址https://gitcode.com/gh_mirrors/be/Bear点击查看免费下载本文基于仓库根目录 CLAUDE.md 展开系统梳理 BearBuild EAR在开发与构建阶段的强制性检查流程、多 crate 工作区结构、四阶段数据流架构、三层构建流水线以及为编译器语义分析生成旗标表flag table的完整机制。读者将掌握如何干净地通过cargo fmt/clippy/test三关检查、INTERCEPT_LIBDIR等跨切割构建环境变量的来龙去脉、Linux/macOS 下拦截库的链接约束lld为何必须、以及新增编译器/旗标时从 YAML 定义到集成测试的完整开发闭环。一、Bear 是什么为 Clang 工具链生成编译数据库Bear 的核心使命是为不支持原生导出编译数据库的构建系统生成 JSON compilation databasecompile_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.3license 为 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 workspaceCargo.toml 的members列表包含六个成员 crate。根 CLAUDE.md 给出的职责分工如下Crate职责bear主驱动程序、CLI、语义分析、输出bear/ 目录即本文主线所在的 crateintercept-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.rswrapper 拦截src/modes/运行模式src/intercept/命令拦截编排environment、reporter、supervise、tcp、wrapper 等src/output/输出生成JSON 编译数据库、统计信息、过滤/原子写入等src/semantic/语义分析——编译器识别与旗标解析src/config/配置加载、验证与类型定义interpreters/编译器定义 YAML 文件bear的二进制产物由 bear/Cargo.toml 声明为两个bear-driversrc/bin/driver.rs与bear-wrappersrc/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 的运行时数据流Interception拦截通过LD_PRELOADLinux/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 shimsrc/c/shim.c与 Rustsrc/implementation.rs两部分理由有二稳定版 Rust 无法处理 C 变参execl家族在 FreeBSD 上将所有导出符号放在 C 中可避免通过dlsym(RTLD_NEXT, ...)造成的递归拦截。各平台机制与符号可见性策略如下平台机制符号可见性Linux、FreeBSD、OpenBSD、NetBSD、DragonFly BSDLD_PRELOADELF version scriptsmacOSDYLD_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分离均可、{}表示可选--stdc99或--std c99、{:}表示:可选/std:c20或/std c20。代码生成侧由 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打印信息后退出如--versiondriver_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映射类型有两种Flagflagseparator按分隔符切分值并为每个元素发射flag entry与Expandexpandseparator: space按 shell 词法切分值并作为原始参数插入。分隔符支持pathUnix 用:、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.mdplatform-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-codegenYAML schema 到 Rust 表的生成器bear-codegen/CLAUDE.md 说明这是一个常规库而非build.rs本身由bear/build.rs以bear_codegen::generate(flags_dir, out_dir)调用读取 bear/interpreters/*.yaml 并写出 Rust 源码到消费者的OUT_DIRbearcrate 再经include!()纳入 src/semantic/interpreters/。生成的模块名集合与输入形态对应当前清单见src/lib.rs::generateYAML schema 校验位于 yaml_types.rstests/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_hDETECTED_SYMBOLS: [str]本主机可链接的符号如execveKNOWN_HEADERS: [str]所有被探测的头文件含未找到者KNOWN_SYMBOLS: [str]所有被探测的符号含未找到者emit_cfg()为所有探测成功项发射cargo:rustc-cfghas_*_Xemit_check_cfg()为所有探测项发射cargo:rustc-check-cfgcfg(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-ldlldmacOS-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 或 clanglld链接器仅 Linux如前述ELF version script 多版本标签需要 lldccache可选当其存在于 PATH 时集成测试会额外演练一条 ccache-masquerade 感知的测试路径integration-tests/build.rs会搜索已知路径寻找 ccache masquerade 目录命中时发射cargo:rustc-cfghost_has_ccache_masquerade。构建命令debug 与 release 两种cargo build --verbose # debug cargo build --release # releaseLTO、strip根 CLAUDE.md 特别提示集成测试要求先存在 debug 构建再运行cargo testintegration-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-cfghas_executable_name供测试以#[cfg(has_executable_make)]条件编译。8.1 调试技巧测试 panic 时fixture 会把最后一次捕获的 bear stdout/stderr 转储到测试二进制 stderr。run_bear继承RUST_LOG未设置时默认info。推荐调试组合cargo test # 失败时输出 info 级日志转储 RUST_LOGdebug cargo test # 全量逐事件追踪本地排查推荐 BEAR_TEST_PRESERVE_FAILURES1 cargo test # 同时保留临时目录于 /tmp/bear-test-name-pid RUST_LOGdebug BEAR_TEST_PRESERVE_FAILURES1 cargo test # 两者兼得CI 设置RUST_LOGdebug使本地无法复现的平台失败也携带完整诊断上下文。九、给开发者的实操清单将以上机制汇总为一条可直接照做的开发路径改 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注册FlagBasedInterpreterbear/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【免费下载链接】BearGenerate compile_commands.json for any C or C build项目地址https://gitcode.com/gh_mirrors/be/Bear点击查看免费下载相关推荐Bear 主 cratebear源码架构指南CLI 驱动、语义分析与编译数据库生成Bear 主 cratebear源码架构指南CLI 驱动、语义分析与编译数据库生成 Bear 是一个为 Clang 工具链生成 JSON 编译数据库 c开发工具CLIBear编译数据库生成工具完整使用指南Bear编译数据库生成工具完整使用指南 编译数据库是现代C开发中不可或缺的重要工具而Bear正是专门为clang工具链设计的高效编译数据库生成工具。无论你开发工具CLIBear完整指南掌握编译数据库生成工具Bear是一款专为clang工具链设计的编译数据库生成工具能够自动捕获构建过程中的编译命令并生成标准化的JSON格式文件。对于C开发者而言Bear编译数开发工具CLI上一篇终极Dio文件下载指南实现智能下载队列与优先级管理下一篇如何设置Kazumi播放倍速个性化视频观看体验完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考