From 962437fafd02c936754d1e992479056577cafd05 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Thu, 9 May 2019 04:14:55 -0700 Subject: [PATCH] Fix duplicate resource error in Android gradle build (#22234) (#24518) Summary: Issue #22234 includes a number of people (myself included) suffering with duplicate resource errors while building in Android. We have been collectively using a patch there but I don't believe any attempt has been made to PR it upstream. I am not excellent at gradle, so I may have approached this in completely the wrong way, but it works for me in the standard init templates, as well as my current work project which has a complicated 2 buildType + 4 productFlavor configuration. If there is a better way to achieve the result I am happy to learn The approach here is to determine the generated path the resources land in, then move them into the main build output tree. If they remain in the generated path android merging fails with duplicate resource errors, so that move (vs copy) is important. [Android] [Fixed] - Fix duplicate resource error in Android build Pull Request resolved: https://github.com/facebook/react-native/pull/24518 Differential Revision: D15276981 Pulled By: cpojer fbshipit-source-id: 3fe8c8556e4dcdac5f96a2d4658ac9b5d9b67379 --- react.gradle | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/react.gradle b/react.gradle index 11b3465e5..488ebd624 100644 --- a/react.gradle +++ b/react.gradle @@ -48,6 +48,32 @@ afterEvaluate { resourcesDir.mkdirs() } + + // If there are flavors, remember the current flavor for use in the resource path we move from + def flavorPathSegment = "" + android.productFlavors.all { flavor -> + if (targetName.toLowerCase().contains(flavor.name)) { + flavorPathSegment = flavor.name + "/" + } + } + + // Address issue #22234 by moving generated resources into build dir so they are in one spot, not duplicated + doLast { + def moveFunc = { resSuffix -> + File originalDir = file("$buildDir/generated/res/react/${flavorPathSegment}release/drawable-${resSuffix}") + if (originalDir.exists()) { + File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}") + ant.move(file: originalDir, tofile: destDir); + } + } + moveFunc.curry("ldpi").call() + moveFunc.curry("mdpi").call() + moveFunc.curry("hdpi").call() + moveFunc.curry("xhdpi").call() + moveFunc.curry("xxhdpi").call() + moveFunc.curry("xxxhdpi").call() + } + // Set up inputs and outputs so gradle can cache the result inputs.files fileTree(dir: reactRoot, excludes: inputExcludes) outputs.dir(jsBundleDir)