I would like to control the use of -whole-archive
when linking a shared library (.so) using the cc_binary() rule.
The reason I'm using a cc_binary() rule to create a shared library is related to this thread: https://groups.google.com/forum/#!topic/bazel-discuss/NG4N84ar3BY
I have a liba.a that contains two function implementations: a(), a1() which are implemented in separate object files and archived into one .a file. the code is as follows:
a.c
void a() {
puts("a");
}
a1.c
void a1() {
d();
}
BUILD file
cc_library(
name = 'a',
srcs = [ 'liba.a' ],
hdrs = [ 'a.h' ],
linkstatic = True,
)
I would like to build a shared library that depends (links) with the above library:
b.c
void b() {
a();
puts("b");
}
BUILD file
cc_binary(
name = 'libb.so',
srcs = [ 'b.c' ],
deps = [ ':a' ],
linkshared = True,
)
What I would like to achieve is linking libb.so in such a way that it will only use liba.a for the required symbols, in this case it should only require the a.o object and link it into libb.so
I could not make this happen. When building, Bazel will use -whole-archive
for liba.a which will result in containing the implementation of a1()
as well when it is not required at all.
If the -whole-archive
was not used, then resulted libb.so would have been built correctly, and there would have been no a1()
symbol.
The reason that this is important, is that now libb.so
when using -whole-archive
will cause a dependency on d()
for no reason.
This is the snippet output of the linkage command from running 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)
The content of the file 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
So to the question again, is there a way to make Bazel ditch the use of -whole-archive
for liba.a
?
You can use
--nolegacy_whole_archive
to disable setting the whole-archive for dependencies of a shared library. There is a short explanation in https://docs.bazel.build/versions/master/command-line-reference.html.