Can we enable pie (i.e. Position Independent Executables) for shared libraries in android-ndk r10c? And if yes then how to do it?
I read that we should use PIC for dynam
The really short story is, if you're building shared libraries (as opposed to executables), you don't need to do anything. Libraries that run on older versions of android will keep on working just fine - nothing has changed in Android 5.0 with respect to this.
The almost as short story is, if you're building executables using Android.mk and targeting Android 4.1+, the necessary flags should be added automatically already.
The full story: The reason why you fail when you try to add the -pie
flag to LDFLAGS for libraries, is that this flag is only for executables, not for libraries. When building shared libraries, the compiler flag -fPIC
(while building individual object files, if running the compiler manually - Android.mk and ndk-build takes care of this automatically) may be needed on some architectures, but you will notice that it is needed because the linker will refuse to produce a shared library if it's needed and you haven't set it. Thus, if you have an issue you will know already because it will fail to build - if you've built it successfully you don't have any issue.
Similarly when building executables, you need to add -fPIE
when building the object files, and -fPIE -pie
when linking the executables. Android.mk and ndk-build will take care of this automatically, if your APP_PLATFORM is android-16 (Android 4.1) or higher. Here's the big gotcha - executables built with -pie
will only work on android-16 or higher, while executables built without -pie
won't work on android-21 (Android 5.0). So there's a grace period here, Android 4.1 to 4.4 will run any executable just fine, while you explicitly need a version without -pie
for the older ones and another version with -pie
for the newer ones.
If you need to target Android versions prior to 4.1 as well, see https://stackoverflow.com/a/26422855/3115956 for an explanation on how to easily build two versions of your executable.
Can we enable pie (i.e. Position Independent Executables) for shared libraries in android-ndk r10c?
PIE was introduced in Android 4.1/android-16
(see Android <uses-sdk>), but it was optional. See Security Enhancements in Android 1.5 through 4.1. So I think it depends less on the NDK version, and more on the Android version.
When I try to run PIE code on Android 4.0 or below, I get a segfault in /system/bin/linker
. That's with an HTC Evo 4G. Your mileage may vary, depending on how robust the link/loader is provided by the OEM. Also see Is PIE (Position-independent executable) for main executables supported in Android 4.0 (ICS)?
Now, PIE is required for Android 5.0 and above. Also see Security Enhancements in Android 5.0.
If you try to compile/link for Android 5.0/android-21
(see Android <uses-sdk>), and without PIE, then you will get a link error. Also see Position Independent Executables and Android Lollipop.
Can we enable pie ... for shared libraries in android-ndk
And a quick word on the obvious (once you know about it). PIC
is slightly different than PIE
. You use PIE on executable programs, and PIC on shared objects.
If you are building an executable and shared object from the same set of sources and object files, then you would use PIC because PIC works for both (the same is not true of PIE). Also see Position Independent Executables and Android Lollipop.
And if yes then how to do it?
You can compile and link a PIE executable in one of two ways. First, compile everything with -fPIE
and link with -pie
. The second is to compile everything with -fPIC
and link with -pie
.
If you are building an executable and shared object from the same set of sources and object files, then you would use PIC because PIC works for both (the same is not true of PIE). Also see Position Independent Executables and Android Lollipop.