EAS build fails for Android: Execution failed for task ':app:mergeReleaseNativeLibs'

Hi

I ran into this error when trying to get an app that uses react-native-ffmpeg to build. I managed to work out how to write a config plugin to resolve this based on @charliecruzan’s message. My config plugin assumes that there are no other config plugins that are also modifying the packagingOptions in the android/app/build.gradle.

Create a new file with the following contents:

plugins/withAndroidPickFirst.js:

const { withAppBuildGradle, withPlugins } = require("@expo/config-plugins");

function addPickFirst(buildGradle, paths) {
  const regexpPackagingOptions = /\bpackagingOptions\s*{[^}]*}/;
  const packagingOptionsMatch = buildGradle.match(regexpPackagingOptions);

  let bodyLines = [];
  paths.forEach((path) => {
    bodyLines.push(`        pickFirst '${path}'`);
  });
  let body = bodyLines.join("\n");

  if (packagingOptionsMatch) {
    console.warn("WARN: withAndroidPickFirst: Replacing packagingOptions in app build.gradle");
    return buildGradle.replace(
      regexpPackagingOptions,
      `packagingOptions {
${body}
    }`
    );
  }

  const regexpAndroid = /\nandroid\s*{/;
  const androidMatch = buildGradle.match(regexpAndroid);

  if (androidMatch) {
    return buildGradle.replace(
      regexpAndroid,
      `
android {
    packagingOptions {
${body}
    }`
    );
  }

  throw new Error("withAndroidPickFirst: Could not find where to add packagingOptions");
}

module.exports = (config, props = {}) => {
  if (!props.paths) {
    throw new Error("withAndroidPickFirst: No paths specified!");
  }
  return withAppBuildGradle(config, (config) => {
    if (config.modResults.language === "groovy") {
      config.modResults.contents = addPickFirst(config.modResults.contents, props.paths);
    } else {
      throw new Error("withAndroidPickFirst: Can't add pickFirst(s) because app build.grandle is not groovy");
    }
    return config;
  });
};

Then add it to your plugins in app.json and specify the libraries that you see in your build logs in the paths. If you’re building a dev client it might complain about lib/x86/libfbjni.so, but you should use ** instead of x86 so that it applies to x86_64 and the different arm architectures as well:

app.json:

[...]
    "plugins": [
      [
        "./plugins/withAndroidPickFirst",
        {
          "paths": ["lib/**/libfbjni.so", "lib/**/libc++_shared.so"]
        }
      ]
    ]
[...]
1 Like