Jak zastosować opcję-fvisibility do symboli w bibliotekach statycznych?

Mam projekt biblioteki współdzielonej, który jest zbudowany z 4 bibliotek statycznych (.a) i jednego pliku object (.o). Próbuję dodać opcję -fvisibility=hidden, aby ograniczyć symbole na wyjściu tylko do tych, które zaznaczam w źródle atrybutem___.

Dodałem opcję -fvisibility=hidden do opcji kompilacji dla projektu .so (który obejmuje plik .o) oraz dla projektów .a.

Symbole w pliku obiektowym są usuwane zgodnie z oczekiwaniami z końcowego .so. Jednakże symbole z projektów .a są nadal w ostatecznym pliku .so. Dodanie opcji -fvisibility=hidden do polecenia .so link nie daje żadnego efektu.

Co robię źle?

Moim celem jest usunięcie z .so wszystkich symboli z wyjątkiem funkcji interfejsu do biblioteki.

EDIT: w rzeczywistości użyłem mapy wersji , aby rozwiązać ten problem. Wymaga to jednak ciągłej konserwacji skryptu wersji w miarę zmiany symboli zewnętrznych. Zaakceptowana odpowiedź ma lepsze pomysł.

Author: jww, 2010-02-08

3 answers

Zasadniczo widoczność jest obsługiwana podczas łączenia, a linker nie wydaje się narzucać jej na statyczne archiwa. Podobne pytanie (choć nie duplikat) zostało zadane na SO tutaj .

Radzę ci, abyś zamienił swój etap łączenia: gcc -shared -o mylib.so foo.o libbar.a w proces dwuetapowy, w którym odzyskujesz pliki obiektowe:

  • ar x libbar.a (ewentualnie do odpowiedniego, pustego katalogu)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o
 29
Author: F'x,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:10

Wystarczy przekazać -Wl,--exclude-libs,ALL do gcc

To powie linkerowi, aby przekształcił wszystkie symbole w bibliotekach statycznych na Ukryte.

--exclude-libs akceptuje również listę archiwów (np. statycznych nazw bibliotek) dla lepszej szczegółowości, z których bibliotek należy ukrywać symbole.

Uwaga: to będzie działać tylko w systemach korzystających z GNU binutils (np. Linux) lub z linkerem wspierającym --exclude-libs (np. nie będzie działać z LD64 OSX)

 53
Author: fons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-12 21:42:43

To jest odpowiedź na problem dla OS X.

Mac ld nie obsługuje --exclude-libs, ale obsługuje -exported_symbol sym i stosuje to do plików obiektowych w bibliotekach statycznych. A kiedy filtrujesz do publicznego API, biała lista jest na tyle mała, aby to przeliterować.

W moim pliku Makefile wygenerowałem flagę -Wl,-exported_symbol,_api_func_1 dla każdego eksportowanego symbolu:

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)

Wtedy możesz if-gate pomiędzy tą wersją FLAG A wersją GNU ld po wykrywam, który łącznik ma system.

 4
Author: Riking,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-30 15:45:08