Clang 不会剥离本地静态库的符号 [英] Clang does not strip symbols for local static libraries

查看:56
本文介绍了Clang 不会剥离本地静态库的符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Android NDK r18b(使用 clang 工具链)和 Android Studio 3.2.1.

Using Android NDK r18b (with clang tool chain) and 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 的相关部分:

And relevant part of my 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):

The static library mylib_jni.so is successfully built. I then run the following command (from the NDK):

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

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

<小时>

符号未剥离

在输出中,我可以看到 lib1lib2 中所有非静态方法的名称(不是可以看到的整个库以上).这怎么可能?我怎样才能从 ndk-build 命令获得一些输出,以及有关为什么符号没有被剥离的信息?(我找不到 NDK 构建步骤的 options.txt.)


Symbols not stripped

In the output I can see the names of all non-static methods in lib1 and lib2 (not whole libraries as can be seen above). How is this possible? How can I get some outputs from the ndk-build command with information about why the symbols are not stripped? (I cannot find the options.txt for my NDK build step.)

推荐答案

恐怕您对 stripvisibility=hidden 感到困惑.

I am afraid you are confused between strip and visibility=hidden.

前者 是一个单独的、后链接器、构建共享的步骤图书馆.它的目的是通过删除链接器为调试目的留下的一些额外信息来减小文件的大小(将被打包到 APK 中).请注意,当所有模块的本机库合并在一起时,gradle(在 Android Studio 3.2+ 中)甚至会在稍后执行此条带.

The former is a separate, post-linker, step of building a shared library. Its purpose is to reduce the size of the file (which will be packed into APK) by removing some extra information that the linker leaves for debugging purposes. Note that gradle (in Android Studio 3.2+) performs this strip even later, when the native libraries from all modules are merged together.

Strip 影响文件的大小,但不影响符号的可见性.

Strip effects the size of the file, but not the visibility of symbols.

隐藏符号是另一种减小二进制文件大小的技术.还强烈建议您这样做,以减少您的库受到逆向工程的影响.

Hiding symbols is another technique to reduce the size of the binaries. It is also highly recommended, to reduce exposure of your libraries to reverse engineering.

默认情况下不会发生这种情况.您必须显式添加此编译器标志:

This does not happen by default. You must explicitly add this compiler flag:

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

您可以将其与丢弃未使用的函数结合起来:

You may combine this with discarding of unused functions:

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

你必须用

__attribute__ ((visibility ("default")))

幸运的是,由于 jni.h,这个属性被设置为所有 JNIEXPORT 函数.

Luckily, thanks to jni.h, this attribute is set for all JNIEXPORT funcitons.

如果您使用预构建的静态库,您可能还需要

If you use prebuilt static libraries, you may need also

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

考虑同时提供版本脚本

LOCAL_LDFLAGS += -Wl,-version-script -Wl,mylib_jni.vs

这篇关于Clang 不会剥离本地静态库的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆