Bazel构建生成.pic.o/.pic.d文件的作用及链接逻辑等相关疑问
使用Bazel构建C++程序的常见疑问解答
背景说明
我通过Bazel构建了一个小型C++程序,相关目录结构与构建配置如下:
项目目录结构
. ├── bazel-bin -> /data/.cache/execroot/__main__/bazel-out/k8-fastbuild/bin ├── bazel-main -> /data/.cache/execroot/__main__ ├── bazel-out -> /data/.cache/execroot/__main__/bazel-out ├── bazel-testlogs -> /data/.cache/execroot/__main__/bazel-out/k8-fastbuild/testlogs ├── BUILD ├── library │ ├── BUILD │ ├── foo.cc │ └── foo.h ├── main.cpp └── WORKSPACE
library目录下的BUILD文件
package(default_visibility = ["//visibility:public"]) cc_library( name = "foo", srcs = ["foo.cc"], hdrs = ["foo.h"] )
主目录下的BUILD文件
cc_binary( name = "myapp", srcs = ["main.cpp"], deps = [ "//library:foo", ], )
构建后bazel-out/k8-fastbuild/bin目录结构
. ├── library │ ├── libfoo.a │ ├── libfoo.a-2.params │ ├── libfoo.so │ ├── libfoo.so-2.params │ └── _objs │ └── foo │ ├── foo.pic.d │ └── foo.pic.o ├── myapp ├── myapp-2.params ├── myapp.runfiles │ ├── __main__ │ │ └── myapp -> /data/.cache/execroot/__main__/bazel-out/k8-fastbuild/bin/myapp │ └── MANIFEST ├── myapp.runfiles_manifest └── _objs └── myapp ├── main.pic.d └── main.pic.o
已知PIC代表位置无关代码(Position Independent Code),针对上述构建结果,有以下三个疑问及解答:
1. Bazel链接main时会使用libfoo.a还是foo.pic.o?
Bazel默认会直接使用foo.pic.o目标文件进行链接,而非libfoo.a静态库。这是因为Bazel采用精细的依赖管理与增量构建策略,直接引用编译后的目标文件可以跳过静态库打包、解压的冗余步骤,大幅提升构建效率。
只有当你显式通过linkopts参数指定链接静态库,或者调整cc_library的构建属性时,才会强制使用libfoo.a。
2. Bazel为何同时生成libfoo.xx和foo.pic.xx两类文件,二者有何区别?
两类文件的核心区别与用途如下:
- foo.pic.o:是
foo.cc编译生成的单个位置无关目标文件,属于构建过程的中间产物,用于直接链接到最终二进制或其他依赖库中,是Bazel默认优先使用的依赖形式。 - libfoo.a/libfoo.so:分别是静态归档库与共享库,属于该
cc_library的独立输出产物。
Bazel同时生成两类文件是为了适配多场景需求:
- 内部依赖时用目标文件链接更高效;
- 若需要将库导出给非Bazel项目使用,可直接取用静态/共享库;
- 部分第三方规则或工具可能要求输入归档格式的库文件。
3. 将library目录移出主目录,通过WORKSPACE的local_repository指定后,为何仅生成foo.pic.xx文件,无libfoo.xx文件?
这是Bazel对外部本地仓库的优化策略导致的:
当库作为外部依赖(即使是本地目录)通过local_repository引入时,Bazel默认仅生成满足当前项目直接依赖所需的产物——也就是foo.pic.o目标文件,因为外部仓库的库通常仅被当前项目的目标引用,不需要生成独立归档库供外部导出。
如果需要让外部仓库的库生成静态/共享库,可以在外部仓库的BUILD文件中添加exports_files规则,或者调整cc_library的alwayslink、linkstatic等属性,强制Bazel生成归档产物。
内容的提问来源于stack exchange,提问作者codesavesworld
相关产品推荐
相关产品推荐

