我有这个库,它涉及一些需要在main()
之前运行的静态初始化代码。如果你只是将所有的翻译单元编译在一起,这一切都很有效,但是如果我提供一个静态库(.a
文件)并让用户将它们的应用程序链接到它,它就不起作用 - 链接器只是忽略我的静态初始化的符号。
替代方法,如果我为GCC指定-Wl,--whole-archive
选项,即指定GNU的--whole-archive
选项,我可以让链接器在静态库中选择所有链接。
但是有一些中间立场吗?我可以标记一些符号并使链接器始终为可执行文件选择它们,而其他符号仅在需要时添加吗?
动机:我使用一些static blocks来注册工厂中的类;我希望将我的代码作为(非动态)库提供,而用户代码不必执行任何"魔术咒语"为工厂填充。
一些相关问题:
答案 0 :(得分:2)
您可以强制链接器保留给定的函数(当然,所有从此函数调用的代码)。将-u my_function
添加到link命令。许多构建系统允许静态库导出'构建设置给那些使用它们的人。例如,对于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)
在您的模块 Android.mk 中。人们通过添加 Android.mk 简单声明
来重复使用它$(call import-module,third_party/the_best_static_library)
N.B。对于此方法,my_function()
无法声明为static
。如果某个符号在文件范围内声明为静态,则链接器根本不会知道它的名称。幸运的是,如果在链接器决定保留的某些代码中引用它,那么它也不会被剥离。此外,除非您创建special effort,否则链接器将剥离或保留整个编译单元(a.k.a. C文件)。因此,它通常是enough到"锚定"一个虚函数,用于保存许多函数和数据。