Skip to content

Commit

Permalink
Use latest JavaScriptCore from npm
Browse files Browse the repository at this point in the history
Summary:
- Use `latest` jsc-android from npm (devDependency of react-native)
- Use clang instead of the deprecated gcc
- Use libc++ instead of the deprecated gnustl
- Updated gradle and android plugin version
- Fixed missing arch in local-cli template
- `clean` task should now always succeed
- `clean` task deletes build artifacts
- No need to specify buildToolsVersion. It's derived.
- Elvis operator for more readable code

Differential Revision: D13004499

fbshipit-source-id: 808d10eb9963ed7fefc6f0c242d5a53012ca0759
  • Loading branch information
DanielZlotin authored and facebook-github-bot committed Nov 25, 2018
1 parent f2894e5 commit ab8148a
Show file tree
Hide file tree
Showing 17 changed files with 113 additions and 94 deletions.
1 change: 0 additions & 1 deletion RNTester/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ def enableProguardInReleaseBuilds = true

android {
compileSdkVersion 27
buildToolsVersion "27.0.3"

defaultConfig {
applicationId "com.facebook.react.uiapp"
Expand Down
146 changes: 86 additions & 60 deletions ReactAndroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ plugins {
import de.undercouch.gradle.tasks.download.Download
import org.apache.tools.ant.taskdefs.condition.Os
import org.apache.tools.ant.filters.ReplaceTokens
import groovy.json.JsonSlurper

// 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.
Expand Down Expand Up @@ -68,7 +69,7 @@ task prepareDoubleConversion(dependsOn: dependenciesPath ? [] : [downloadDoubleC
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}"})
filesMatching('*/src/**/*', { fname -> fname.path = "double-conversion/${fname.name}" })
includeEmptyDirs = false
into "$thirdPartyNdkDir/double-conversion"
}
Expand All @@ -84,17 +85,17 @@ 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}/")}
eachFile { fname -> fname.path = (fname.path - "folly-${FOLLY_VERSION}/") }
includeEmptyDirs = false

// Patch for folly build break on gcc 4.9 and could be removed after build by clang
filesMatching('**/container/detail/F14Policy.h') {
filter(ReplaceTokens, tokens: [
'ObjectHolder(Args&&... args) : value_{std::forward<Args>(args)...} {}': 'ObjectHolder(Args&&... args) : value_({std::forward<Args>(args)...}) {}',
'ObjectHolder(Args&&... args) : T{std::forward<Args>(args)...} {}': 'ObjectHolder(Args&&... args) : T({std::forward<Args>(args)...}) {}',
'ObjectHolder(Args&&... args) : value_{std::forward<Args>(args)...} {}': 'ObjectHolder(Args&&... args) : value_({std::forward<Args>(args)...}) {}',
'ObjectHolder(Args&&... args) : T{std::forward<Args>(args)...} {}' : 'ObjectHolder(Args&&... args) : T({std::forward<Args>(args)...}) {}',
],
beginToken: '',
endToken: '')
beginToken: '',
endToken: '')
}

into "$thirdPartyNdkDir/folly"
Expand All @@ -116,20 +117,20 @@ task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy)
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_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')
Expand All @@ -145,40 +146,61 @@ task prepareGlog(dependsOn: dependenciesPath ? [] : [downloadGlog], type: Copy)
}
}

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', 'JSStringRef.h', 'JSValueRef.h', 'WebKitAvailability.h']
def output = new File(downloadsDir, 'jsc')
output.mkdirs()
src(jscHeaderFiles.collect { headerName -> "$jscAPIBaseURL$headerName" })
def readFromCommandLine(String cmd) {
new ByteArrayOutputStream().withStream { os ->
exec {
standardOutput os
commandLine cmd.split(" ")
}.assertNormalExitValue()
return os.toString().trim()
}
}

def isIdeBuild() {
return project.properties['android.injected.invoked.from.ide'] == 'true'
}

task downloadJSC(dependsOn: createNativeDepsDirectories, type: Download) {
if (isIdeBuild()) return

def packageJson = new JsonSlurper().parse(file("${rootDir}/package.json"))
def jscVersionName = packageJson.devDependencies["jsc-android"]
def jscVersion = readFromCommandLine("npm info jsc-android@$jscVersionName version")
def url = readFromCommandLine("npm info jsc-android@$jscVersionName dist.tarball")
src "$url"
onlyIfNewer true
overwrite false
dest output
dest new File(downloadsDir, "jsc-${jscVersion}.tar.gz")
}

// Create Android.mk library module based on so files from mvn + include headers fetched from webkit.org
task prepareJSC(dependsOn: dependenciesPath ? [] : [downloadJSCHeaders]) {
doLast {
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'
include 'jni/**/*.so', '*.h', 'Android.mk'
filesMatching('*.h', { fname -> fname.path = "JavaScriptCore/${fname.path}"})
into "$thirdPartyNdkDir/jsc";
}
// Create Android.mk library module based on jsc from npm
task prepareJSC(dependsOn: downloadJSC) << {
copy {
def jscTar = tarTree(downloadJSC.dest)
def jscAAR = jscTar.matching({ it.include "**/android-jsc/**/*.aar" }).singleFile
def soFiles = zipTree(jscAAR).matching({ it.include "**/*.so" })

def headerFiles = jscTar.matching({ it.include "**/include/*.h" })

from soFiles
from headerFiles
from "src/main/jni/third-party/jsc/Android.mk"

filesMatching("**/*.h", { it.path = "JavaScriptCore/${it.name}"})

includeEmptyDirs false
into "$thirdPartyNdkDir/jsc"
}
}

task downloadNdkBuildDependencies {
if (!boostPath) {
dependsOn downloadBoost
}
dependsOn downloadDoubleConversion
dependsOn downloadFolly
dependsOn downloadGlog
dependsOn downloadJSCHeaders
if (!boostPath) {
dependsOn downloadBoost
}
dependsOn downloadDoubleConversion
dependsOn downloadFolly
dependsOn downloadGlog
dependsOn downloadJSC
}

def getNdkBuildName() {
Expand Down Expand Up @@ -217,23 +239,23 @@ 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)
"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)
"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.dir('src/main/jni/react')
inputs.file('src/main/jni/react')
outputs.dir("$buildDir/react-ndk/all")
commandLine getNdkBuildFullPath(),
'NDK_PROJECT_PATH=null',
Expand All @@ -244,21 +266,27 @@ task buildReactNdkLib(dependsOn: [prepareJSC, prepareBoost, prepareDoubleConvers
"REACT_COMMON_DIR=$projectDir/../ReactCommon",
"REACT_SRC_DIR=$projectDir/src/main/java/com/facebook/react",
'-C', file('src/main/jni/react/jni').absolutePath,
'--jobs', project.hasProperty("jobs") ? project.property("jobs") : Runtime.runtime.availableProcessors()
'--jobs', project.findProperty("jobs") ?: Runtime.runtime.availableProcessors()
}

task cleanReactNdkLib(type: Exec) {
ignoreExitValue true
errorOutput new ByteArrayOutputStream()
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'
doLast {
file(AAR_OUTPUT_URL).delete()
println "Deleted aar output dir at ${file(AAR_OUTPUT_URL)}"
}
}

task packageReactNdkLibs(dependsOn: buildReactNdkLib, type: Copy) {
from "$buildDir/react-ndk/all"
exclude '**/libjsc.so'
from "$thirdPartyNdkDir/jsc/jni"
into "$buildDir/react-ndk/exported"
}

Expand All @@ -269,7 +297,6 @@ task packageReactNdkLibsForBuck(dependsOn: packageReactNdkLibs, type: Copy) {

android {
compileSdkVersion 27
buildToolsVersion "27.0.3"

defaultConfig {
minSdkVersion 16
Expand All @@ -291,7 +318,7 @@ android {

sourceSets.main {
jni.srcDirs = []
jniLibs.srcDirs = ["$buildDir/react-ndk/exported", 'src/main/jni/third-party/jsc/jni']
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']
Expand Down Expand Up @@ -326,7 +353,6 @@ dependencies {
api "com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}"
api "com.squareup.okhttp3:okhttp-urlconnection:${OKHTTP_VERSION}"
api 'com.squareup.okio:okio:1.14.0'
compile 'org.webkit:android-jsc:r174650'

testImplementation "junit:junit:${JUNIT_VERSION}"
testImplementation "org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}"
Expand Down
12 changes: 8 additions & 4 deletions ReactAndroid/release.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
apply plugin: 'maven'
apply plugin: 'signing'

ext {
AAR_OUTPUT_URL = "file://${projectDir}/../android"
}

// Gradle tasks for publishing to maven
// 1) To install in local maven repo use :installArchives task
// 2) To upload artifact to maven central use: :uploadArchives (you'd need to have the permission to do that)
Expand All @@ -15,15 +19,15 @@ def isReleaseBuild() {
}

def getRepositoryUrl() {
return project.hasProperty('repositoryUrl') ? property('repositoryUrl') : 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
return project.findProperty('repositoryUrl') ?: 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
}

def getRepositoryUsername() {
return project.hasProperty('repositoryUsername') ? property('repositoryUsername') : ''
return project.findProperty('repositoryUsername') ?: ''
}

def getRepositoryPassword() {
return project.hasProperty('repositoryPassword') ? property('repositoryPassword') : ''
return project.findProperty('repositoryPassword') ?: ''
}

def configureReactNativePom(def pom) {
Expand Down Expand Up @@ -128,7 +132,7 @@ afterEvaluate { project ->
configuration = configurations.archives
repositories.mavenDeployer {
// Deploy to react-native/android, ready to publish to npm
repository url: "file://${projectDir}/../android"
repository url: AAR_OUTPUT_URL

configureReactNativePom pom
}
Expand Down
4 changes: 2 additions & 2 deletions ReactAndroid/src/main/jni/Application.mk
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ APP_MK_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
# etc.) are defined inside build.gradle.
NDK_MODULE_PATH := $(APP_MK_DIR)$(HOST_DIRSEP)$(THIRD_PARTY_NDK_DIR)$(HOST_DIRSEP)$(REACT_COMMON_DIR)$(HOST_DIRSEP)$(APP_MK_DIR)first-party$(HOST_DIRSEP)$(REACT_SRC_DIR)

APP_STL := gnustl_shared
APP_STL := c++_shared

# Make sure every shared lib includes a .note.gnu.build-id header
APP_CFLAGS := -Wall -Werror
APP_CPPFLAGS := -std=c++1y
APP_LDFLAGS := -Wl,--build-id

NDK_TOOLCHAIN_VERSION := 4.9
NDK_TOOLCHAIN_VERSION := clang
2 changes: 1 addition & 1 deletion ReactAndroid/src/main/jni/react/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)
# ./../ == react
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../..

LOCAL_CFLAGS += -fexceptions -frtti
LOCAL_CFLAGS += -fexceptions -frtti -Wno-unused-lambda-capture

LOCAL_LDLIBS += -landroid

Expand Down
1 change: 1 addition & 0 deletions ReactAndroid/src/main/jni/third-party/folly/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ FOLLY_FLAGS := \
-DFOLLY_NO_CONFIG=1 \
-DFOLLY_HAVE_CLOCK_GETTIME=1 \
-DFOLLY_HAVE_MEMRCHR=1 \
-DFOLLY_USE_LIBCPP=1

# If APP_PLATFORM in Application.mk targets android-23 above, please comment this line.
# NDK uses GNU style stderror_r() after API 23.
Expand Down
3 changes: 2 additions & 1 deletion ReactAndroid/src/main/jni/third-party/glog/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ LOCAL_CFLAGS += \
-g \
-O2 \
-D_START_GOOGLE_NAMESPACE_="namespace google {" \
-D_END_GOOGLE_NAMESPACE_="}"
-D_END_GOOGLE_NAMESPACE_="}" \
-DHAVE_PREAD=1


LOCAL_MODULE := glog
Expand Down
2 changes: 1 addition & 1 deletion ReactCommon/cxxreact/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
LOCAL_CFLAGS := \
-DLOG_TAG=\"ReactNative\"

LOCAL_CFLAGS += -fexceptions -frtti
LOCAL_CFLAGS += -fexceptions -frtti -Wno-unused-lambda-capture

LOCAL_STATIC_LIBRARIES := boost
LOCAL_SHARED_LIBRARIES := jsinspector libfolly_json glog
Expand Down
7 changes: 1 addition & 6 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'de.undercouch:gradle-download-task:3.4.3'

// NOTE: Do not place your application dependencies here; they belong
Expand All @@ -30,8 +30,3 @@ allprojects {
}
}
}

task wrapper(type: Wrapper) {
gradleVersion = '4.4'
distributionUrl = distributionUrl.replace("bin", "all")
}
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
5 changes: 0 additions & 5 deletions gradlew.bat
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
:: Copyright (c) 2015-present, Facebook, Inc.
::
:: This source code is licensed under the MIT license found in the
:: LICENSE file in the root directory of this source tree.

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
Expand Down
Loading

0 comments on commit ab8148a

Please sign in to comment.