Как применить параметр -fvisibility к символам в статических библиотеках?

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

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

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

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

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

EDIT: Я на самом деле использовал карту версий, чтобы решить эту проблему на данный момент. Однако это требует продолжения обслуживания скрипта версии при изменении внешних символов. Принятый ответ имеет лучшую идею.

В основном, видимость обрабатывается во время связывания, и компоновщик, похоже, не накладывает его на статические архивы. Соответствующий вопрос (хотя и не дубликат) был задан здесь .

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

  • ar x libbar.a (возможно, в подходящую пустую директорию)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o

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

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

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

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

Это ответ на проблему для 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 [email protected] ... $(LDFLAGS) 

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

Interesting Posts

Чистая установка Windows 8 на OEM-ноутбуке Windows 8

Как я могу определить виновника моего медленного закрытия Windows?

Купить версию старой версии Windows и получить бесплатную версию?

Как продолжить передачу файлов в локальную сеть в Windows?

ASP.NET MVC и Ajax, одновременные запросы?

Использует Random и OrderBy хороший алгоритм тасования?

Поиск наилучшей точки компромисса на кривой

Что именно делает планировщик QoS-пакетов? Каковы конкретные реальные причины для его включения?

Контроль доступа в ASP.NET MVC в зависимости от входных параметров / уровня обслуживания?

Как отключить запись в Firebase 3.x

Как вставить видео в PowerPoint с относительными путями?

Какая лучшая библиотека обработки изображений java?

Как я могу «группировать по» и суммировать столбец в excel?

Как отключить предупреждения о неиспользуемом коде в Rust?

Ubuntu не будет распознавать загрузочный USB или CD

Давайте будем гением компьютера.