2009-11-19 5 views
3

Предположим, у меня есть статическая библиотека libx.a. Как мне сделать некоторые символы (не все) из этой библиотеки, чтобы быть всегда присутствует в любом бинарном я ссылку с моей библиотекой? Причина в том, что мне нужны эти символы для доступа через dlopen + dlsym. Я знаю, что-быще-архивный компоновщик, но он заставляет все объектные файлы из архива библиотеки связываться в получающийся двоичный файл, и это не то, что я хочу ...как всегда включать символы из статической библиотеки?

Наблюдения до сих пор (CentOS 5.4, 32bit) (обн: этот пункт не так, я не мог воспроизвести это поведение)

ld main.o libx.a 

счастливо раздеть все не ссылки символов, в то время как

ld main.o -L. -lx 

соединит всю библиотеку, я думаю. это зависит от версии binu однако новые линкеры смогут выбирать отдельные объекты из статической библиотеки.

Другой вопрос: как я могу добиться такого же эффекта под Windows?

Заранее спасибо. Любые подсказки будут высоко оценены.

ответ

1

Я бы начал с разделения этих символов, которые вам всегда нужны, в отдельную библиотеку, сохраняя только дополнительные в libx.a.

+0

, кажется, самый простой и практичный путь к цели, но я считаю, что OP хочет более элегантного решения :) –

+0

@MottiShneor: Простой и практичный * - элегантный. ;-) Боже, это должно быть одно из моих * самых старых сообщений * SO ... :-D – DevSolar

+0

Я думаю, для этого должен быть флаг компоновщика, что-то вроде -все-архив или тому подобное. Я пришел к этому вопросу и ответу, потому что теперь у меня противоположная проблема. Мои статические символы lib просто не будут «проходить» мою Xcode Framework (что является своего рода dylib), и я не могу понять, почему. –

1

Возьмите адрес символа, который необходимо включить.

Если оптимизатор gcc в любом случае устраняет это, сделайте что-то с этим адресом - должно быть достаточно.

+0

Спасибо, но я уже думал об этом взломе; Мне интересно, есть ли чистые способы сделать это. – kolbusa

+2

@ kolbusa Хаки не вредят :) – qrdl

+0

@kolubsa: Я бы не считал это взломом ... вам нужно как-то ссылаться на символы, чтобы заставить компоновщик втянуть их. – Nicholaz

2

В первую очередь: ld main.o libx.a не создает действительный исполняемый файл. В общем, вы должны никогда использовать ld, чтобы связать что-либо напрямую; всегда использовать надлежащий драйвер компилятора (gcc в данном случае).

Кроме того, "ld main.o libx.a" и "ld main.o -L. -lx" должны быть в точности эквивалентными. Я очень сомневаюсь, что вы получили разные результаты от этих двух команд.

Теперь, чтобы ответить на ваш вопрос: если вы хотите foo, bar и baz быть экспортированы из вашего a.out, сделайте следующее:

gcc -Wl,-u,foo,-u,bar,-u,baz main.o -L. -lx -rdynamic 

Обновление:
Ваше утверждение: «символы Я хочу включить используются только внутри библиотеки "не имеет большого смысла: если символы являются внутренними для библиотеки, зачем их экспортировать? И если что-то еще использует их (через dlsym), то они являются не внутренними библиотеками - они являются частью общедоступного API библиотеки.

Вы должны уточнить свой вопрос и объяснить, что вы делаете действительно. Предоставление образца кода тоже не повредит.

+0

1. Действительно, я не могу воспроизвести разницу между -l и спецификацией библиотеки прямо сейчас. Возможно, я сделал что-то не так ... 2. Хотя -u выглядит как решение, использовать его Мне нужно знать список «лишних» символов при создании двоичного файла. Я хотел бы «скрыть» эти зависимости (символы, которые я хочу включить, используются только внутри библиотеки). – kolbusa

3

Представьте, что у вас есть проект, который состоит из следующих трех файлов C в одной папке;

// ---- jam.h 
int jam_badger(int); 

// ---- jam.c 
#include "jam.h" 
int jam_badger(int a) 
{ 
    return a + 1; 
} 

// ---- main.c 
#include "jam.h" 
int main() 
{ 
    return jam_badger(2); 
} 

И вы создадите его с помощью файла bjam с форсированием, как это;

lib jam : jam.c <link>static ; 

lib jam_badger : jam ; 

exe demo : jam_badger main.c ; 

У вас будет такая ошибка.

undefined reference to `jam_badger' 

(я использовал bjam здесь, потому что файл легче читать, но вы можете использовать все, что вы хотите)

Извлечение «статический» производит рабочий двоичный, как это делает добавление статического к другому библиотеки или просто используя одну библиотеку (а не глупую обертку внутри другой)

Причина этого в том, что ld достаточно умен, чтобы выбрать только те части архива, которые в действительности используются, ни один из них.

Решение состоит в том, чтобы окружить статические архивы с помощью -Wl, - цельного архива и -Wl, - без-целого архива, например;

g++ -o "libjam_candle_badger.so" -Wl,--whole-archive libjam_badger.a Wl,--no-whole-archive 

Не совсем уверен, как получить boost-build, чтобы сделать это за вас, но вы получите эту идею.

+0

Есть ли у вас идея, как это сделать с помощью настроек Apple Xcode? Xcode создает собственные строки команд. Используя форму «Настройки сборки», вы можете изменить способ ее работы и, таким образом, косвенно ввести флаги компоновщика, а также добавить свои собственные «другие флаги компоновщика», но я не думаю, что они «обернут» конкретный ввод файл/staticLib. –

Смежные вопросы