如何使用Bazel链接不带‘lib’前缀的外部库ace.so?
在Bazel中链接不带
lib前缀的共享库(如ace.so) 我之前也碰到过完全一样的问题——要在Bazel里直接链接不带标准lib前缀的共享库,不想靠创建符号链接这种临时方案。下面是两个经过验证的可行方案,以及为什么你之前的尝试没成功的原因:
方案一:直接将共享库作为链接输入文件(最可靠)
这种方法绕开了链接器的-l选项规则,直接把ace.so当作普通目标文件传给链接器,就像你手动执行gcc ... path/to/ace.so一样。配置如下:
cc_library( name = "ace", hdrs = glob(["path/to/ace/**/*.h"]), # 精准匹配头文件,避免不必要的文件 srcs = ["path/to/ace.so"], # 直接指定库文件路径作为链接选项,Bazel会自动替换$(location)为正确的构建路径 linkopts = ["$(location path/to/ace.so)"], )
当你在其他目标中依赖//:ace时,Bazel会自动把ace.so的正确路径插入到链接命令里,完全不需要关心前缀问题。
方案二:使用cc_import配合自定义链接选项
如果你更倾向于用Bazel专门为预编译库设计的cc_import规则,需要明确告诉链接器使用不带前缀的库名:
cc_import( name = "ace", shared_library = "path/to/ace.so", hdrs = glob(["path/to/ace/**/*.h"]), # 通过-Wl传递链接器参数,强制使用指定的库文件名 linkopts = ["-Wl,-l:ace.so"], # 确保运行时能找到库,添加到data中 data = ["path/to/ace.so"], )
为什么你之前的尝试失败了?
copts不是链接选项:copts是传给编译器(gcc/g++)的编译参数,链接选项必须用linkopts,这也是你加-l:ace.so到copts里没效果的原因。cc_import的默认行为:当你直接用cc_import而不指定linkopts时,Bazel会自动尝试给库名加上lib前缀,生成-lace的链接参数,这就和你要的-l:ace.so冲突了。srcs中的.so文件会被Bazel自动处理:如果你在cc_library的srcs里放ace.so,Bazel默认会把它当作需要链接的库,自动生成-lace参数,覆盖你手动加的linkopts——这也是方案一用$(location)直接指定路径的原因,绕开了这个自动处理逻辑。
验证方法
你可以通过bazel build --subcommands //your/target查看生成的链接命令,确认ace.so是否被正确添加(要么是完整路径,要么是-l:ace.so参数)。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

