为何Enigma项目生成*.a静态库而LinkedList不生成?如何配置Bazel?
1. 为何两个项目的库文件生成情况不同?
Enigma项目中的signal_converter库包含srcs字段(对应signal_converter.cpp实现文件),Bazel会编译这些源文件生成目标文件,再打包成静态库libsignal_converter.a——这是Bazel对包含可编译代码的库的默认行为。
而LinkedList项目的linkedlist库只有hdrs字段(仅头文件,无.cpp实现代码),属于仅头文件库。这类库的代码(比如模板类、inline函数)会在编译依赖它的二进制文件时直接被引入,不需要单独编译生成库文件,所以Bazel不会产出.a静态库。即使单独执行bazel build //:linkedlist,因为没有可编译的源文件,也不会生成库文件。
2. 如何配置Bazel强制生成库文件?
分两种场景处理:
场景1:包含实现代码的库(有srcs)
如果库本身有.cpp等实现文件,直接构建该库目标即可生成静态库:
bazel build //path/to:library_target
比如Enigma项目中执行bazel build //:signal_converter,就会在bazel-bin下生成libsignal_converter.a,无需依赖cc_binary目标。
如果需要生成动态库(.so),可以在cc_library中添加linkshared = True属性:
cc_library( name = "signal_converter", srcs = [ "signal_converter.cpp" ], hdrs = [ "signal_converter.h" ], includes = [ "." ], linkshared = True, )
执行构建后会生成libsignal_converter.so动态库。
场景2:仅头文件的库(无srcs)
仅头文件库本身没有可编译代码,若要强制生成静态库,需要添加一个空的源文件作为srcs,比如创建空的dummy.cpp,再修改BUILD文件:
cc_library( name = "linkedlist", srcs = [ "dummy.cpp" ], # 添加空源文件触发库生成 hdrs = [ "node.h", "linked_list.h" ] )
此时执行bazel build //:linkedlist,Bazel会编译这个空文件生成目标文件,再打包成liblinkedlist.a静态库。
注意:仅头文件库强制生成的静态库实际上是空的,没有实际代码意义,仅满足生成库文件的形式需求。
内容的提问来源于stack exchange,提问作者DCaruso

