كيفية تطبيق خيار التصفية للرموز في المكتبات الثابتة؟
-
19-09-2019 - |
سؤال
لدي مشروع مكتبة مشترك تم بناؤه من 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 بعد اكتشاف أي رابط يحتوي النظام عليه.