كيفية تطبيق خيار التصفية للرموز في المكتبات الثابتة؟

StackOverflow https://stackoverflow.com/questions/2222162

سؤال

لدي مشروع مكتبة مشترك تم بناؤه من 4 مكتبات ثابتة (.a) وجوه واحد (.o) ملف. أحاول إضافة -fvisibility=hidden خيار لتقييد الرموز في الإخراج إلى أولئك الذين أرتموا فقط في المصدر باستخدام __attribute__.

لقد أضفت -fvisibility=hidden خيار خيارات ترجمة ل .so مشروع (الذي يغطي .o ملف) ول .a مشاريع.

تتم إزالة الرموز الموجودة في ملف الكائن كما هو متوقع من النهائي .so. وبعد لكن الرموز من .a المشاريع كلها ما زلت في النهائي .so ملف. مضيفا -fvisibility=hidden خيار .so أمر الارتباط ليس له أي تأثير.

ما الخطأ الذي افعله؟

هدفي هنا هو إزالته من .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

نصائح أخرى

ببساطة تمر -Wl,--exclude-libs,ALL إلى دول مجلس التعاون الخليجي

سيخبر ذلك روابط تحويل جميع الرموز في المكتبات الثابتة إلى المخفية.

--exclude-libs يقبل أيضا قائمة المحفوظات (أي أسماء مكتبة ثابتة) للحصول على تحبيب أدق المكتبات التي تخفيها الرموز.

ملحوظة: لن يعمل هذا فقط في الأنظمة باستخدام GNU Binutils (مثل Linux) أو مع دعم روابط --exclude-libs (على سبيل المثال، لن يعمل مع OSX's LD64)

هذه إجابة لمشكلة نظام التشغيل X.

ماك 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)

ثم يمكنك إذا كان بوابة بين هذا الإصدار من العلامات وإصدار GNU LD بعد اكتشاف أي رابط يحتوي النظام عليه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top