使用 Clang 作为编译器构建 Android 项目时从静态库中隐藏符号
Posted
技术标签:
【中文标题】使用 Clang 作为编译器构建 Android 项目时从静态库中隐藏符号【英文标题】:Hiding symbols from static library when building an Android project with Clang as compiler 【发布时间】:2018-12-30 17:49:51 【问题描述】:当 gcc 用作编译器时隐藏符号可以使用 --exclude-libs 选项来完成。
一个工作示例:
我的 Application.mk 文件如下所示:
APP_ABI := all
APP_STL=c++_static
APP_PLATFORM := android-21
TARGET_PLATFORM := android-21
NDK_TOOLCHAIN_VERSION := 4.9
Android.mk 文件中的以下行完成了这项工作:
LOCAL_LDFLAGS += -Wl,--exclude-libs=library.a
如果我从 Application.mk 文件中删除以下行
NDK_TOOLCHAIN_VERSION := 4.9
我相信 Clang 被用作默认编译器,它似乎没有 --exclude-libs 选项,因此 library.a 中的符号不再隐藏。
是否有与 gcc --exclude-libs 选项等效的 Clang?
我已经尝试过以下链接的建议
http://lists.llvm.org/pipermail/cfe-dev/2013-June/030376.html
但这似乎没有任何效果。
修改源代码并利用 Clang 的 LTO Visibility 属性不是一种选择。
【问题讨论】:
【参考方案1】:您链接到的页面是正确的。 --exclude-libs
是一个链接器选项,即使使用 Clang 编译,GCC 仍然用于链接。来自 NDK 文档:
GCC 二进制文件也包含在内,因为 Clang 依赖于 GCC 发行版中包含的相同的汇编器、链接器、头文件和库。
所以,LOCAL_LDFLAGS += -Wl,--exclude-libs,library.a
应该可以工作(注意 ,
而不是 =
)。我已经验证它确实可以在 CMake 项目中工作(它使用稍微不同的语法,但设置完全相同的链接器选项)。
这对您不起作用的最可能原因是存档的实际文件名不是library.a
(例如,它可能是liblibrary.a
或类似名称)。
【讨论】:
感谢您的回答。库的名称实际上不是 library.a。这只是为了本示例的目的而选择的。因此,我给出的示例使用实际的库文件名有效,但前提是我设置了 NDK_TOOLCHAIN_VERSION:=4.9。 如果你把它设置为clang
呢?
我也尝试使用 CMake 项目,在 CMakeLists.txt 文件中使用以下命令:set(CMAKE_SHARED_LINKER_FLAGS "$CMAKE_SHARED_LINKER_FLAGS -Wl -exclude-libs,ALL")。这并不成功。您能否分享您在 CMake 项目中设置的标志?
这与我设置的选项相同。我还验证了它在使用ndkBuild
而不是cmake
时有效。您确定您正在检查正确的 .so 文件(即打包到 APK 中的文件,而不是某个中间版本)?
当然应该是-Wl,--exclude-libs,ALL
,而不是-Wl -exclude-libs,ALL
。以上是关于使用 Clang 作为编译器构建 Android 项目时从静态库中隐藏符号的主要内容,如果未能解决你的问题,请参考以下文章
使用 MSVC2015 在 Windows 上进行 clang-tidy