Google Play Store requires 16KB native library alignment from Android 15 lazarus / 43-Android ---------------------------------------------------------------------- Manlio · 2025-06-02 16:54 On the Google Play Store dashboard I'm reading that starting with Android 15 it is recommended to "Recompile your app with 16 KB native library alignment". Failure to do that may cause apps to fail to load the library, or to just crash. I started studying the matter but I didn't make much progress. Is there anyone who knows how to do that? Thank you!! ---------------------------------------------------------------------- neuro · 2025-06-06 14:23 https://developer.android.com/guide/practices/page-sizes Support 16 KB page sizes 16 KB Google Play compatibility requirement Starting November 1st, 2025, all new apps and updates to existing apps submitted to Google Play and targeting Android 15+ devices must support 16 KB page sizes. -------------------------- Android NDK r28 and higher NDK version r28 and higher compile 16 KB-aligned by default. -------------------------- Android NDK r27 To support compiling 16 KB-aligned shared libraries with Android NDK version r27 and higher, you need to update your ndk-build, build.gradle, build.gradle.kts, or linker flags as follows: In your Application.mk: APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true -------------------------- Android NDK r26 and lower Update your Android.mk to enable 16 KB ELF alignment: LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384" ---------------------------------------------------------------------- nicelybrewed · 2025-06-12 06:00 Has anyone tested this to get 16KB alignment in LAMW? ---------------------------------------------------------------------- nobody.00 · 2025-08-13 20:02 LAMW Manager added support to 16kb on 64 bits build, directly of compiler Now this LD_FLAGS required has been add to fpc-android.cfg Get the new lamw_manager when this is required! But still supports to NDK r22b, but I'm preparing enviroment to migrate to ndk r28 with Clang LLVM ---------------------------------------------------------------------- nicelybrewed · 2025-08-13 20:33 Ah, cool, thanks! ---------------------------------------------------------------------- nobody.00 · 2025-08-17 14:14 To add support to 16 KB pages to ndk <= r22b add this ld flags in aarch64/android or x86_64/android: -k-z common-page-size=16384 -k-z max-page-size=16384 ---------------------------------------------------------------------- han · 2025-08-23 15:06 I put the two lines in Lazarus at the project options and get this warning: Warning: Only one source file supported, changing source file to compile from "common-page-size=16384" into "max-page-size=16384" Warning: Only one source file supported, changing source file to compile from "max-page-size=16384" into "astap_command_line.lpr" I'm using and FPCupdeLuxe cross compiler Linix to Android.  How to fix this? ---------------------------------------------------------------------- PascalDragon · 2025-08-24 09:39 Quote from: han on August 23, 2025, 05:06:01 pmI'm using and FPCupdeLuxe cross compiler Linix to Android.  How to fix this? You need to quote the options correctly (not tested): Code: [Select]-k"-z common-page-size=16384" -k"-z max-page-size=16384" or Code: [Select]-k"-z common-page-size=16384 -z max-page-size=16384" ---------------------------------------------------------------------- han · 2025-08-24 13:19 Thanks. Both options still give a warning. Now I understand they should be entered as: -k-z -kcommon-page-size=16384 -k-z -kmax-page-size=16384 No warning and the file size increases. I still have to test it in Android QuoteEach -k only forwards the immediate next token to the linker. ---------------------------------------------------------------------- han · 2025-08-24 19:51 The following project option -k-z -kcommon-page-size=16384 -k-z -kmax-page-size=16384  increase the file size but the 16kb warning does not go away. I have try to compile with a fresh LAWM manager installer. I see in the fpc.cfg the following: Quote#IFDEF CPUAARCH64 -Xd -XPaarch64-linux-android- -FlC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\llvm\prebuilt\window s-x86_64\sysroot\usr\lib\aarch64-linux-android\30 -FLlibdl.so -FDC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\aarch64-linux- android-4.9\prebuilt\windows-x86_64\bin -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ * -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ rtl -k-z common-page-size=16384 -k-z max-page-size=16384 #ENDIF But unfortunately the 16kb warning does not go away. Also the resulting program is not functional. My tester uses Android studio. My program is a command-line tool. There are even more problems : FpCupdeluxe installation, Linux to Android cross compiling using fpc 3.2.2. creates a functional Android program. But only if interpreter is adapted as follows: This is initially reported for the file: file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter libdl.so, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped For this I'm using patchelf as a fix: patchelf --set-interpreter /system/bin/linker64 ./astap_cli file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped But cross compiling from Linux to Android using FPC 3.3.1 (installed by FPcupDeLuxe) then the Android command-line program doesn't work anymore. So not much progress here. Does anybody have an hint how to solve the 16kb warning and above cross compiling problems? ---------------------------------------------------------------------- abouchez · 2025-08-25 05:56 Searching the FPC compiler sources, I found that the value seems hardcoded to 4KB: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TLinkerAndroid.SetDefaultInfo;var  s: string;begin  with Info do   begin     { Specify correct max-page-size and common-page-size to prevent big gaps between sections in resulting executable }     s:='ld -z max-page-size=0x1000 -z common-page-size=0x1000 -z noexecstack -z now -z relro --build-id $OPT -L. -T $RES -o $EXE';  My guess is that the supplied command line option is not enough to fix this. ---------------------------------------------------------------------- abouchez · 2025-08-25 06:00 I also found this article which seems very informative: https://medium.com/@contact2kalshetty/android-15-16kb-page-size-a- complete-handbook-for-android-developers-detect-fix-ship-6c4df068aef6 ---------------------------------------------------------------------- DonAlfredo · 2025-08-25 09:23 I a fix is found, I will happily implement the fix into fpcupdeluxe. ---------------------------------------------------------------------- han · 2025-08-25 13:38 Thanks for looking into the FPC code. Today I tried the project options Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i -k-z- kcommon-page-size=16384-k-z-kmax-page-size=16384 again and did in Linux the test with "readelf -l executable" as mentioned in the article. I did the test on a Linux X86_64 and Android aarch64 executable. The align value changes from $1000 to $4000!. See screenshots. Why there is still a 16kb warning, I can think only of the following explanations: 1) The Android test fails to test the 16kb alignment properly 2) My tester did something wrong (I have no Android setup here to test it, but I will try to set it up myself) Note also that when the target is Android aarch64, the compiler produces a DYN (share object file) which I still do not understand. A few years ago the compiler was producing an executable if I remember correctly. Files where compiled with a setup created by FpCupDeLuxe in Linux. ---------------------------------------------------------------------- nobody.00 · 2025-08-26 15:16 Quote from: han on August 24, 2025, 09:51:01 pmThe following project option -k-z -kcommon-page-size=16384 -k-z -kmax-page-size=16384  increase the file size but the 16kb warning does not go away. I have try to compile with a fresh LAWM manager installer. I see in the fpc.cfg the following: Quote#IFDEF CPUAARCH64 -Xd -XPaarch64-linux-android- -FlC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\llvm\prebuilt\window s-x86_64\sysroot\usr\lib\aarch64-linux-android\30 -FLlibdl.so -FDC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\aarch64-linux- android-4.9\prebuilt\windows-x86_64\bin -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ * -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ rtl -k-z common-page-size=16384 -k-z max-page-size=16384 #ENDIF But unfortunately the 16kb warning does not go away. Also the resulting program is not functional. My tester uses Android studio. My program is a command-line tool. There are even more problems : FpCupdeluxe installation, Linux to Android cross compiling using fpc 3.2.2. creates a functional Android program. But only if interpreter is adapted as follows: This is initially reported for the file: file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter libdl.so, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped For this I'm using patchelf as a fix: patchelf --set-interpreter /system/bin/linker64 ./astap_cli file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped But cross compiling from Linux to Android using FPC 3.3.1 (installed by FPcupDeLuxe) then the Android command-line program doesn't work anymore. So not much progress here. Does anybody have an hint how to solve the 16kb warning and above cross compiling problems? I need  more information about your project ? Do you use lazarus create by LAMW Manager ? Try run same test with your library My test on linux using lamw_manager : ---------------------------------------------------------------------- han · 2025-08-26 16:10 The cross compiler Linux to Android was created with FpCupdeluxe. I have tried the Windows version of LAMW but it didn't help. My source code is here: https://sourceforge.net/p/astap-program/code/ci/default/tree/command- line_version/ My executables are here: https://sourceforge.net/projects/astap-program/files/android/ And here the test result: ---------------------------------------------------------------------- han · 2025-08-26 19:18 I have now learned that old style executables are no longer allowed in Android and I have to set in the Lazarus project options, Compilation and Linking, Pass options to linker with.... Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  -pie  and for Lazarus project options, Custom options: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i -k-z- kcommon-page-size=16384-k-z-kmax-page-size=16384 Then it runs in a pre-release 16kb emulator. So all problems are now solved  . About -pie QuoteOn Linux/Android, when you build a PIE binary, the ELF header ends up marked as ET_DYN (shared object) instead of ET_EXEC. That’s normal for Android executables since Android 5.0: ET_EXEC (old-style executable) → not allowed anymore by the Android kernel/loader. ET_DYN with -pie → this is how modern Android executables look. So the fact that file says:     ELF 64-bit LSB shared object, dynamically linked, interpreter /system/bin/linker64 does not mean it’s a library — it’s a position-independent executable. ---------------------------------------------------------------------- nobody.00 · 2025-08-28 21:28 Quote from: han on August 24, 2025, 09:51:01 pmThe following project option -k-z -kcommon-page-size=16384 -k-z -kmax-page-size=16384  increase the file size but the 16kb warning does not go away. I have try to compile with a fresh LAWM manager installer. I see in the fpc.cfg the following: Quote#IFDEF CPUAARCH64 -Xd -XPaarch64-linux-android- -FlC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\llvm\prebuilt\window s-x86_64\sysroot\usr\lib\aarch64-linux-android\30 -FLlibdl.so -FDC:\lamw_manager\LAMW\sdk\ndk-bundle\toolchains\aarch64-linux- android-4.9\prebuilt\windows-x86_64\bin -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ * -FuC:\lamw_manager\LAMW\LAMW4Windows\fpc\$fpcversion\units\$fpctarget\ rtl -k-z common-page-size=16384 -k-z max-page-size=16384 #ENDIF But unfortunately the 16kb warning does not go away. Also the resulting program is not functional. My tester uses Android studio. My program is a command-line tool. There are even more problems : FpCupdeluxe installation, Linux to Android cross compiling using fpc 3.2.2. creates a functional Android program. But only if interpreter is adapted as follows: This is initially reported for the file: file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter libdl.so, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped For this I'm using patchelf as a fix: patchelf --set-interpreter /system/bin/linker64 ./astap_cli file ./astap_cli ./astap_cli: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /system/bin/linker64, BuildID[sha1]=fd5d50db766cf49c9b21ed8dcde3384c36f9ec40, stripped But cross compiling from Linux to Android using FPC 3.3.1 (installed by FPcupDeLuxe) then the Android command-line program doesn't work anymore. So not much progress here. Does anybody have an hint how to solve the 16kb warning and above cross compiling problems? When do you use fpc make with lamw_manager can be compile, your cli executable:  ppcrossa64 pointer.pas -k--dynamic-linker=/system/bin/linker64   -Tandroid  -k-pie remember: -k--dynamic-linker=/system/bin/linker64 is important, k-pie also 16kb flags is  passed by fpc.cfg ---------------------------------------------------------------------- han · 2025-08-29 08:22 I tested myself and the 16kb warning DID go away. For the future, I have suggested for FpCupDeluxe to update fpc.cfg with the the 16kb page size setting similar as LAMW. Using the lastest FpCupDeluxe and trunk, the setting the dynamic- linker=/system/bin/linker64 is now default. ---------------------------------------------------------------------- neuro · 2025-10-26 11:15 Today I have successfully converted all my Android projects to support 16 KB native library alignment. Now Google Play Console shows the following message for my apps: QuoteSupports 16 KB You may still have errors if your app uses libraries that we couldn't detect, or if your code assumes a device is using a specific page size. I have used fpcupdeluxe v2.4.0f to install Lazarus+LAMW stable versions. My LAMW Paths/Settings are the following: QuoteC:\Program Files\Java\jdk-21 C:\fpcupdeluxe\ccr\lamw-ant\apache-ant-1.10.12\bin C:\fpcupdeluxe\ccr\lamw-gradle\gradle-8.14.3 C:\Users\username\AppData\Local\Android\Sdk\ndk\21.4.7075529 C:\Users\username\AppData\Local\Android\Sdk I have done the following steps to add support for 16 KB. Step #1 I have modified file “fpc.cfg” by adding lines (marked in bold) to four android crosscompilers: Quote# begin fpcup do not remove aarch64-android # Inserted by up v2.4.0f on 10/2/2025 3:25:34 AM # Cross compile settings dependent on both target OS and target CPU #IFDEF FPC_CROSSCOMPILING #IFDEF ANDROID #IFDEF CPUAARCH64 -FDC:\fpcupdeluxe\cross\bin\all-android\bin -XPaarch64-linux-android- -Xd -FlC:\Users\username\AppData\Local\Android\Sdk\ndk\21.4.7075529\toolch ains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux- android\21 -k-z common-page-size=16384 -k-z max-page-size=16384 #ENDIF CPUAARCH64 #ENDIF ANDROID #ENDIF FPC_CROSSCOMPILING # end fpcup do not remove Step #2 I have modified “build.gradle” file according to the following instructions: Quotehttps://developer.android.com/guide/practices/page-sizes#update- packaging Note: In AGP version 8.3 to 8.5, apps are 16 KB aligned by default. However, bundletool does not zipalign APKs by default. So, the app may appear to work, but when built from a bundle in Play, it won't install. If you can't upgrade AGP to version 8.5.1 or higher, then the alternative is to switch to use compressed shared libraries. Update your Gradle configuration to have Gradle compress your shared libraries when packaging your app to avoid app installation issues with unaligned shared libraries. In your build.gradle file, add the following option: android {   ...   packagingOptions {       jniLibs {         useLegacyPackaging true       }   } } Step #3 For projects which additionally use C++ code I have used additional instructions: Quotehttps://developer.android.com/guide/practices/page-sizes Support 16 KB page sizes 16 KB Google Play compatibility requirement Starting November 1st, 2025, all new apps and updates to existing apps submitted to Google Play and targeting Android 15+ devices must support 16 KB page sizes. -------------------------- Android NDK r28 and higher NDK version r28 and higher compile 16 KB-aligned by default. -------------------------- Android NDK r27 To support compiling 16 KB-aligned shared libraries with Android NDK version r27 and higher, you need to update your ndk-build, build.gradle, build.gradle.kts, or linker flags as follows: In your Application.mk: APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true -------------------------- Android NDK r26 and lower Update your Android.mk to enable 16 KB ELF alignment: LOCAL_LDFLAGS += "-Wl,-z,max-page-size=16384" Step #4 I have used the following instructions to solve the problem of constantly crashing gradle build: Quotehttps://docs.gradle.org/current/userguide/performance.html#increa se_heap_size 8. Increase the Heap Size By default, Gradle reserves 512MB of heap space for your build, which is sufficient for most projects. However, very large builds may require more memory to store Gradle’s model and caches. If needed, you can increase the heap size by specifying the following property in the gradle.properties file in your project root or your Gradle home directory: gradle.properties org.gradle.jvmargs=-Xmx2048M For more details, see the JVM Memory Configuration documentation. ---------------------------------------------------------------------- nicelybrewed · 2025-10-26 15:11 I will mention two things that may or may not help: The first is app builds of armeabi-v7a, I found that even although they don't fall into the category of converting to 16kb page alignment, Google does not appear to like/want them anymore in your project, as soon as I removed armeabi-v7a the message went away, assuming your arm64-v8a libcontrols.so is aligned correctly to 16kb. All I needed to do was delete the armeabi-v7a folder/dir in the libs of the project. I know what folk will say, but that will drop a load of device support?...yep, no idea how to get around this, and would love to hear other's experiences with this. Second, I never tried the useLegacyPackaging route, as I really wanted to be on Gradle/AGP > v8.5.1 as suspected the legacy route might come back to bite me later, although you may have a very valid reason for staying at your current gradle version. I upgraded Gradle to v8.7 (it's also easier to have a generic named folder for the path so you don't have to keep changing config files/shell/bat files etc. to repoint to a new folder), or you can move the current data out of the current named gradle version path and copy your new upgraded v8.7 contents inside the current folder (saves a lot of messing about with paths), as long as you know what version it is, it should be fine. Under your buildscript in build.gradle you may find that you need to change the dependency class as below if you upgrade gradle to v8.7, I believe this is the class supporting this version:     dependencies {         classpath 'com.android.tools.build:gradle:8.6.0'     } You will also need to change the wrapper version in build.gradle to match. This was my experience, armeabi-v7a being dropped is a big issue for me tbh, I get they (Google) want things to move forward to 64-bit and have technically been warning about this for a good few years, but there are still brand new phones being sold with armeabi-v7a architectures, albeit budget end phones. Hopefully this will help. ---------------------------------------------------------------------- nobody.00 · 2025-11-11 18:34 Directly in the fpc.cfg file, this option works very well: -k-z common-page-size=16384 -k-z max-page-size=16384 But using Custom Options in Lazarus IDE (4.4) doesn't work so well; without quotes, the alignment is not applied. Using quotation marks results in a compilation error: -k"-z common-page-size=16384" -k"-z max-page-size=16384" The other option presented here: -k-z -kcommon-page-size = 16384 -k-z -kmax-page-size=16384 This works in the IDE, but not in lazbuild, which can make CI/CD difficult. Of all the options, the one that works best is still including these flags in fpc.cfg: -k-z common-page-size=16384 -k-z max-page-size=16384 These settings will only no longer be necessary when llvm/clang android is supported by FPC.