eas-build icon indicating copy to clipboard operation
eas-build copied to clipboard

feat: allow to enable abi splitting via env var for local builds

Open Fuzzyma opened this issue 10 months ago • 2 comments

  • EAS_BUILD_ENABLE_ABI_SPLITTING enables abi splitting for all abis
  • EAS_BUILD_ABI_LIST lets you select which abis to build (e.g. "armeabi-v7a,arm64-v8a"

Why

In the early phases of development (especially in hobby projects), you end up sending around your apks quite a bit. The more features you add, the bigger your apks become and it is quite cumbersome to send them around easily.

Abi splitting helps in that regard by only including the abi that is needed.

It was also requested here: https://expo.canny.io/feature-requests/p/build-only-one-abi-during-development-android-only

How

I edited the gradle file to include an abi split section when some env vars are set. For later it would be obviously better to have that setting anchored in the eas.json schema. But for now, env vars were the simple simultion. If somone tells me, where the settings are read, we could translate it to an env there (?)

Test Plan

Simply pass the corresponding env vars in your eas.json:

    "preview": {
      "distribution": "internal",
      "env": {
        "EAS_BUILD_ENABLE_ABI_SPLITTING": "true",
        "EAS_BUILD_ABI_LIST": "armeabi-v7a,arm64-v8a" // optional. Will build all abis by default
      }
    },

And then do a local build. When only using a single abi, the resulting apk should be places as usual into your output dir. When specifying multple abis, a tar.gz package with all abis is created instead

Fuzzyma avatar Feb 09 '25 17:02 Fuzzyma

Lets see! If I understood correctly, I would use the mods.android.projectBuildGradle or the corresponding plugin withProjectBuildGradle to load the project gradle and do string manipulation to add the abi splitting. Is that correct?

Thanks for your feedback!

Fuzzyma avatar Feb 19 '25 21:02 Fuzzyma

@szdziedzic so i came up with something and it looks like it should just work ™️ but it doesnt:

export const abiList = ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"];

export function withAbiSplitting(config, abiFilters) {
  return withAppBuildGradle(config, (config) => {
    if (abiFilters && abiFilters.length === 0) {
      return config;
    }

    const abis = [...new Set(...(abiFilters ?? abiList))]
      .map((abi) => `'${abi}'`)
      .join(", ");

    config.modResults.contents += `
            android {
              splits {
                abi {
                  enable true
                  reset()
                  include ${abis}
                  universalApk false
                }
              }
            }
        `;
    return config;
  });
}

Is there any way to see the resulting gradl file? Is this even the correct file? I also tried withProjectBuildGradle instead but that errored

Fuzzyma avatar Feb 20 '25 10:02 Fuzzyma

@Kudo / @lukmccall - do you think we should expose this through expo-build-properties?

@kadikraman shared a link to a discord thread where someone made a config plugin to accomplish this: https://discord.com/channels/695411232856997968/1370401592926535700/1370771024076996770

brentvatne avatar May 13 '25 17:05 brentvatne

is the request to split the APK into multiple APKs for users to download, rather than to optimize build time? that seems like a pretty niche use case.

if you’re talking about building a single apk with eas build using an environment variable, the easiest way is like:

$ export ORG_GRADLE_PROJECT_reactNativeArchitectures=x86_64

Kudo avatar May 14 '25 09:05 Kudo