Переопределить слабые символы в статической библиотеке
Я хочу сделать статическую библиотеку.a для моего проекта из нескольких источников, некоторые из них определяют слабые функции, а другие реализуют их. Скажем в качестве примера у меня есть:
lib1.c:
void defaultHandler()
{
for(;;);
}
void myHandler() __attribute__((weak, alias ("defaultHandler")));
lib2.c:
void myHandler()
{
/* do my stuff here */
}
Затем я хочу поместить их в одну библиотеку, чтобы она была прозрачной для конечного приложения.
$ ar -r libhandlers.a lib1.o lib2.o
Но теперь есть 2 символа myHandler
в libhandlers:
$ nm libhandlers.a | grep "myHandler"
00000001 W myHandler
00000581 T myHandler
И затем при использовании lib, слабая ссылка связана. Единственное решение, которое у меня есть на данный момент, это не включать в библиотеку. lib2.c
но добавлять его в качестве исходного кода в Makefile приложения... это неудовлетворительно, поскольку я хотел бы предоставить только несколько библиотек для использования, а не целую кучу файлов.
--whole-archive
Опция также не удовлетворяет, так как я работаю на встроенной системе и не хочу включать все вещи, которые мне не нужны.
Есть ли способ скомпилировать библиотеку, чтобы слабый символ исчезал, если был указан сильный?
ПРИМЕЧАНИЕ: я использую arm-none-eabi-gcc v4.8
1 ответ
Это побочный продукт того, что .a
библиотеки работают - они просто коллекция .o
файлы.
Что происходит во время компиляции, так это то, что первая ссылка на имя преобразуется в слабую ссылку, а строгое имя никогда не просматривается.
Вы можете проверить это сами, фактически сделав одинаковое и сильное имя, и вы увидите точно такое же поведение.
Если вы хотите, чтобы сначала были разрешены строгие ссылки, поместите их ранее в архив или создайте отдельный надежный архив и создайте ссылку, которая сначала находится в строке ссылок.
Хотя это не относится непосредственно к вашему случаю, поскольку вы используете встроенную среду, слабые и сильные ссылки вступают в силу надлежащим образом при создании / использовании .so
динамические библиотеки, а не .a
архивы. Когда вы создаете.so, все слабые ссылки, которые составляют библиотеку, не будут генерировать ошибку, и только одна из них будет использоваться для конечного продукта; и если где-либо есть строгое определение, то оно используется, а не любое из слабых (это работает правильно только тогда, когда вы создаете .so
связываешь все .o
файлы, которые составляют его отдельно, или использовать --whole-archive
при создании .so
если ссылка на .a
).