Soru Statik kütüphanelerde gcc-görünmezlik seçeneği sembollere nasıl uygulanır?


4 statik kitaplıktan oluşturulmuş bir paylaşılan kitaplık projem var (.a) ve bir nesne (.o) dosya. Eklemeye çalışıyorum -fvisibility=hidden Çıktının içindeki sembolleri, yalnızca __attribute__ ile kaynakta işaretlediğim karakterlere sınırlama seçeneği.

Ekledim -fvisibility=hidden için derleme seçenekleri seçeneği .so projeyi kapsar .o dosya) ve .a projeler.

Nesne dosyasındaki semboller, finalden beklendiği gibi kaldırılır .so. Ancak semboller .a projeler hala finalde .so dosya. Ekleme -fvisibility=hidden seçeneğine .so bağlantı komutunun etkisi yoktur.

Neyi yanlış yapıyorum?

Buradaki amacım .so arayüz dışındaki tüm semboller kütüphaneye fonksiyon verir.

DÜZENLEME: Aslında bir sürüm haritası Bunu şimdilik çözmek için. Bununla birlikte, harici semboller değiştikçe, sürüm komut dosyasının sürekli bakımını gerektirir. Kabul edilen cevabın daha iyi bir fikri vardır.


35
2018-02-08 14:23


Menşei


Platform belirtilmemiş, ancak iOS / OS X altında bunu yapmak için bir çözüm için bkz. stackoverflow.com/a/18949281/316487 - bleater


Cevaplar:


Temel olarak, bağlantı sırasında görünürlük işlenir ve bağlayıcı, statik arşivlere dayatılmayabilir. SO ile ilgili bir soru (bir çoğaltmasa da) sorulmuştur. İşte.

Yapmanızı tavsiye ettiğim şey, bağlantı aşamasını değiştirmek: gcc -shared -o mylib.so foo.o libbar.a Nesne dosyalarını geri aldığınız iki aşama sürecine:

  • ar x libbar.a (muhtemelen uygun, boş bir dizine)
  • gcc -fvisibility=hidden -shared -o mylib.so foo.o tempdir/*.o

28
2018-02-12 11:38



İyi fikir. Deneyimle öğrendiklerime uyuyor. Bunu daha sonra deneyebilirim. - Steve Fallows


Sadece geçmek -Wl,--exclude-libs,ALL gcc'ye

Bu, linker'ın statik kütüphanelerdeki tüm sembolleri gizli olarak değiştirmesini söyleyecektir.

--exclude-libs ayrıca, kütüphaneleri sembollerin saklandığı daha ince tanecikli için arşivlerin bir listesini (yani statik kütüphane isimleri) de kabul eder.

Not: Bu yalnızca GNU binutils (örneğin Linux) kullanan sistemlerde veya destekleyen bir linker ile çalışacaktır. --exclude-libs (ör. OSX’in ld64’ünde çalışmaz)


51
2018-02-13 21:24



Size çok teşekkür ederim! Bunu -fvisibility = ile birlikte kullanıyorum gizli ve seçici bir şekilde sadece genel API'yi dışa aktarıyorum (IMO sadece projeye harici statik kütüphaneler söz konusu olduğunda özellikle beyaz liste yaklaşımı aklı başındadır). Belki de bazı etiketler ekleyebilirseniz Google çalışanı müteşekkir olacaktır. - dashesy
Sanırım -Wl, - exclude-libs = ALL (ikinci virgülü bir = ile değiştir) - Nathan Monteleone
Maalesef bu Mac OS'de bu seçeneği bilmediğinden Mac OS'de çalışmaz. - rsp1984
Ayrıca, --exclude-libs yalnızca dinamik kütüphanelerde olmayan statik lib'lerde uygulanabilir. - Manish Shukla
@ManishShukla Soru, özellikle statik kütüphaneler hakkında - fons


Bu OS X için sorunun bir cevabı.

Mac ld desteklemiyor --exclude-libsama destekliyor -exported_symbol sym ve o yapar Bunu, statik kitaplıklardaki nesne nesnelerine uygulayın. Ve bir genel API'ye filtrelediğinizde, beyaz liste bunu heceleyecek kadar küçüktür.

Makefile’de aşağıdakileri yaptım: -Wl,-exported_symbol,_api_func_1 Dışa aktarılan her sembol için bayrak:

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)

Daha sonra sistemin hangi linker olduğunu tespit ettikten sonra bayrakların bu versiyonu ile GNU ld versiyonu arasında geçiş yapabilirsiniz.


1
2018-05-30 15:45