cc_library、cc_binary与filegroup的区别及适用场景咨询
Bazel中cc_library、cc_binary与filegroup的区别及适用场景
一、各目标核心特性
1. cc_library
- 本质:编译C/C++源码(
.cpp/.cc/.h等)生成**静态库(.a)或动态库(.so/.dll)**的构建目标。 - 依赖处理:自动解析并链接依赖的其他
cc_library,支持配置头文件路径、编译选项(copts)、链接选项(linkopts)等。 - 可复用性:作为其他
cc_library或cc_binary的deps依赖项,实现代码模块化复用。 - 产物:编译后的库文件,属于中间构建产物,仅用于链接到其他目标中。
2. cc_binary
- 本质:生成可执行二进制文件的构建目标,是最终可运行的产物。
- 依赖处理:会链接所有通过
deps指定的cc_library,以及自身srcs中的源码,生成独立可执行文件(或依赖动态库的可执行文件)。 - 可复用性:不能作为任何其他构建目标的依赖,因为它是最终可执行程序,而非供链接的库。
- 产物:直接可运行的二进制文件,比如Linux下的ELF、Windows下的EXE。
3. filegroup
- 本质:逻辑文件集合,不执行编译或任何构建动作,仅将一组文件(源码、资源、配置等)打包成一个可引用的目标。
- 依赖处理:本身无编译依赖,仅作为文件的逻辑分组存在。
- 可复用性:可以被其他目标的
srcs、hdrs、data等字段引用,但不能作为deps依赖项(deps要求的是编译产出的库目标,而filegroup只是原始文件集合)。 - 产物:无构建产物,编译时会直接展开为对应的文件列表。
二、核心差异对比
| 对比维度 | cc_library | cc_binary | filegroup |
|---|---|---|---|
| 核心作用 | 生成可链接的库文件 | 生成可执行二进制文件 | 分组管理文件集合 |
| 是否产生构建产物 | 是(.a/.so/.dll等) | 是(可执行文件) | 无 |
能否作为deps依赖 | 是(可被库/二进制依赖) | 否(不可作为任何目标依赖) | 否(仅能被srcs/hdrs等引用) |
| 构建逻辑 | 编译源码+链接依赖库 | 编译源码+链接所有依赖库 | 无编译逻辑,仅文件分组 |
| 复用方式 | 编译后库文件复用 | 无复用(最终产物) | 文件列表复用 |
三、各自独有适用场景
cc_library独有场景
- 封装可复用模块:比如工具函数库、算法库、业务逻辑组件,供多个
cc_binary或其他cc_library共用。 - 拆分大型项目:将项目拆分为多个独立库目标,降低编译耦合,实现增量编译(修改单个库仅重新编译该库及依赖它的目标)。
- 对外提供SDK:编译为静态或动态库,作为SDK分发给其他团队或项目使用。
cc_binary独有场景
- 生成最终可执行程序:比如命令行工具、服务端程序、客户端应用等,是用户最终运行的产物。
- 运行测试用例:结合Bazel测试框架,生成测试可执行文件,执行单元测试或集成测试。
filegroup独有场景
- 统一管理重复引用的文件:比如多个
cc_library需要用到同一批头文件,用filegroup定义后,只需引用该目标即可,无需重复编写文件路径。 - 分类管理资源文件:比如项目中的配置文件、静态资源(如模板、配置),用
filegroup分组后,方便在多个目标的data字段中引用。 - 简化复杂文件列表:当某个目标需要引用数十个零散文件时,用
filegroup打包,让BUILD文件更简洁易维护。
四、cc_library与filegroup的关键区别
本质差异:
cc_library是编译目标,会对源码进行编译、链接,产出可复用的库文件;filegroup是文件分组工具,仅对已有文件做逻辑聚合,无编译动作,无产出物。
依赖方式差异:
cc_library可以作为其他目标的deps依赖,其他目标会链接它的编译产物;filegroup不能作为deps依赖,只能被srcs、hdrs、data等字段引用,本质是将文件列表注入到目标中。
适用场景差异:
cc_library用于封装可复用的编译后代码;filegroup用于简化文件列表的引用和管理,不涉及代码编译。
内容的提问来源于stack exchange,提问作者a learner
相关产品推荐
相关产品推荐

