Переопределить слабые символы в статической библиотеке

Я хочу сделать статическую библиотеку.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).

Другие вопросы по тегам