使用 Bazel cc_binary() 规则控制 --whole-archive 的使用
Controlling the use of --whole-archive with Bazel cc_binary() rule
我想在使用 cc_binary() 规则 linking 共享库 (.so) 时控制 -whole-archive
的使用。
我使用 cc_binary() 规则创建共享库的原因与此线程有关:https://groups.google.com/forum/#!topic/bazel-discuss/NG4N84ar3BY
我有一个 liba.a,其中包含两个函数实现:a()、a1(),它们在单独的目标文件中实现并归档到一个 .a 文件中.
代码如下:
a.c
void a() {
puts("a");
}
a1.c
void a1() {
d();
}
构建文件
cc_library(
name = 'a',
srcs = [ 'liba.a' ],
hdrs = [ 'a.h' ],
linkstatic = True,
)
我想构建一个依赖于(links)以上库的共享库:
b.c
void b() {
a();
puts("b");
}
构建文件
cc_binary(
name = 'libb.so',
srcs = [ 'b.c' ],
deps = [ ':a' ],
linkshared = True,
)
我想要实现的是 linking libb.so,这样它只会使用 liba.a 作为所需的符号,在这种情况下,它应该只需要 a.o 对象和 link 到 libb.so
我无法做到这一点。构建时,Bazel 将使用 -whole-archive
作为 liba.a,这将导致包含 a1()
的实现以及根本不需要的实现。
如果没有使用 -whole-archive
,那么结果 libb.so 会被正确构建,并且不会有 a1()
符号。
这很重要的原因是现在 libb.so
在使用 -whole-archive
时会无缘无故地导致对 d()
的依赖。
这是 linkage 命令的片段输出,来自 运行 bazel build libb.so -s
:
>>>>> # //:libb.so [action 'Linking libb.so']
(cd /bazel/jbasila/_bazel_jbasila/9ad84409935838f6b01d4c9936deda53/execroot/__main__ && \
exec env - \
PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/.local/bin:/home/jbasila/bin:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/.local/bin:/home/jbasila/bin \
PWD=/proc/self/cwd \
/usr/bin/gcc -shared -o bazel-out/local-fastbuild/bin/libb.so '-fuse-ld=gold' -Wl,-no-as-needed -Wl,-z,relro,-z,now -B/usr/bin -B/usr/bin -pass-exit-codes -Wl,-S -Wl,@bazel-out/local-fastbuild/bin/libb.so-2.params)
文件内容bazel-out/local-fastbuild/bin/libb.so-2.params
:
-whole-archive
bazel-out/local-fastbuild/bin/_objs/libb.so/b.pic.o
-no-whole-archive
-whole-archive
liba.a
-no-whole-archive
-lstdc++
-lm
那么问题又来了,有没有办法让 Bazel 放弃对 liba.a
使用 -whole-archive
?
您可以使用 --nolegacy_whole_archive
来禁用为共享库的依赖项设置整个存档。 https://docs.bazel.build/versions/master/command-line-reference.html.
中有一个简短的解释
我想在使用 cc_binary() 规则 linking 共享库 (.so) 时控制 -whole-archive
的使用。
我使用 cc_binary() 规则创建共享库的原因与此线程有关:https://groups.google.com/forum/#!topic/bazel-discuss/NG4N84ar3BY
我有一个 liba.a,其中包含两个函数实现:a()、a1(),它们在单独的目标文件中实现并归档到一个 .a 文件中. 代码如下:
a.c
void a() {
puts("a");
}
a1.c
void a1() {
d();
}
构建文件
cc_library(
name = 'a',
srcs = [ 'liba.a' ],
hdrs = [ 'a.h' ],
linkstatic = True,
)
我想构建一个依赖于(links)以上库的共享库:
b.c
void b() {
a();
puts("b");
}
构建文件
cc_binary(
name = 'libb.so',
srcs = [ 'b.c' ],
deps = [ ':a' ],
linkshared = True,
)
我想要实现的是 linking libb.so,这样它只会使用 liba.a 作为所需的符号,在这种情况下,它应该只需要 a.o 对象和 link 到 libb.so
我无法做到这一点。构建时,Bazel 将使用 -whole-archive
作为 liba.a,这将导致包含 a1()
的实现以及根本不需要的实现。
如果没有使用 -whole-archive
,那么结果 libb.so 会被正确构建,并且不会有 a1()
符号。
这很重要的原因是现在 libb.so
在使用 -whole-archive
时会无缘无故地导致对 d()
的依赖。
这是 linkage 命令的片段输出,来自 运行 bazel build libb.so -s
:
>>>>> # //:libb.so [action 'Linking libb.so']
(cd /bazel/jbasila/_bazel_jbasila/9ad84409935838f6b01d4c9936deda53/execroot/__main__ && \
exec env - \
PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/.local/bin:/home/jbasila/bin:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/tools/bin:/home/jbasila/tools/git-tools:/home/jbasila/.local/bin:/home/jbasila/bin \
PWD=/proc/self/cwd \
/usr/bin/gcc -shared -o bazel-out/local-fastbuild/bin/libb.so '-fuse-ld=gold' -Wl,-no-as-needed -Wl,-z,relro,-z,now -B/usr/bin -B/usr/bin -pass-exit-codes -Wl,-S -Wl,@bazel-out/local-fastbuild/bin/libb.so-2.params)
文件内容bazel-out/local-fastbuild/bin/libb.so-2.params
:
-whole-archive
bazel-out/local-fastbuild/bin/_objs/libb.so/b.pic.o
-no-whole-archive
-whole-archive
liba.a
-no-whole-archive
-lstdc++
-lm
那么问题又来了,有没有办法让 Bazel 放弃对 liba.a
使用 -whole-archive
?
您可以使用 --nolegacy_whole_archive
来禁用为共享库的依赖项设置整个存档。 https://docs.bazel.build/versions/master/command-line-reference.html.