Как применить параметр -fvisibility к символам в статических библиотеках? - PullRequest
43 голосов
/ 08 февраля 2010

У меня есть проект общей библиотеки, который построен из 4 статических библиотек (.a) и одного файла объекта (.o). Я пытаюсь добавить параметр -fvisibility=hidden, чтобы ограничить символы в выводе только теми, которые отмечены в источнике с __attribute __.

Я добавил параметр -fvisibility=hidden в параметры компиляции для проекта .so (который охватывает файл .o) и для проектов .a.

Символы в объектном файле удаляются, как и ожидалось, из окончательного .so. Однако символы из проектов .a все еще находятся в окончательном файле .so. Добавление опции -fvisibility=hidden к команде ссылки .so не имеет никакого эффекта.

Что я делаю не так?

Моя цель - удалить из .so все символы, кроме функций интерфейса для библиотеки.

РЕДАКТИРОВАТЬ: Я на самом деле использовал карту версий , чтобы решить это сейчас. Однако это требует постоянного обслуживания скрипта версии при изменении внешних символов. Принятый ответ имеет лучшую идею.

Ответы [ 3 ]

59 голосов
/ 14 февраля 2013

Просто передайте -Wl,--exclude-libs,ALL в gcc

Это скажет компоновщику преобразовать все символы в статических библиотеках в скрытые.

--exclude-libs также принимает список архивов (то есть статических имен библиотек) для более точной детализации, в которых библиотеки скрывают символы.

Примечание: это будет работать только в системах, использующих GNU binutils (например, Linux) или с компоновщиком, поддерживающим --exclude-libs (например, он не будет работать с OSX ld64)

30 голосов
/ 12 февраля 2010

По сути, видимость обрабатывается во время компоновки, и компоновщик, похоже, не навязывает ее статическим архивам. На SO здесь .

был задан связанный вопрос (хотя и не дубликат).

Я бы посоветовал вам заменить этап связывания: gcc -shared -o mylib.so foo.o libbar.a на двухэтапный процесс, в котором вы получите объектные файлы:

  • ar x libbar.a (возможно, в подходящий пустой каталог)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
5 голосов
/ 30 мая 2018

Это ответ на проблему для OS X.

Mac ld не поддерживает --exclude-libs, но поддерживает -exported_symbol sym и применяет , применяет это к объектным файлам в статических библиотеках. И когда вы фильтруете в общедоступный API, белый список достаточно мал, чтобы разобрать его.

В моем Makefile я получил следующее, чтобы сгенерировать флаг -Wl,-exported_symbol,_api_func_1 для каждого экспортируемого символа:

SYMBOLS   = api_func_1 api_func_2 api_func_3 api_func_4
SYMBOLS   += api_func_5 # add more as necessary
COMMA     = ,
LDFLAGS   += $(addprefix -Wl$(COMMA)-exported_symbol$(COMMA)_,$(SYMBOLS))

# ...

libmyapi.so: # ...
    $(CC) -shared -o $@ ... $(LDFLAGS)

Затем вы можете if-gate между этой версией флагов и версией GNU ld после определения, какой компоновщик имеет система.

...