У меня есть эта библиотека, которая включает в себя некоторый статический код инициализации, который должен быть запущен до main()
, Все работает хорошо, если вы просто скомпилируете все блоки перевода вместе, но не работает, если я предоставляю статическую библиотеку (.a
файл), и пользователи связывают свои приложения с ним — компоновщик просто игнорирует символы, которые выполняют мою статическую инициализацию.
Альтернатива, я могу заставить компоновщик забрать все в статической библиотеке, если я укажу -Wl,--whole-archive
опцию GCC, т.е. указать --whole-archive
вариант ссылки GNU.
Но есть ли что-то среднее? Могу ли я пометить некоторые символы и заставить компоновщик всегда подбирать их для исполняемого файла, тогда как остальные символы добавляются только при необходимости?
Мотивация: Я использую некоторые статические блоки регистрировать классы на фабрике; Я хочу сделать мой код доступным (не динамической) библиотекой, чтобы пользовательский код не выполнял никаких «магических заклинаний» для фабрики, которую нужно заполнить.
Некоторые связанные вопросы:
Вы можете заставить компоновщик оставить данную функцию (и, естественно, весь код, который вызывается из этой функции). добавлять -u my_function
к команде связи. Многие системы сборки позволяют статическим библиотекам «экспортировать» параметры сборки тем, кто их использует. Например, для Android NDK-сборки рамки, вы можете указать что-то вроде
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
, Если какой-то символ объявлен как статический в области видимости файла, то компоновщик догадывается, что вообще не знает его по имени. К счастью, если на него ссылаются в каком-то коде, который компоновщик решает сохранить, то он также не будет удален. Кроме того, если вы не сделаете особое усилие, компоновщик удалит или сохранит целые блоки компиляции (файлы a.k.a. C). Таким образом, обычно довольно «привязать» фиктивную функцию, чтобы сохранить множество функций и данных.
Других решений пока нет …