我们可以为android-ndk r10c中的共享库启用pie(即Position Independent Executables)吗?如果是,那该怎么做?
我读到我们应该使用PIC作为动态库,PIE作为可执行文件,但看起来像android NDK不支持PIC。
我尝试在LDFLAGS中启用-pie标志,但我收到以下错误:
/android-ndk-r10c/platforms/android-19/arch-arm/usr/lib/crtbegin_dynamic.o:
in function _start:crtbrand.c(.text+0x8c): error: undefined reference to 'main'
请帮我解决这个问题,因为我已经读到谷歌将在即将到来的Android版本中强制执行PIE,所以我希望我的应用程序与ANDROID-L +兼容。
真正的简短故事是,如果您正在构建共享库(而不是可执行文件),则不需要执行任何操作。在较旧版本的Android上运行的库将继续正常运行 - 在Android 5.0中没有任何改变。
几乎同样简短的故事是,如果您使用Android.mk构建可执行文件并定位到Android 4.1+,则必须自动添加必要的标记。
全文:当您尝试添加时失败的原因 -pie
标记到LDFLAGS的库,是这个标志只用于可执行文件,而不是库。构建共享库时,编译器标志 -fPIC
(在构建单个目标文件时,如果手动运行编译器 - Android.mk和ndk-build自动处理这种情况)可能需要某些体系结构,但您会注意到它是必需的,因为链接器将拒绝生成共享库,如果需要,你没有设置它。因此,如果您遇到问题,您将会知道它将无法构建 - 如果您已成功构建它,则没有任何问题。
类似地,在构建可执行文件时,您需要添加 -fPIE
在构建目标文件时,和 -fPIE -pie
链接可执行文件时。如果你的APP_PLATFORM是android-16(Android 4.1)或更高版本,Android.mk和ndk-build会自动处理这个问题。这是一个很大的问题 - 用它构建的可执行文件 -pie
只能在android-16或更高版本上运行,而无需构建可执行文件 -pie
不适用于android-21(Android 5.0)。所以这里有一个宽限期,Android 4.1到4.4会运行任何可执行文件就好了,而你明确需要一个版本没有 -pie
对于较旧的和另一个版本 -pie
对于新的。
如果您还需要定位4.1之前的Android版本,请参阅 https://stackoverflow.com/a/26422855/3115956 有关如何轻松构建可执行文件的两个版本的说明。
我们可以为android-ndk r10c中的共享库启用pie(即Position Independent Executables)吗?
PIE是在Android 4.1 /中引入的android-16
(看到 Android <uses-sdk>
),但它是可选的。看到 Android 1.5到4.1中的安全增强功能。所以我认为它更少依赖于NDK版本,而更多依赖于Android版本。
当我尝试在Android 4.0或更低版本上运行PIE代码时,我得到了一个段错误 /system/bin/linker
。那就是HTC Evo 4G。您的里程可能会有所不同,具体取决于OEM提供的链接/装载机的强大程度。另见 Android 4.0(ICS)支持主要可执行文件的PIE(位置无关可执行文件)吗?
现在,Android 5.0及更高版本需要PIE。另见 Android 5.0中的安全增强功能。
如果您尝试编译/链接Android 5.0 /android-21
(看到 Android <uses-sdk>
),没有PIE,那么你会得到一个链接错误。另见 位置独立可执行文件和Android棒棒糖。
我们可以为android-ndk中的共享库启用pie ...
快速说明一下(一旦你了解它)。 PIC
与...略有不同 PIE
。您在可执行程序上使用PIE,在共享对象上使用PIC。
如果 您正在从同一组源和目标文件构建可执行文件和共享对象,然后您将使用PIC,因为PIC适用于两者(相同) 不是 PIE的真实情况)。另见 位置独立可执行文件和Android棒棒糖。
如果是,那该怎么做?
您可以通过两种方式之一编译和链接PIE可执行文件。首先,编译所有内容 -fPIE
和链接 -pie
。第二个是编译所有内容 -fPIC
和链接 -pie
。
如果 您正在从同一组源和目标文件构建可执行文件和共享对象,然后您将使用PIC,因为PIC适用于两者(相同) 不是 PIE的真实情况)。另见 位置独立可执行文件和Android棒棒糖。