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

У меня есть:

  1. разделяемая библиотека, скажем libShared.so, которая содержит класс Bar с методом int Bar::do(int d) const
  2. статическая библиотека, скажем libStatic.a, которая содержит класс Foo с методом int Foo::act(int a) const.

Код Bar выглядит примерно так:

//Bar.h
class __attribute__ ((visibility ("default"))) Bar
{
  private: 
    __attribute__ ((visibility ("hidden"))) int privateMethod(int x) const;
  public:
    Bar() {}
    int do(int d) const;
}

//Bar.cpp
#include "Bar.h"
#include "Foo.h"

int Bar::do(int d) const {
   Foo foo;
   int result = foo.act(d) + this->privateMethod(d);
   return result;
}

libShared.so скомпилирован с флагом -fvisibility = hidden.

Проблема заключается в следующем: я выполняю команду Linux nm -g -D -C --defined-only libShared.so, и получается, что class Foo, вместе со своим методом виден за пределами libShared.so, несмотря на то, что компилятору было сказано скрыть все, кроме того, что помечено как "общедоступное" (фактически, они отмечены как "T" автор: nm).

Как мне этого избежать? Я хочу, чтобы в libShared.so не отображались символы, полученные от его зависимостей.

Спасибо


person Mauro    schedule 28.07.2015    source источник


Ответы (2)


Вам необходимо скомпилировать libStatic.a также с флагом -fvisibility=hidden.

person m.s.    schedule 28.07.2015
comment
извините, но это не помешает libShared.so использовать Foo? - person Mauro; 28.07.2015
comment
Я отвечаю себе. Оно работает! Я полагаю, это связано с тем, что статическая привязка не поддерживает скрытие символов, поэтому флаг hidden вступит в силу только тогда, когда объекты в статической библиотеке используются внутри общей. Большое спасибо! - person Mauro; 28.07.2015
comment
Измените свой ответ, добавив в него информацию о скрытии символов в статических и динамических библиотеках. Обнаружил это только сейчас - person Aviv; 14.01.2020

-fvisibility=hidden влияет только на видимость по умолчанию символов, сгенерированных компилятором, он не изменяет видимость существующих символов, например, полученных из статических библиотек.

К счастью, у компоновщика есть флаг, который делает именно это: используйте -Wl,--exclude-libs=ALL, чтобы изменить видимость глобальных символов со статических библиотек на скрытые, что предотвратит их экспорт в вашу общую библиотеку.

person Matthijs    schedule 04.03.2021