链接时,"grab what you need" 和 "grab all" 之间是否有某些内容(-wl,--whole-archive)?

When linking, is there something between "grab what you need" and "grab all" (-Wl,--whole-archive)?

本文关键字:grab --whole-archive -wl 之间 you what need 是否 链接 all      更新时间:2023-10-16

我有这个库,它涉及一些静态初始化代码,需要在main()之前运行。如果您只是将所有翻译单元编译在一起,这一切都可以正常工作,但是如果我提供一个静态库(.a文件)并让用户将他们的应用程序链接到它,它就不起作用 - 链接器只是忽略执行静态初始化的符号。

或者,如果我为 GCC 指定-Wl,--whole-archive选项,即为 GNU 链接指定--whole-archive选项,我可以让链接器拾取静态库中的所有内容

但是有一些中间立场吗?是否可以标记某些符号并使链接器始终为可执行文件选取它们,而仅在需要时添加其余符号?

动机:我使用一些静态块在工厂中注册类;我想使我的代码作为(非动态)库提供,而无需用户代码执行任何"魔术咒语"来填充工厂。

一些相关问题:

  • 如何在 C++ 中强制包含静态库中的静态对象 (MSVC 11)
  • 如何强制 gcc 链接库中未引用的静态C++对象
  • 如何强制 gcc 链接未使用的静态库

您可以强制链接器保留给定的函数(当然,从此函数调用的所有代码)。将-u my_function添加到链接命令。许多构建系统允许静态库将构建设置"导出"给使用它们的人。例如,对于Androidndk-build框架,您可以指定类似的东西

include $(CLEAR_VARS)
LOCAL_MODULE := the_best_static_library
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_LDFLAGS := -u my_function
include $(PREBUILT_STATIC_LIBRARY)

在您的模块Android.mk中。人们通过在他们的 Android.mk中添加简单的语句来重用它

$(call import-module,third_party/the_best_static_library)

:注:对于这种方法的工作,my_function()不能static宣布。如果某个符号在文件范围内声明为静态,则链接器猜测根本不知道它的名称。幸运的是,如果在链接器决定保留的某些代码中引用了它,那么它也不会被剥离。此外,除非您特别努力,否则链接器将剥离或保留整个编译单元(也称为 C 文件)。因此,通常"锚定"一个虚拟函数以保留许多函数和数据就足够了。