mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
5a8033df98
On Windows there are limits on number of character in file paths and in command lines Ref: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#Path-Length-Limits NDK allows circumventing command line limits using response(RSP) files as inputs using NDK_APP_SHORT_COMMANDS flag. Windows can support long file paths if configured through registry or by prefixing all file paths with a special character sequence The latter requires changes in NDK. And there are tools in NDK (AR) which is not able to handle long paths (>256) even after setting the registry key. The new architecutre source tree is too deep, and the object file naming conventions in NDK makes the matters worse, by producing incredibly long file paths. Other solutions such as symlinking source code etc. didn't work as expected, and makes the build scripts complicated and hard to manage. This change temporarily works around the issue by placing the temporary build outputs as short a path as possible within the project path. Changelog: [Android] [Fixed] - Fix for building new architecture sources on Windows
488 lines
20 KiB
Groovy
488 lines
20 KiB
Groovy
/*
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
plugins {
|
|
id("com.android.library")
|
|
id("com.facebook.react")
|
|
id("maven-publish")
|
|
id("de.undercouch.download")
|
|
}
|
|
|
|
import com.facebook.react.tasks.internal.*
|
|
|
|
import java.nio.file.Paths
|
|
|
|
import de.undercouch.gradle.tasks.download.Download
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
import org.apache.tools.ant.filters.ReplaceTokens
|
|
|
|
def AAR_OUTPUT_URL = "file://${projectDir}/../android"
|
|
// We download various C++ open-source dependencies into downloads.
|
|
// We then copy both the downloaded code and our custom makefiles and headers into third-party-ndk.
|
|
// After that we build native code from src/main/jni with module path pointing at third-party-ndk.
|
|
|
|
def customDownloadsDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
|
|
def downloadsDir = customDownloadsDir ? new File(customDownloadsDir) : new File("$buildDir/downloads")
|
|
def thirdPartyNdkDir = new File("$buildDir/third-party-ndk")
|
|
|
|
// You need to have following folders in this directory:
|
|
// - boost_1_63_0
|
|
// - double-conversion-1.1.6
|
|
// - folly-deprecate-dynamic-initializer
|
|
// - glog-0.3.5
|
|
def dependenciesPath = System.getenv("REACT_NATIVE_DEPENDENCIES")
|
|
|
|
// The Boost library is a very large download (>100MB).
|
|
// If Boost is already present on your system, define the REACT_NATIVE_BOOST_PATH env variable
|
|
// and the build will use that.
|
|
def boostPath = dependenciesPath ?: System.getenv("REACT_NATIVE_BOOST_PATH")
|
|
|
|
// Setup build type for NDK, supported values: {debug, release}
|
|
def nativeBuildType = System.getenv("NATIVE_BUILD_TYPE") ?: "release"
|
|
|
|
task createNativeDepsDirectories {
|
|
downloadsDir.mkdirs()
|
|
thirdPartyNdkDir.mkdirs()
|
|
}
|
|
|
|
task downloadBoost(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/react-native-community/boost-for-react-native/releases/download/v${BOOST_VERSION.replace("_", ".")}-0/boost_${BOOST_VERSION}.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "boost_${BOOST_VERSION}.tar.gz"))
|
|
}
|
|
|
|
final def prepareBoost = tasks.register("prepareBoost", PrepareBoostTask) {
|
|
it.dependsOn(boostPath ? [] : [downloadBoost])
|
|
it.boostPath.setFrom(boostPath ?: tarTree(resources.gzip(downloadBoost.dest)))
|
|
it.boostVersion.set(BOOST_VERSION)
|
|
it.outputDir.set(new File(thirdPartyNdkDir, "boost"))
|
|
}
|
|
|
|
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/google/double-conversion/archive/v${DOUBLE_CONVERSION_VERSION}.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "double-conversion-${DOUBLE_CONVERSION_VERSION}.tar.gz"))
|
|
}
|
|
|
|
task prepareDoubleConversion(dependsOn: dependenciesPath ? [] : [downloadDoubleConversion], type: Copy) {
|
|
from(dependenciesPath ?: tarTree(downloadDoubleConversion.dest))
|
|
from("src/main/jni/third-party/double-conversion/Android.mk")
|
|
include("double-conversion-${DOUBLE_CONVERSION_VERSION}/src/**/*", "Android.mk")
|
|
filesMatching("*/src/**/*", { fname -> fname.path = "double-conversion/${fname.name}" })
|
|
includeEmptyDirs = false
|
|
into("$thirdPartyNdkDir/double-conversion")
|
|
}
|
|
|
|
task downloadFolly(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/facebook/folly/archive/v${FOLLY_VERSION}.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "folly-${FOLLY_VERSION}.tar.gz"))
|
|
}
|
|
|
|
task prepareFolly(dependsOn: dependenciesPath ? [] : [downloadFolly], type: Copy) {
|
|
from(dependenciesPath ?: tarTree(downloadFolly.dest))
|
|
from("src/main/jni/third-party/folly/Android.mk")
|
|
include("folly-${FOLLY_VERSION}/folly/**/*", "Android.mk")
|
|
eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
|
|
includeEmptyDirs = false
|
|
into("$thirdPartyNdkDir/folly")
|
|
}
|
|
|
|
task downloadFmt(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/fmtlib/fmt/archive/${FMT_VERSION}.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "fmt-${FMT_VERSION}.tar.gz"))
|
|
}
|
|
|
|
task prepareFmt(dependsOn: dependenciesPath ? [] : [downloadFmt], type: Copy) {
|
|
from(dependenciesPath ?: tarTree(downloadFmt.dest))
|
|
from("src/main/jni/third-party/fmt/Android.mk")
|
|
include("fmt-${FMT_VERSION}/src/**/*", "fmt-${FMT_VERSION}/include/**/*", "Android.mk")
|
|
eachFile { fname -> fname.path = (fname.path - "fmt-${FMT_VERSION}/") }
|
|
includeEmptyDirs = false
|
|
into("$thirdPartyNdkDir/fmt")
|
|
}
|
|
|
|
task downloadLibevent(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/libevent/libevent/releases/download/release-${LIBEVENT_VERSION}-stable/libevent-${LIBEVENT_VERSION}-stable.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "libevent-${LIBEVENT_VERSION}.tar.gz"))
|
|
}
|
|
|
|
|
|
final def prepareLibevent = tasks.register("prepareLibevent", PrepareLibeventTask) {
|
|
it.dependsOn(dependenciesPath ? [] : [downloadLibevent])
|
|
it.libeventPath.setFrom(dependenciesPath ?: tarTree(downloadLibevent.dest))
|
|
it.libeventVersion.set(LIBEVENT_VERSION)
|
|
it.outputDir.set(new File(thirdPartyNdkDir, "libevent"))
|
|
}
|
|
|
|
task prepareHermes(dependsOn: createNativeDepsDirectories, type: Copy) {
|
|
def hermesPackagePath = findNodeModulePath(projectDir, "hermes-engine")
|
|
if (!hermesPackagePath) {
|
|
throw new GradleScriptException("Could not find the hermes-engine npm package", null)
|
|
}
|
|
|
|
def hermesAAR = file("$hermesPackagePath/android/hermes-debug.aar")
|
|
if (!hermesAAR.exists()) {
|
|
throw new GradleScriptException("The hermes-engine npm package is missing \"android/hermes-debug.aar\"", null)
|
|
}
|
|
|
|
def soFiles = zipTree(hermesAAR).matching({ it.include "**/*.so" })
|
|
|
|
from soFiles
|
|
from "src/main/jni/first-party/hermes/Android.mk"
|
|
into "$thirdPartyNdkDir/hermes"
|
|
}
|
|
|
|
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src("https://github.com/google/glog/archive/v${GLOG_VERSION}.tar.gz")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "glog-${GLOG_VERSION}.tar.gz"))
|
|
}
|
|
|
|
// Prepare glog sources to be compiled, this task will perform steps that normally should've been
|
|
// executed by automake. This way we can avoid dependencies on make/automake
|
|
final def prepareGlog = tasks.register("prepareGlog", PrepareGlogTask) {
|
|
it.dependsOn(dependenciesPath ? [] : [downloadGlog])
|
|
it.glogPath.setFrom(dependenciesPath ?: tarTree(downloadGlog.dest))
|
|
it.glogVersion.set(GLOG_VERSION)
|
|
it.outputDir.set(new File(thirdPartyNdkDir, "glog"))
|
|
}
|
|
|
|
// Create Android.mk library module based on jsc from npm
|
|
tasks.register('prepareJSC', PrepareJSCTask) {
|
|
it.jscPackagePath.set(findNodeModulePath(projectDir, "jsc-android"))
|
|
it.outputDir = project.layout.buildDirectory.dir("third-party-ndk/jsc")
|
|
}
|
|
|
|
task downloadNdkBuildDependencies {
|
|
if (!boostPath) {
|
|
dependsOn(downloadBoost)
|
|
}
|
|
dependsOn(downloadDoubleConversion)
|
|
dependsOn(downloadFolly)
|
|
dependsOn(downloadGlog)
|
|
dependsOn(downloadFmt)
|
|
dependsOn(downloadLibevent)
|
|
}
|
|
|
|
/**
|
|
* Finds the path of the installed npm package with the given name using Node's
|
|
* module resolution algorithm, which searches "node_modules" directories up to
|
|
* the file system root. This handles various cases, including:
|
|
*
|
|
* - Working in the open-source RN repo:
|
|
* Gradle: /path/to/react-native/ReactAndroid
|
|
* Node module: /path/to/react-native/node_modules/[package]
|
|
*
|
|
* - Installing RN as a dependency of an app and searching for hoisted
|
|
* dependencies:
|
|
* Gradle: /path/to/app/node_modules/react-native/ReactAndroid
|
|
* Node module: /path/to/app/node_modules/[package]
|
|
*
|
|
* - Working in a larger repo (e.g., Facebook) that contains RN:
|
|
* Gradle: /path/to/repo/path/to/react-native/ReactAndroid
|
|
* Node module: /path/to/repo/node_modules/[package]
|
|
*
|
|
* The search begins at the given base directory (a File object). The returned
|
|
* path is a string.
|
|
*/
|
|
def findNodeModulePath(baseDir, packageName) {
|
|
def basePath = baseDir.toPath().normalize()
|
|
// Node's module resolution algorithm searches up to the root directory,
|
|
// after which the base path will be null
|
|
while (basePath) {
|
|
def candidatePath = Paths.get(basePath.toString(), "node_modules", packageName)
|
|
if (candidatePath.toFile().exists()) {
|
|
return candidatePath.toString()
|
|
}
|
|
basePath = basePath.getParent()
|
|
}
|
|
return null
|
|
}
|
|
|
|
|
|
def reactNativeDevServerPort() {
|
|
def value = project.getProperties().get("reactNativeDevServerPort")
|
|
return value != null ? value : "8081"
|
|
}
|
|
|
|
def reactNativeInspectorProxyPort() {
|
|
def value = project.getProperties().get("reactNativeInspectorProxyPort")
|
|
return value != null ? value : reactNativeDevServerPort()
|
|
}
|
|
|
|
def reactNativeArchitectures() {
|
|
def value = project.getProperties().get("reactNativeArchitectures")
|
|
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
}
|
|
|
|
def ndkBuildJobs() {
|
|
return project.findProperty("jobs") ?: Runtime.runtime.availableProcessors()
|
|
}
|
|
|
|
tasks.register("packageReactNdkLibsForBuck") {
|
|
dependsOn("packageReactNdkDebugLibsForBuck")
|
|
}
|
|
|
|
tasks.register("packageReactNdkDebugLibsForBuck", Copy) {
|
|
dependsOn("mergeDebugNativeLibs")
|
|
// Shared libraries (.so) are copied from the merged_native_libs folder instead
|
|
from("$buildDir/intermediates/merged_native_libs/debug/out/lib/")
|
|
exclude("**/libjsc.so")
|
|
exclude("**/libhermes.so")
|
|
into("src/main/jni/prebuilt/lib")
|
|
}
|
|
|
|
tasks.register("packageReactNdkReleaseLibsForBuck", Copy) {
|
|
dependsOn("mergeReleaseNativeLibs")
|
|
// Shared libraries (.so) are copied from the merged_native_libs folder instead
|
|
from("$buildDir/intermediates/merged_native_libs/release/out/lib/")
|
|
exclude("**/libjsc.so")
|
|
exclude("**/libhermes.so")
|
|
into("src/main/jni/prebuilt/lib")
|
|
}
|
|
|
|
final def extractNativeDependencies = tasks.register('extractNativeDependencies', ExtractJniAndHeadersTask) {
|
|
it.extractHeadersConfiguration.setFrom(configurations.extractHeaders)
|
|
it.extractJniConfiguration.setFrom(configurations.extractJNI)
|
|
it.baseOutputDir = project.file("src/main/jni/first-party/")
|
|
// Sadly this task as an output folder path that is directly dependent on
|
|
// the task input (i.e. src/main/jni/first-party/<package-name>/...
|
|
// This means that this task is using the parent folder (first-party/) as
|
|
// @OutputFolder. The `prepareHermes` task will also output inside that
|
|
// folder and if the two tasks happen to be inside the same run, we want
|
|
// `extractNativeDependencies` to run after `prepareHermes` to do not
|
|
// invalidate the input/output calculation for this task.
|
|
it.mustRunAfter(prepareHermes)
|
|
}
|
|
|
|
task installArchives {
|
|
dependsOn("publishReleasePublicationToNpmRepository")
|
|
}
|
|
|
|
// Creating sources with comments
|
|
task androidSourcesJar(type: Jar) {
|
|
classifier = 'sources'
|
|
from android.sourceSets.main.java.srcDirs
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion 31
|
|
|
|
// Used to override the NDK path & version on internal CI
|
|
if (System.getenv("ANDROID_NDK") != null && System.getenv("LOCAL_ANDROID_NDK_VERSION") != null) {
|
|
ndkPath System.getenv("ANDROID_NDK")
|
|
ndkVersion System.getenv("LOCAL_ANDROID_NDK_VERSION")
|
|
}
|
|
|
|
defaultConfig {
|
|
minSdkVersion(21)
|
|
targetSdkVersion(31)
|
|
versionCode(1)
|
|
versionName("1.0")
|
|
|
|
consumerProguardFiles("proguard-rules.pro")
|
|
|
|
buildConfigField("boolean", "IS_INTERNAL_BUILD", "false")
|
|
buildConfigField("int", "EXOPACKAGE_FLAGS", "0")
|
|
buildConfigField("int", "HERMES_BYTECODE_VERSION", "0")
|
|
|
|
resValue "integer", "react_native_dev_server_port", reactNativeDevServerPort()
|
|
resValue "integer", "react_native_inspector_proxy_port", reactNativeInspectorProxyPort()
|
|
|
|
testApplicationId("com.facebook.react.tests.gradle")
|
|
testInstrumentationRunner("androidx.test.runner.AndroidJUnitRunner")
|
|
|
|
externalNativeBuild {
|
|
ndkBuild {
|
|
arguments "NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
|
|
"THIRD_PARTY_NDK_DIR=$thirdPartyNdkDir",
|
|
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
|
|
"REACT_GENERATED_SRC_DIR=$buildDir/generated/source",
|
|
"REACT_SRC_DIR=$projectDir/src/main/java/com/facebook/react",
|
|
"-j${ndkBuildJobs()}"
|
|
|
|
if (Os.isFamily(Os.FAMILY_MAC)) {
|
|
// This flag will suppress "fcntl(): Bad file descriptor" warnings on local builds.
|
|
arguments "--output-sync=none"
|
|
}
|
|
|
|
// Note: On Windows there are limits on number of character in file paths and in command lines
|
|
// Ref: https://android.googlesource.com/platform/ndk/+/master/docs/BuildSystemMaintainers.md#Path-Length-Limits
|
|
// NDK allows circumventing command line limits using response(RSP) files as inputs using NDK_APP_SHORT_COMMANDS flag.
|
|
//
|
|
// Windows can support long file paths if configured through registry or by prefixing all file paths with a special character sequence
|
|
// The latter requires changes in NDK. And there are tools in NDK (AR) which is not able to handle long paths (>256) even after setting the registry key.
|
|
// The new architecutre source tree is too deep, and the object file naming conventions in NDK makes the matters worse, by producing incredibly long file paths.
|
|
// Other solutions such as symlinking source code etc. didn't work as expected, and makes the build scripts complicated and hard to manage.
|
|
// This change temporarily works around the issue by placing the temporary build outputs as short a path as possible within the project path.
|
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
arguments "NDK_OUT=${rootProject.projectDir.getParent()}\\.cxx",
|
|
"NDK_APP_SHORT_COMMANDS=true"
|
|
}
|
|
}
|
|
}
|
|
ndk {
|
|
abiFilters (*reactNativeArchitectures())
|
|
}
|
|
}
|
|
|
|
externalNativeBuild {
|
|
ndkBuild {
|
|
path "src/main/jni/react/jni/Android.mk"
|
|
}
|
|
}
|
|
|
|
preBuild.dependsOn(prepareJSC, prepareHermes, prepareBoost, prepareDoubleConversion, prepareFmt, prepareFolly, prepareGlog, prepareLibevent, extractNativeDependencies)
|
|
preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
|
|
|
sourceSets.main {
|
|
jni.srcDirs = []
|
|
res.srcDirs = ["src/main/res/devsupport", "src/main/res/shell", "src/main/res/views/modal", "src/main/res/views/uimanager"]
|
|
java {
|
|
srcDirs = ["src/main/java", "src/main/libraries/soloader/java", "src/main/jni/first-party/fb/jni/java"]
|
|
exclude("com/facebook/react/processing")
|
|
exclude("com/facebook/react/module/processing")
|
|
}
|
|
}
|
|
|
|
lintOptions {
|
|
abortOnError(false)
|
|
}
|
|
|
|
packagingOptions {
|
|
exclude("META-INF/NOTICE")
|
|
exclude("META-INF/LICENSE")
|
|
// We intentionally don't want to bundle any JS Runtime inside the Android AAR
|
|
// we produce. The reason behind this is that we want to allow users to pick the
|
|
// JS engine by specifying a dependency on either `hermes-engine` or `android-jsc`
|
|
// that will include the necessary .so files to load.
|
|
exclude("**/libhermes.so")
|
|
exclude("**/libjsc.so")
|
|
}
|
|
|
|
configurations {
|
|
extractHeaders
|
|
extractJNI
|
|
javadocDeps.extendsFrom api
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
api("com.facebook.infer.annotation:infer-annotation:0.18.0")
|
|
api("com.facebook.yoga:proguard-annotations:1.19.0")
|
|
api("javax.inject:javax.inject:1")
|
|
api("androidx.appcompat:appcompat:1.0.2")
|
|
api("androidx.autofill:autofill:1.1.0")
|
|
api("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
|
|
api("com.facebook.fresco:fresco:${FRESCO_VERSION}")
|
|
api("com.facebook.fresco:imagepipeline-okhttp3:${FRESCO_VERSION}")
|
|
api("com.facebook.fresco:ui-common:${FRESCO_VERSION}")
|
|
api("com.facebook.soloader:soloader:${SO_LOADER_VERSION}")
|
|
api("com.google.code.findbugs:jsr305:3.0.2")
|
|
api("com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}")
|
|
api("com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}")
|
|
api("com.squareup.okio:okio:2.9.0")
|
|
api("com.facebook.fbjni:fbjni-java-only:0.2.2")
|
|
extractHeaders("com.facebook.fbjni:fbjni:0.2.2:headers")
|
|
extractJNI("com.facebook.fbjni:fbjni:0.2.2")
|
|
|
|
javadocDeps("com.squareup:javapoet:1.13.0")
|
|
|
|
testImplementation("junit:junit:${JUNIT_VERSION}")
|
|
testImplementation("org.powermock:powermock-api-mockito2:${POWERMOCK_VERSION}")
|
|
testImplementation("org.powermock:powermock-module-junit4-rule:${POWERMOCK_VERSION}")
|
|
testImplementation("org.powermock:powermock-classloading-xstream:${POWERMOCK_VERSION}")
|
|
testImplementation("org.mockito:mockito-core:${MOCKITO_CORE_VERSION}")
|
|
testImplementation("org.assertj:assertj-core:3.21.0")
|
|
testImplementation("org.robolectric:robolectric:${ROBOLECTRIC_VERSION}")
|
|
|
|
androidTestImplementation(fileTree(dir: "src/main/third-party/java/buck-android-support/", include: ["*.jar"]))
|
|
androidTestImplementation("androidx.test:runner:${ANDROIDX_TEST_VERSION}")
|
|
androidTestImplementation("androidx.test:rules:${ANDROIDX_TEST_VERSION}")
|
|
androidTestImplementation("org.mockito:mockito-core:${MOCKITO_CORE_VERSION}")
|
|
}
|
|
|
|
react {
|
|
// TODO: The library name is chosen for parity with Fabric components & iOS
|
|
// This should be changed to a more generic name, e.g. `ReactCoreSpec`.
|
|
libraryName = "rncore"
|
|
jsRootDir = file("../Libraries")
|
|
reactNativeDir = file("$projectDir/..")
|
|
useJavaGenerator = System.getenv("USE_CODEGEN_JAVAPOET")?.toBoolean() ?: false
|
|
// We search for the codegen in either one of the `node_modules` folder or in the
|
|
// root packages folder (that's for when we build from source without calling `yarn install`).
|
|
codegenDir = file(findNodeModulePath(projectDir, "react-native-codegen") ?: "../packages/react-native-codegen/")
|
|
}
|
|
|
|
afterEvaluate {
|
|
|
|
// Needed as some of the native sources needs to be downloaded
|
|
// before configureNdkBuildDebug could be executed.
|
|
configureNdkBuildDebug.dependsOn(preBuild)
|
|
configureNdkBuildRelease.dependsOn(preBuild)
|
|
|
|
publishing {
|
|
publications {
|
|
release(MavenPublication) {
|
|
// Applies the component for the release build variant.
|
|
from components.release
|
|
|
|
// Add additional sourcesJar to artifacts
|
|
artifact(androidSourcesJar)
|
|
|
|
// You can then customize attributes of the publication as shown below.
|
|
artifactId = POM_ARTIFACT_ID
|
|
groupId = GROUP
|
|
version = VERSION_NAME
|
|
|
|
pom {
|
|
name = POM_NAME
|
|
description = "A framework for building native apps with React"
|
|
url = "https://github.com/facebook/react-native"
|
|
|
|
developers {
|
|
developer {
|
|
id = "facebook"
|
|
name = "Facebook"
|
|
}
|
|
}
|
|
|
|
licenses {
|
|
license {
|
|
name = "MIT License"
|
|
url = "https://github.com/facebook/react-native/blob/HEAD/LICENSE"
|
|
distribution = "repo"
|
|
}
|
|
}
|
|
|
|
scm {
|
|
url = "https://github.com/facebook/react-native.git"
|
|
connection = "scm:git:https://github.com/facebook/react-native.git"
|
|
developerConnection = "scm:git:git@github.com:facebook/react-native.git"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
repositories {
|
|
maven {
|
|
name = "npm"
|
|
url = AAR_OUTPUT_URL
|
|
}
|
|
}
|
|
}
|
|
}
|