Clang не удаляет символы для локальных статических библиотек - PullRequest
0 голосов
/ 07 ноября 2018

Использование Android NDK r18bclang цепочкой инструментов) и Android Studio 3.2.1.

Соответствующая часть моего mylib.gradle:

task ndkBuild(type: Exec) {
    commandLine "${ndkDir}/ndk-build${ndkExt}"
}

Мой Application.mk:

APP_PLATFORM := android-17
APP_ABI := armeabi-v7a
# APP_OPTIM := release
APP_CFLAGS += -D_BSD_SOURCE

И соответствующая часть моего Android.mk:

include $(CLEAR_VARS)

LOCAL_PATH := $(BASE_PATH)
LOCAL_MODULE := mylib_jni

LOCAL_STATIC_LIBRARIES := \
  lib1 \
  lib2

LOCAL_WHOLE_STATIC_LIBRARIES := \
  mylib_wrap \
  other_wrap

include $(BUILD_SHARED_LIBRARY)

Статическая библиотека mylib_jni.so успешно создана. Затем я запускаю следующую команду (из NDK):

arm-linux-androideabi-readelf -a mylib_jni.so


Символы не вырезаны

В выводе я вижу имена всех нестатических методов в lib1 и lib2 (не целых библиотеках, как видно выше). Как это возможно? Как получить некоторые выходные данные из команды ndk-build с информацией о том, почему символы не удаляются? (Я не могу найти options.txt для моего шага сборки NDK.)

1 Ответ

0 голосов
/ 07 ноября 2018

Боюсь, вы запутались между strip и visibility = hidden .

прежний - это отдельный пост-линкерный этап создания общей библиотеки. Его целью является уменьшение размера файла (который будет упакован в APK) путем удаления некоторой дополнительной информации, которую компоновщик оставляет для целей отладки. Обратите внимание, что gradle (в Android Studio 3.2+) выполняет эту полосу еще позже, когда собственные библиотеки из всех модулей объединяются вместе.

Полоса влияет на размер файла, но не на видимость символов.

Сокрытие символов - это еще один метод уменьшения размера двоичных файлов. Также настоятельно рекомендуется, чтобы уменьшить подверженность ваших библиотек обратному проектированию.

Это не происходит по умолчанию. Вы должны явно добавить этот флаг компилятора:

APP_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden

Вы можете комбинировать это с удалением неиспользуемых функций:

APP_CFLAGS += -ffunction-sections -fdata-sections
APP_LDFLAGS += -Wl,--gc-sections

Вы должны явно пометить внешние функции

__attribute__ ((visibility ("default")))

К счастью, благодаря jni.h этот атрибут установлен для всех JNIEXPORT функций.

Если вы используете встроенные статические библиотеки, вам может потребоваться также

APP_LDFLAGS += -Wl,--exclude-libs,ALL

Также рассмотрите возможность предоставления версии скрипта

LOCAL_LDFLAGS += -Wl,-version-script -Wl,mylib_jni.vs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...