【问题标题】:Controlling the use of --whole-archive with Bazel cc_binary() rule使用 Bazel cc_binary() 规则控制 --whole-archive 的使用
【发布时间】:2017-08-29 13:58:18
【问题描述】:

我想在使用 cc_binary() 规则链接共享库 (.so) 时控制 -whole-archive 的使用。

我使用 cc_binary() 规则创建共享库的原因与此线程有关:https://groups.google.com/forum/#!topic/bazel-discuss/NG4N84ar3BY

我有一个 liba.a,其中包含两个函数实现:a()、a1(),它们在单独的目标文件中实现并归档到一个 .a 文件中。 代码如下:

交流

void a() {
    puts("a");
}

a1.c

void a1() {                                                
    d();                                                   
}

构建文件

cc_library(                                                
    name = 'a',                                            
    srcs = [ 'liba.a' ],                                   
    hdrs = [ 'a.h' ],                                      
    linkstatic = True,                                     
)

我想用上述库构建一个依赖(链接)的共享库:

b.c

void b() {
    a();
    puts("b");
}

构建文件

cc_binary(                                                 
    name = 'libb.so',                                      
    srcs = [ 'b.c' ],                                      
    deps = [ ':a' ],                                       
    linkshared = True,                                     
)

我想要实现的是链接 libb.so,使其仅将 liba.a 用于所需的符号,在这种情况下,它应该只需要 a.o 对象和链接它进入 libb.so

我无法做到这一点。在构建时,Bazel 将为 liba.a 使用 -whole-archive,这将导致包含 a1() 的实现以及根本不需要的实现。

如果不使用 -whole-archive,则结果 libb.so 将被正确构建,并且不会有 a1() 符号。

这很重要的原因是,现在libb.so 在使用-whole-archive 时会无缘无故地导致对d() 的依赖。

这是运行bazel build libb.so -s的链接命令的sn-p输出:

>>>>> # //: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 放弃使用 -whole-archive 代替 liba.a

【问题讨论】:

    标签: bazel


    【解决方案1】:

    您可以使用--nolegacy_whole_archive 禁用为共享库的依赖项设置整体存档。在https://docs.bazel.build/versions/master/command-line-reference.html中有一个简短的解释。

    【讨论】:

    • 不确定它对我有多大帮助。我需要能够从最终目标的角度控制哪些依赖项应该是一个完整的档案,哪些不是。如果我有两条规则,一条将 liba.a 作为一个完整的归档文件,另一个需要与 liba.a 链接并且不将其作为一个完整的归档文件使用,那么我不确定我是否了解它是如何完成的。 alwayslink 将控制一个库是否是依赖于该库的所有目标的完整档案。有没有办法控制它?
    • 您需要两个不同的目标。在docs.google.com/document/d/… 实施之前它不会很好地工作。除了以下 hack:如果您将 .a 文件重命名为 .lo,它将作为整个存档链接。我们也在考虑让 Wholearchive 应用于边缘,而不是节点(例如,通过具有 whole_archive_deps 属性),但短期内没有计划这项工作。
    猜你喜欢
    • 2015-08-06
    • 1970-01-01
    • 2017-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多