You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下Buck的link_whole未添加全部符号的原因及作用咨询

问题背景

测试库文件

头文件 ObjectA.h

#pragma once

namespace sarora::testing {
void testingObject();
void againTesting();

} // namespace sarora::testing

Cpp文件 ObjectA.cpp

#include "ObjectA.h"
#include <iostream>
namespace sarora::testing {

void testingObject() {
  std::cout << "testingObject" << std::endl;
}

void againTesting() {
  std::cout << "againTesting" << std::endl;
}

} // namespace sarora::testing

Buck构建规则

库的BUCK规则

cpp_library(
    name = "object",
    srcs = ["ObjectA.cpp"],
    headers = ["ObjectA.h"],
    link_whole = True,
)

主程序文件 main.cpp

#include "ObjectA.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
sarora::testing::testingObject();
}

主程序的BUCK规则

cpp_binary(
    name = "test",
    srcs = ["test.cpp"],
    deps = [
        ":object",
    ],
)

现象

主程序仅调用了testingObject(),执行nm main_executable_path | grep testingObject能查到对应符号,但nm main_executable_path | grep againTesting却找不到againTesting的符号。


解答

link_whole是Buck给C++库配置的链接控制选项,本质是传递给底层链接器(比如GCC的ld、Clang的ld.lld)一个指令:不要对这个库做未使用符号的剔除。

默认情况下,链接器会做“死代码消除”优化:只把被直接/间接引用到的符号(函数、全局变量等)打包进最终可执行文件,未被引用的符号会被丢弃,以此减小可执行文件体积。而当link_whole = True时,链接器会把该库的所有内容完整链接,不管其中的符号有没有被上层代码引用——但这个逻辑主要针对**静态库(.a文件)**生效。

2. 为什么会出现当前现象

你遇到的情况看起来有点反直觉,但核心原因在于目标文件的编译粒度:

  • 你的cpp_library只有一个源文件ObjectA.cpp,编译后生成的是单个目标文件(ObjectA.o),而不是由多个.o归档而成的静态库(.a)。
  • link_whole参数的设计初衷是解决静态库的链接问题:默认链接静态库时,链接器只会提取其中被引用的.o文件;而link_whole=True会强制链接器把静态库里所有的.o都包含进去。但对于单个.o文件,这个参数不起作用——链接器依然会进行符号级的死代码消除(比如通过-fdata-sections -ffunction-sections和-Wl,--gc-sections这类编译/链接选项)。
  • 因为againTesting()没有被任何代码引用,所以链接器直接把这个函数的符号从最终可执行文件中剔除了,导致nm查不到它。

如果要验证这个逻辑,可以把ObjectA.cpp拆成两个源文件:比如ObjectA1.cpp只实现testingObject(),ObjectA2.cpp只实现againTesting(),然后修改cpp_library的srcs为这两个文件。此时object库会被打包成静态库,设置link_whole=True后,链接器会把两个.o都完整链接进去,这时用nm就能查到againTesting的符号了。


内容的提问来源于stack exchange,提问作者Shivanshu Arora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:30:58