• Stars
    star
    1,056
  • Rank 43,682 (Top 0.9 %)
  • Language
    JavaScript
  • License
    BSD 2-Clause "Sim...
  • Created over 7 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Script for building JavaScriptCore for Android (for React Native but not only)

npm version GitHub Actions CI

JSC build scripts for Android

The aim of this project is to provide maintainable build scripts for the JavaScriptCore JavaScript engine and allow the React Native project to incorporate up-to-date releases of JSC into the framework on Android.

This project is based on facebook/android-jsc but instead of rewriting JSC's build scripts into BUCK files, it relies on CMake build scripts maintained in a GTK branch of WebKit maintained by the WebKitGTK team (great work btw!). Thanks to that, with just a small amount of work we should be able to build not only current but also future releases of JSC. An obvious benefit for everyone using React Native is that this will allow us to update JSC for React Native on Android much more often than before (note that facebook/android-jsc uses JSC version from Nov 2014), which is especially helpful since React Native on iOS uses the built-in copy of JSC that is updated with each major iOS release (see this as a reference).

Requirements

  • Homebrew (https://brew.sh/)
  • GNU coreutils brew install coreutils
  • Node brew install node
  • Java 8: brew tap caskroom/versions && brew cask install java8
  • Android SDK: brew cask install android-sdk
    • Run sdkmanager --list and install all platforms, tools, buildtool v28.0.3, cmake (android images are not needed)
    • Set $ANDROID_HOME to the correct path (in ~/.bashrc or similar)
    • Set export PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/tools/bin
  • Android NDK r19c: download from NDK Archives
    • Set export ANDROID_NDK=/path/to/android-ndk-r19c
  • Make sure you have Ruby (>2.3), Python (>2.7), Git, SVN, gperf

Build instructions

  1. Clone this repo
  2. npm run clean will clean everything (artifacts, downloaded sources)
  3. Update the version in package.json. The version will be printed by JSC lib as soon as it loads.
  4. Update the config section under package.json to the desired build configuration
  5. Update patches if needed (don't forget to update the printVersion patch in jsc.patch)
  6. npm run download: downloads all needed sources
  7. npm run start: builds jsc (this might take some time...)

The zipfile containing the android-jsc AAR will be available at /dist. The library is packaged as a local Maven repository containing AAR files that include the binaries.

Distribution

JSC library built using this project is distributed over npm: npm/jsc-android. The library is packaged as a local Maven repository containing AAR files that include the binaries. Please refer to the section below in order to learn how your app can consume this format.

On load, JSC prints the version out to logcat, under "JavaScriptCore.Version" tag.

How to use it with my React Native app

Follow steps below in order for your React Native app to use new version of JSC VM on android:

For React Native version 0.60 and newer

  1. Update jsc-android:
yarn add jsc-android

# Or if you would like to try latest version
# yarn add 'jsc-android@next'

  1. You're done, rebuild your app and enjoy updated version of JSC on android!

For React Native version 0.59

  1. Add jsc-android:
yarn add jsc-android

# Or if you would like to try latest version
# yarn add 'jsc-android@next'

  1. Modify android/build.gradle file to add the new local maven repository packaged in the jsc-android package to the search path:
allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
+       maven {
+           // Local Maven repo containing AARs with JSC library built for Android
+           url "$rootDir/../node_modules/jsc-android/dist"
+       }
    }
}
  1. Update your app's build.gradle file located in android/app/build.gradle to add the JSC dependency. Please make sure the dependency is before the React Native dependency.
dependencies {
+   // Make sure to put android-jsc at the top
+   implementation "org.webkit:android-jsc:+"
+
    compile fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
}
  1. Update your app's build.gradle file located in android/app/build.gradle to use first matched JSC library.
android {
    // ...
+   packagingOptions {
+       pickFirst '**/libjsc.so'
+       pickFirst '**/libc++_shared.so'
+    }
}
  1. You're done - rebuild your app and enjoy the updated version of JSC on Android!

For React Native version 0.58 below

  1. Add jsc-android:
yarn add jsc-android

# Or if you would like to try latest version
# yarn add 'jsc-android@next'

  1. Modify android/build.gradle file to add new local maven repository packaged in the jsc-android package to the search path:
allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
+       maven {
+           // Local Maven repo containing AARs with JSC library built for Android
+           url "$rootDir/../node_modules/jsc-android/dist"
+       }
    }
}
  1. Update your app's build.gradle file located in android/app/build.gradle to force app builds to use new version of the JSC library as opposed to the version specified in react-native gradle module as a dependency:
}

+configurations.all {
+    resolutionStrategy {
+        force 'org.webkit:android-jsc:+'
+    }
+}

dependencies {
    compile fileTree(dir: "libs", include: ["*.jar"])
+   // ...
+   implementation 'org.webkit:android-jsc-cppruntime:+'
+   // For even older gradle
+   // compile 'org.webkit:android-jsc-cppruntime:+'
  1. You're done, rebuild your app and enjoy updated version of JSC on android!

International variant

International variant includes ICU i18n library and necessary data allowing to use e.g. Date.toLocaleString and String.localeCompare that give correct results when using with locales other than en-US. Note that this variant is about 6MiB larger per architecture than default.

To use this variant instead replace the third installation step with:

For React Native version 0.60 and newer, your build.gradle should have a flag to enable this feature.

  /**
   * Use the international variant of JavaScriptCore
   * This variant includes the ICU i18n library to make APIs like `Date.toLocaleString`
   * and `String.localeCompare` work when using with locales other than en-US.
   * Note that this variant is about 6MiB larger per architecture than the default.
   */
-  def useIntlJsc = false
+  def useIntlJsc = true

For React Native version 0.59, replace original artifact id with android-jsc-intl

dependencies {
+   // Make sure to put android-jsc at the the first
+   implementation "org.webkit:android-jsc-intl:+"
+
    compile fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
}

For React Native version 0.58 below, replace original resolutionStrategy with this.

+configurations.all {
+    resolutionStrategy {
+        eachDependency { DependencyResolveDetails details ->
+            if (details.requested.name == 'android-jsc') {
+                details.useTarget group: details.requested.group, name: 'android-jsc-intl', version: 'r241213'
+            }
+        }
+    }
+}

Testing

See Measurements page that contains synthetic perf test results for the most notable versions of JSC we have tried.

Troubleshooting

Compile errors of the sort:

More than one file was found with OS independent path 'lib/armeabi-v7a/libgnustl_shared.so'

Add the following to your app/build.gradle, under android:

packagingOptions {
    pickFirst '**/libgnustl_shared.so'
}

Resources

Credits

Check the list of contributors here. This project is supported by:

expo Expo.io

swm Software Mansion

wix Wix

More Repositories

1

upgrade-helper

⚛️ A web tool to support React Native developers in upgrading their apps.
TypeScript
3,628
star
2

hooks

React Native APIs turned into React Hooks for use in functional React components
TypeScript
3,451
star
3

cli

The React Native Community CLI - command line tools to help you build RN apps
TypeScript
2,374
star
4

react-native-template-typescript

👾 Clean and minimalist React Native template for a quick start with TypeScript.
Java
1,858
star
5

discussions-and-proposals

Discussions and proposals related to the main React Native project
1,684
star
6

releases

React Native releases
JavaScript
1,501
star
7

rn-diff-purge

Easier React Native upgrades by clearly exposing changes from a version to another. 🚀 And what better way than to purge, init, then diff? Spoiler: there's no better way. 😎
Shell
1,266
star
8

directory

A searchable and filterable directory of React Native libraries.
TypeScript
1,003
star
9

docker-android

Android Docker Image for React Native and common android development.
Dockerfile
473
star
10

RNNewArchitectureLibraries

A collection of sample React Native Libraries that will show you how to use the New Architecture (Fabric & TurboModules) step-by-step.
322
star
11

upgrade-support

A central community-backed place to request and give help when upgrading your app.
JavaScript
254
star
12

RNNewArchitectureApp

A collection of sample React Native Apps that will show you how to use the New Architecture (Fabric & TurboModules) step-by-step.
201
star
13

react-native-circleci-orb

A CircleCI Orb to Simplify Testing your React Native App
174
star
14

hermes-profile-transformer

TypeScript tool for converting Hermes Sampling Profiler output to Chrome Dev Tools format
TypeScript
86
star
15

boost-for-react-native

The Boost C++ library source code used to build React Native from source
C++
86
star
16

template

The React Native Community Template - getting started building RN apps for Android & iOS
JavaScript
46
star
17

eslint-plugin-react-native-globals

ESLint Environment for React Native
JavaScript
38
star
18

reproducer-react-native

A reproducer to easily recreate bugs and report problems for React Native
TypeScript
32
star
19

developer-experience-wg

Discussions-only repo for topics around React Developer Experience
18
star
20

rn-diff-lib-purge

Easier React Native library upgrades by clearly exposing changes from a version to another. 🚀 And what better way than to purge, init, then diff? Spoiler: there's no better way. 😎
Shell
3
star