ein*_*ica 5 c++ linker static-block ld abstract-factory
我有这个库,其中包含一些需要在之前运行的静态初始化代码main()。如果您只将所有翻译单元一起编译,那么一切都很好,但是如果我提供一个静态库(.a文件)并让用户将其应用程序链接到它,则它不起作用-链接器只是忽略了进行我的静态初始化的符号。
或者,如果我为GCC指定选项,即为GNU链接指定选项,则可以使链接程序在静态库中接收所有内容。-Wl,--whole-archive--whole-archive
但是有中间立场吗?我可以标记一些符号并使链接器始终为可执行文件选择它们,而其余符号仅在需要时添加吗?
动机:我使用一些静态块在工厂中注册类。我想让我的代码可以作为(非动态)库使用,而用户代码不必为要填充的工厂执行任何“魔咒”。
一些相关的问题:
您可以强制链接器保留给定的函数(当然,也包括从此函数调用的所有代码)。添加-u my_function到链接命令。许多构建系统允许静态库将构建设置“导出”给使用它们的人。例如,对于 Android ndk-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)
Run Code Online (Sandbox Code Playgroud)
在您的模块Android.mk中。人们通过在Android.mk中添加简单的语句来重用它
$(call import-module,third_party/the_best_static_library)
Run Code Online (Sandbox Code Playgroud)
注意:对于这种方法的工作,my_function()不能声明static。如果某个符号在文件范围内被声明为静态,则链接器猜测根本不知道它的名称。幸运的是,如果链接器决定保留的某些代码中引用了它,那么它也不会被删除。此外,除非您付出特别的努力,否则链接器将删除或保留整个编译单元(也称为 C 文件)。因此,“锚定”一个虚拟函数通常足以保留许多函数和数据。