Android 使用NDK cmake链接静态库libm.a或libc.a

Android 使用NDK cmake链接静态库libm.a或libc.a,android,c++,android-ndk,cmake,clang,Android,C++,Android Ndk,Cmake,Clang,在android Studio中使用NDK Cmake构建系统时,是否可以链接platforms\android XX\arch arm\usr\lib*.a版本的库?我正在使用LLVM工具链和Android NDK 13 我已尝试修改示例应用程序,更改文件: 经过以下修改(添加libm.a): 生成成功,但readelf-d显示libm.so仍处于链接状态: 0x00000001 (NEEDED) Shared library: [libandroid

在android Studio中使用NDK Cmake构建系统时,是否可以链接platforms\android XX\arch arm\usr\lib*.a版本的库?我正在使用LLVM工具链和Android NDK 13

我已尝试修改示例应用程序,更改文件:

经过以下修改(添加libm.a):

生成成功,但readelf-d显示libm.so仍处于链接状态:

 0x00000001 (NEEDED)                     Shared library: [libandroid.so]
 0x00000001 (NEEDED)                     Shared library: [liblog.so]
 0x00000001 (NEEDED)                     Shared library: [libm.so]
 0x00000001 (NEEDED)                     Shared library: [libdl.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so]
同时添加libc.a时,情况会变得更糟,生成失败:

Error:error: relocation overflow in R_ARM_THM_JUMP11
Error:error: linker command failed with exit code 1 (use -v to see invocation)

顺便说一句,有时我只看到最后一个错误,没有任何解释(例如,当拼错库名时)。我是否应该设置-v标志以查看更多详细信息?如何做到这一点?

如果您只是想编译它,我会尝试使用arm linux AndroidABI gcc而不是clang。我意识到gcc被贬值了。但是如果你的目标是编译或者理解问题,我不能。从Dan的评论来看,我假设他不相信他在aosp中评论的任何标志会有所帮助(见下面的链接)

FWIW,我倾向于总是使用aosp/仿生构建中的静态库,因为我处理许多需要它们的事情。在sdk版本之间,仿生学libc中包含的符号往往有太多的不一致性,我相信在大多数情况下,静态链接它需要使用libc.a。如果要使用ndk版本的静态libc,我建议使用平台21而不是24

我认为,由于Android是如此分散,所有设备都使用不同的libc.so、libdl.so等,所以它不会引起太多问题


编辑:误读了问题

仅供参考,静态地将libc链接到你的应用程序会很痛苦。合子将拥有它自己的相同全局数据的副本,这两个副本将发生冲突。@DanAlbert我明白了。需要明确的是,您是否在谈论libc.a中内部使用的一些全局数据,这些数据是由库用户间接使用和共享的?也许可以以某种方式仅链接静态库中的必要部分,从而避免全局数据出现问题?我认为使用静态链接链接器只导入必要的东西。就C运行时而言,“必要的东西”包括全局数据。我们确实计划在NDK中实现类似的功能(这样您就可以在旧设备上访问新的libc功能),但它还没有准备好。在应用程序中使用静态libc可能没有我预期的那么糟糕。老实说,我并没有尝试过,但我尝试过的类似方法确实存在这个问题。结果是,我在build.gradle(应用程序)中将minSdkVersion设置为15,所以linker尝试从该文件夹链接libc.a。当将minSdkVersion切换到21正确的libc时,使用了一个版本,所有内容都编译成功,尽管readelf仍然显示libc.so,但我猜这是因为本机库的其他部分需要它。但是加载共享库在gcc和clang中都会失败-仅当使用静态libc.a时:
SIGSEGV(signal-SIGSEGV:address-access-protected(fault-address:0x206e7777))
我猜这是因为静态版本的libc与Dan提到的共享版本冲突。如果您正在创建一个共享库,则无法链接到libc.a,你必须使用libc.so(当然你可以,但这不是一个好主意,就像丹说的),对不起,我以为你在制作一个可执行文件。我明白了,为什么在创建共享库时要使用静态libs?老实说,除了libc之外,您可能还包括了所有需要的库的静态版本。但是,如果你的目标是创建一个共享库,我也不确定为什么要静态链接它们。最终的目标也是将*.so转换为*.a。我希望使用静态链接,以避免在有人试图滥用我的库时容易重写C函数(如memcpy等)。因为这些函数对我想要隐藏的数据进行操作。在这种情况下,将静态库链接到可执行库或共享库之间有什么区别?
Error:error: relocation overflow in R_ARM_THM_JUMP11
Error:error: linker command failed with exit code 1 (use -v to see invocation)