mirror of
https://github.com/status-im/react-native.git
synced 2025-01-15 03:56:03 +00:00
9b9b6c845e
Summary:
The original proguard rules are put in the template, which is not very convenient and easy to get wrong. Because new rules get put, people also has two copy paste the rule. And there are also existing project import react native as a dependency. So the best way to keep a android library project proguard rule is to manage the rule itself, using `consumerProguardFiles` like [dagger](46baef6d96/butterknife/build.gradle (L9)
) and other android library project.
<!--
Required: Write your motivation here.
If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
-->
Use RNTester to build the release flavor (now it has bugs https://github.com/facebook/react-native/issues/18460, I keep my change in local for now), after build success, run to check if crash.
In the process, I also fix https://github.com/facebook/react-native/issues/12994 and https://github.com/facebook/react-native/issues/6624 by adding the following to proguard rules
```proguard
-keep,includedescriptorclasses class com.facebook.react.bridge.** { *; }
```
<!--
Does this PR require a documentation change?
Create a PR at https://github.com/facebook/react-native-website and add a link to it here.
-->
[ANDROID] [ENHANCEMENT and BUGFIX] [Proguard rules] - inline and fix proguard rules .
<!--
**INTERNAL and MINOR tagged notes will not be included in the next version's final release notes.**
CATEGORY
[----------] TYPE
[ CLI ] [-------------] LOCATION
[ DOCS ] [ BREAKING ] [-------------]
[ GENERAL ] [ BUGFIX ] [ {Component} ]
[ INTERNAL ] [ ENHANCEMENT ] [ {Filename} ]
[ IOS ] [ FEATURE ] [ {Directory} ] |-----------|
[ ANDROID ] [ MINOR ] [ {Framework} ] - | {Message} |
[----------] [-------------] [-------------] |-----------|
EXAMPLES:
[IOS] [BREAKING] [FlatList] - Change a thing that breaks other things
[ANDROID] [BUGFIX] [TextInput] - Did a thing to TextInput
[CLI] [FEATURE] [local-cli/info/info.js] - CLI easier to do things with
[DOCS] [BUGFIX] [GettingStarted.md] - Accidentally a thing/word
[GENERAL] [ENHANCEMENT] [Yoga] - Added new yoga thing/position
[INTERNAL] [FEATURE] [./scripts] - Added thing to script that nobody will see
-->
Closes https://github.com/facebook/react-native/pull/18461
Differential Revision: D7527533
Pulled By: hramos
fbshipit-source-id: 447dbc16983bcfb597187b40c1be3987a8c5a832
320 lines
13 KiB
Groovy
320 lines
13 KiB
Groovy
// Copyright 2015-present Facebook. All Rights Reserved.
|
|
|
|
apply plugin: 'com.android.library'
|
|
apply plugin: 'maven'
|
|
|
|
apply plugin: 'de.undercouch.download'
|
|
|
|
import de.undercouch.gradle.tasks.download.Download
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
import org.apache.tools.ant.filters.ReplaceTokens
|
|
|
|
// 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.1
|
|
// - folly-deprecate-dynamic-initializer
|
|
// - glog-0.3.3
|
|
// - jsc-headers
|
|
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")
|
|
|
|
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/v1.63.0-0/boost_1_63_0.tar.gz'
|
|
onlyIfNewer true
|
|
overwrite false
|
|
dest new File(downloadsDir, 'boost_1_63_0.tar.gz')
|
|
}
|
|
|
|
task prepareBoost(dependsOn: boostPath ? [] : [downloadBoost], type: Copy) {
|
|
from boostPath ?: tarTree(resources.gzip(downloadBoost.dest))
|
|
from 'src/main/jni/third-party/boost/Android.mk'
|
|
include 'Android.mk', 'boost_1_63_0/boost/**/*.hpp', 'boost/boost/**/*.hpp'
|
|
includeEmptyDirs = false
|
|
into "$thirdPartyNdkDir/boost"
|
|
doLast {
|
|
file("$thirdPartyNdkDir/boost/boost").renameTo("$thirdPartyNdkDir/boost/boost_1_63_0")
|
|
}
|
|
}
|
|
|
|
task downloadDoubleConversion(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src 'https://github.com/google/double-conversion/archive/v1.1.1.tar.gz'
|
|
onlyIfNewer true
|
|
overwrite false
|
|
dest new File(downloadsDir, 'double-conversion-1.1.1.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-1.1.1/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/v2016.09.26.00.tar.gz'
|
|
onlyIfNewer true
|
|
overwrite false
|
|
dest new File(downloadsDir, 'folly-2016.09.26.00.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-2016.09.26.00/folly/**/*', 'Android.mk'
|
|
eachFile {fname -> fname.path = (fname.path - "folly-2016.09.26.00/")}
|
|
includeEmptyDirs = false
|
|
into "$thirdPartyNdkDir/folly"
|
|
}
|
|
|
|
task downloadGlog(dependsOn: createNativeDepsDirectories, type: Download) {
|
|
src 'https://github.com/google/glog/archive/v0.3.3.tar.gz'
|
|
onlyIfNewer true
|
|
overwrite false
|
|
dest new File(downloadsDir, 'glog-0.3.3.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
|
|
task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy) {
|
|
from dependenciesPath ?: tarTree(downloadGlog.dest)
|
|
from 'src/main/jni/third-party/glog/'
|
|
include 'glog-0.3.3/src/**/*', 'Android.mk', 'config.h'
|
|
includeEmptyDirs = false
|
|
filesMatching('**/*.h.in') {
|
|
filter(ReplaceTokens, tokens: [
|
|
ac_cv_have_unistd_h: '1',
|
|
ac_cv_have_stdint_h: '1',
|
|
ac_cv_have_systypes_h: '1',
|
|
ac_cv_have_inttypes_h: '1',
|
|
ac_cv_have_libgflags: '0',
|
|
ac_google_start_namespace: 'namespace google {',
|
|
ac_cv_have_uint16_t: '1',
|
|
ac_cv_have_u_int16_t: '1',
|
|
ac_cv_have___uint16: '0',
|
|
ac_google_end_namespace: '}',
|
|
ac_cv_have___builtin_expect: '1',
|
|
ac_google_namespace: 'google',
|
|
ac_cv___attribute___noinline: '__attribute__ ((noinline))',
|
|
ac_cv___attribute___noreturn: '__attribute__ ((noreturn))',
|
|
ac_cv___attribute___printf_4_5: '__attribute__((__format__ (__printf__, 4, 5)))'
|
|
])
|
|
it.path = (it.name - '.in')
|
|
}
|
|
into "$thirdPartyNdkDir/glog"
|
|
}
|
|
|
|
task downloadJSCHeaders(type: Download) {
|
|
// in sync with webkit SVN revision 174650
|
|
def jscAPIBaseURL = 'https://raw.githubusercontent.com/WebKit/webkit/38b15a3ba3c1b0798f2036f7cea36ffdc096202e/Source/JavaScriptCore/API/'
|
|
def jscHeaderFiles = ['JavaScript.h', 'JSBase.h', 'JSContextRef.h', 'JSObjectRef.h', 'JSRetainPtr.h', 'JSStringRef.h', 'JSValueRef.h', 'WebKitAvailability.h']
|
|
def output = new File(downloadsDir, 'jsc')
|
|
output.mkdirs()
|
|
src(jscHeaderFiles.collect { headerName -> "$jscAPIBaseURL$headerName" })
|
|
onlyIfNewer true
|
|
overwrite false
|
|
dest output
|
|
}
|
|
|
|
// Create Android.mk library module based on so files from mvn + include headers fetched from webkit.org
|
|
task prepareJSC(dependsOn: dependenciesPath ? [] : [downloadJSCHeaders]) << {
|
|
copy {
|
|
from zipTree(configurations.compile.fileCollection { dep -> dep.name == 'android-jsc' }.singleFile)
|
|
from dependenciesPath ? "$dependenciesPath/jsc-headers" : {downloadJSCHeaders.dest}
|
|
from 'src/main/jni/third-party/jsc/Android.mk'
|
|
include 'jni/**/*.so', '*.h', 'Android.mk'
|
|
filesMatching('*.h', { fname -> fname.path = "JavaScriptCore/${fname.path}"})
|
|
into "$thirdPartyNdkDir/jsc";
|
|
}
|
|
}
|
|
|
|
task downloadNdkBuildDependencies {
|
|
if (!boostPath) {
|
|
dependsOn downloadBoost
|
|
}
|
|
dependsOn downloadDoubleConversion
|
|
dependsOn downloadFolly
|
|
dependsOn downloadGlog
|
|
dependsOn downloadJSCHeaders
|
|
}
|
|
|
|
def getNdkBuildName() {
|
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
return "ndk-build.cmd"
|
|
} else {
|
|
return "ndk-build"
|
|
}
|
|
}
|
|
|
|
def findNdkBuildFullPath() {
|
|
// we allow to provide full path to ndk-build tool
|
|
if (hasProperty('ndk.command')) {
|
|
return property('ndk.command')
|
|
}
|
|
// or just a path to the containing directory
|
|
if (hasProperty('ndk.path')) {
|
|
def ndkDir = property('ndk.path')
|
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
|
}
|
|
if (System.getenv('ANDROID_NDK') != null) {
|
|
def ndkDir = System.getenv('ANDROID_NDK')
|
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
|
}
|
|
def ndkDir = android.hasProperty('plugin') ? android.plugin.ndkFolder :
|
|
plugins.getPlugin('com.android.library').hasProperty('sdkHandler') ?
|
|
plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder() :
|
|
android.ndkDirectory.absolutePath
|
|
if (ndkDir) {
|
|
return new File(ndkDir, getNdkBuildName()).getAbsolutePath()
|
|
}
|
|
return null
|
|
}
|
|
|
|
def getNdkBuildFullPath() {
|
|
def ndkBuildFullPath = findNdkBuildFullPath()
|
|
if (ndkBuildFullPath == null) {
|
|
throw new GradleScriptException(
|
|
"ndk-build binary cannot be found, check if you've set " +
|
|
"\$ANDROID_NDK environment variable correctly or if ndk.dir is " +
|
|
"setup in local.properties",
|
|
null)
|
|
}
|
|
if (!new File(ndkBuildFullPath).canExecute()) {
|
|
throw new GradleScriptException(
|
|
"ndk-build binary " + ndkBuildFullPath + " doesn't exist or isn't executable.\n" +
|
|
"Check that the \$ANDROID_NDK environment variable, or ndk.dir in local.properties, is set correctly.\n" +
|
|
"(On Windows, make sure you escape backslashes in local.properties or use forward slashes, e.g. C:\\\\ndk or C:/ndk rather than C:\\ndk)",
|
|
null)
|
|
}
|
|
return ndkBuildFullPath
|
|
}
|
|
|
|
task buildReactNdkLib(dependsOn: [prepareJSC, prepareBoost, prepareDoubleConversion, prepareFolly, prepareGlog], type: Exec) {
|
|
inputs.file('src/main/jni/react')
|
|
outputs.dir("$buildDir/react-ndk/all")
|
|
commandLine getNdkBuildFullPath(),
|
|
'NDK_PROJECT_PATH=null',
|
|
"NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
|
|
'NDK_OUT=' + temporaryDir,
|
|
"NDK_LIBS_OUT=$buildDir/react-ndk/all",
|
|
"THIRD_PARTY_NDK_DIR=$buildDir/third-party-ndk",
|
|
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
|
|
'-C', file('src/main/jni/react/jni').absolutePath,
|
|
'--jobs', project.hasProperty("jobs") ? project.property("jobs") : Runtime.runtime.availableProcessors()
|
|
}
|
|
|
|
task cleanReactNdkLib(type: Exec) {
|
|
commandLine getNdkBuildFullPath(),
|
|
"NDK_APPLICATION_MK=$projectDir/src/main/jni/Application.mk",
|
|
"THIRD_PARTY_NDK_DIR=$buildDir/third-party-ndk",
|
|
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
|
|
'-C', file('src/main/jni/react/jni').absolutePath,
|
|
'clean'
|
|
}
|
|
|
|
task packageReactNdkLibs(dependsOn: buildReactNdkLib, type: Copy) {
|
|
from "$buildDir/react-ndk/all"
|
|
exclude '**/libjsc.so'
|
|
into "$buildDir/react-ndk/exported"
|
|
}
|
|
|
|
task packageReactNdkLibsForBuck(dependsOn: packageReactNdkLibs, type: Copy) {
|
|
from "$buildDir/react-ndk/exported"
|
|
into "src/main/jni/prebuilt/lib"
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion 23
|
|
buildToolsVersion "23.0.1"
|
|
|
|
defaultConfig {
|
|
minSdkVersion 16
|
|
targetSdkVersion 22
|
|
versionCode 1
|
|
versionName "1.0"
|
|
|
|
consumerProguardFiles 'proguard-rules.pro'
|
|
|
|
ndk {
|
|
moduleName "reactnativejni"
|
|
}
|
|
|
|
buildConfigField 'boolean', 'IS_INTERNAL_BUILD', 'false'
|
|
buildConfigField 'int', 'EXOPACKAGE_FLAGS', '0'
|
|
testApplicationId "com.facebook.react.tests.gradle"
|
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
|
}
|
|
|
|
sourceSets.main {
|
|
jni.srcDirs = []
|
|
jniLibs.srcDir "$buildDir/react-ndk/exported"
|
|
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'
|
|
}
|
|
}
|
|
|
|
tasks.withType(JavaCompile) {
|
|
compileTask -> compileTask.dependsOn packageReactNdkLibs
|
|
}
|
|
|
|
clean.dependsOn cleanReactNdkLib
|
|
|
|
lintOptions {
|
|
abortOnError false
|
|
}
|
|
packagingOptions {
|
|
exclude 'META-INF/NOTICE'
|
|
exclude 'META-INF/LICENSE'
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
compile fileTree(dir: 'src/main/third-party/java/infer-annotations/', include: ['*.jar'])
|
|
compile 'javax.inject:javax.inject:1'
|
|
compile 'com.android.support:appcompat-v7:23.0.1'
|
|
compile 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.0.0'
|
|
compile 'com.facebook.fresco:fresco:1.8.1'
|
|
compile 'com.facebook.fresco:imagepipeline-okhttp3:1.8.1'
|
|
compile 'com.facebook.soloader:soloader:0.3.0'
|
|
compile 'com.google.code.findbugs:jsr305:3.0.0'
|
|
compile 'com.squareup.okhttp3:okhttp:3.8.0'
|
|
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.8.0'
|
|
compile 'com.squareup.okio:okio:1.14.0'
|
|
compile 'org.webkit:android-jsc:r174650'
|
|
|
|
testCompile "junit:junit:${JUNIT_VERSION}"
|
|
testCompile "org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}"
|
|
testCompile "org.powermock:powermock-module-junit4-rule:${POWERMOCK_VERSION}"
|
|
testCompile "org.powermock:powermock-classloading-xstream:${POWERMOCK_VERSION}"
|
|
testCompile "org.mockito:mockito-core:${MOCKITO_CORE_VERSION}"
|
|
testCompile "org.easytesting:fest-assert-core:${FEST_ASSERT_CORE_VERSION}"
|
|
testCompile "org.robolectric:robolectric:${ROBOLECTRIC_VERSION}"
|
|
|
|
androidTestCompile fileTree(dir: 'src/main/third-party/java/buck-android-support/', include: ['*.jar'])
|
|
androidTestCompile 'com.android.support.test:runner:0.3'
|
|
androidTestCompile "org.mockito:mockito-core:${MOCKITO_CORE_VERSION}"
|
|
}
|
|
|
|
apply from: 'release.gradle'
|