Skip to content

Commit

Permalink
[core] fix androidTest build issues (#19469)
Browse files Browse the repository at this point in the history
# Why

a couple of issues i find when investigating the jsc problem in #19411

# How

- from #19372 and #19447, i noticed the androidTest running from bare-expo is crashing. the crash is libc++_shared.so not found. when i try to use `pickFirsts` to fix that, there's another `__emutls_get_address` symbol not found crashing issue. that happens because i build ReactAndroid by ndk r24, but expo-modules-core by ndk r21 (the default side-by-side ndk version in the current AGP). so the first addressing issue is to align the ndk version with the root project.
- support hermes building on react-native 0.70 without building from source. close ENG-6598
- use static c++ runtime for androidTest
  - this is the most complicated stuff. when running `et android-native-unit-tests -t instrumented`, it executes multiple androidTest commands together, e.g. `./gradlew :expo-modules-core:connectedAndroidTest :expo-eas-client:connectedAndroidTest`. if we use `pickFirsts` strategy, it will have multiple libc++_shared.so error when building expo-eas-client androidTest, one from e-m-c, and the other from ReactAndroid. so maybe the easy solution is to have static c++ runtime for androidTest.

# Test Plan

after these changes, the androidTest will fail both on jsc and hermes. to test everything works, i have to comment out other broken tests: `JSIFunctionTest.coded_error_should_be_converted` and `JSIFunctionTest.arbitrary_error_should_be_converted`

- ✅ [bare-expo] `./gradlew :expo-modules-core:connectedAndroidTest :expo-eas-client:connectedAndroidTest`
- ✅ [bare-expo] `./gradlew :expo-modules-core:connectedAndroidTest`
- ✅ [bare-expo] `./gradlew :expo-eas-client:connectedAndroidTest`
- ✅ [android expo go] `./gradlew :expo-modules-core:connectedAndroidTest :expo-eas-client:connectedAndroidTest`
- ✅ [android expo go] `./gradlew :expo-modules-core:connectedAndroidTest`
- ✅ [android expo go] `./gradlew :expo-eas-client:connectedAndroidTest`
  • Loading branch information
Kudo committed Oct 10, 2022
1 parent 74e3651 commit e9bd9a9
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 11 deletions.
7 changes: 7 additions & 0 deletions packages/expo-av/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ afterEvaluate {
android {
compileSdkVersion safeExtGet("compileSdkVersion", 31)

if (rootProject.hasProperty("ndkPath")) {
ndkPath rootProject.ext.ndkPath
}
if (rootProject.hasProperty("ndkVersion")) {
ndkVersion rootProject.ext.ndkVersion
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
Expand Down
7 changes: 7 additions & 0 deletions packages/expo-gl/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ afterEvaluate {
android {
compileSdkVersion safeExtGet("compileSdkVersion", 31)

if (rootProject.hasProperty("ndkPath")) {
ndkPath rootProject.ext.ndkPath
}
if (rootProject.hasProperty("ndkVersion")) {
ndkVersion rootProject.ext.ndkVersion
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
Expand Down
2 changes: 1 addition & 1 deletion packages/expo-modules-core/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ if(${UNIT_TEST})
PATHS ${HERMES_SO_DIR}
NO_CMAKE_FIND_ROOT_PATH
)
set(JSEXECUTOR_INCLUDE "${HERMES_HEADER_DIR}")
set(JSEXECUTOR_INCLUDE ${HERMES_HEADER_DIR} ${HERMES_HEADER_DIR}/API ${HERMES_HEADER_DIR}/public)
else()
find_library(
JSEXECUTOR_LIB
Expand Down
51 changes: 41 additions & 10 deletions packages/expo-modules-core/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,12 @@ def currentHermesVersion = file("${REACT_NATIVE_DIR}/sdks/.hermesversion").exist
def hasHermesProject = findProject(":ReactAndroid:hermes-engine") != null
def prebuiltHermesCacheHit = hasHermesProject && currentHermesVersion == prebuiltHermesVersion

// By default we are going to download and unzip hermes inside the /sdks/hermes folder
// but you can provide an override for where the hermes source code is located.
def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: file("${REACT_NATIVE_DIR}/sdks/hermes")

def USE_HERMES = false
def NEED_DOWNLOAD_HERMES = false
def HERMES_HEADER_DIR = null
def HERMES_AAR = null
if (findProject(":app")) {
Expand All @@ -108,19 +113,14 @@ if (USE_HERMES) {
HERMES_HEADER_DIR = file("${thirdPartyNdkDir}/hermes/prefab/modules/libhermes/include")
HERMES_AAR = file("${REACT_NATIVE_DIR}/ReactAndroid/hermes-engine/build/outputs/aar/hermes-engine-debug.aar")
} else {
// The `hermes-engine` package doesn't contain the correct version of the Hermes.
// The AAR we need to import is located in the React Native package.
// However, the version from RN doesn't include header files.
// To get those, we must fall back to the `hermes-engine` package.
def hermesEngineDir = new File(["node", "--print", "require.resolve('hermes-engine/package.json')"].execute(null, rootDir).text.trim()).parent

def prebuiltAAR = fileTree(REACT_NATIVE_DIR).matching { include "**/hermes-engine/**/hermes-engine-*-debug.aar" }
if (prebuiltAAR.any()) {
HERMES_AAR = prebuiltAAR.singleFile
} else {
HERMES_AAR = file("${hermesEngineDir}/android/hermes-debug.aar")
}
HERMES_HEADER_DIR = file("${hermesEngineDir}/android/include")
HERMES_HEADER_DIR = file("${hermesDir}")
NEED_DOWNLOAD_HERMES = true
}
}
// END HERMES
Expand Down Expand Up @@ -154,6 +154,13 @@ afterEvaluate {
android {
compileSdkVersion safeExtGet("compileSdkVersion", 31)

if (rootProject.hasProperty("ndkPath")) {
ndkPath rootProject.ext.ndkPath
}
if (rootProject.hasProperty("ndkVersion")) {
ndkVersion rootProject.ext.ndkVersion
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
Expand All @@ -176,7 +183,7 @@ android {
externalNativeBuild {
cmake {
abiFilters (*reactNativeArchitectures())
arguments "-DANDROID_STL=c++_shared",
arguments "-DANDROID_STL=${isExpoModulesCoreTests ? 'c++_static' : 'c++_shared'}",
"-DREACT_NATIVE_DIR=${REACT_NATIVE_DIR}",
"-DREACT_NATIVE_SO_DIR=${REACT_NATIVE_SO_DIR}",
"-DREACT_NATIVE_TARGET_VERSION=${REACT_NATIVE_TARGET_VERSION}",
Expand Down Expand Up @@ -206,6 +213,7 @@ android {
// Gradle will add cmake target dependencies into packaging.
// Theses files are intermediated linking files to build modules-core and should not be in final package.
def sharedLibraries = [
"**/libc++_shared.so",
"**/libfabricjni.so",
"**/libfbjni.so",
"**/libfolly_json.so",
Expand Down Expand Up @@ -234,7 +242,6 @@ android {
} else {
excludes += sharedLibraries
}
excludes.add("**/libc++_shared.so")
}

configurations {
Expand Down Expand Up @@ -457,12 +464,36 @@ task prepareFolly(dependsOn: [downloadFolly], type: Copy) {
includeEmptyDirs = false
into("$thirdPartyNdkDir/folly")
}
// END FOLLy
// END FOLLY

task downloadHermes(type: Download) {
def hermesVersion = currentHermesVersion ?: "main"
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
onlyIfNewer(true)
overwrite(false)
dest(new File(downloadsDir, "hermes-${hermesVersion}.tar.gz"))
}

task unzipHermes(dependsOn: downloadHermes, type: Copy) {
from(tarTree(downloadHermes.dest)) {
eachFile { file ->
// We flatten the unzip as the tarball contains a `facebook-hermes-<SHA>`
// folder at the top level.
if (file.relativePath.segments.size() > 1) {
file.relativePath = new org.gradle.api.file.RelativePath(!file.isDirectory(), file.relativePath.segments.drop(1))
}
}
}
into(hermesDir)
}

task prepareHermes(dependsOn: createNativeDepsDirectories) {
if (!USE_HERMES) {
return
}
if (NEED_DOWNLOAD_HERMES) {
dependsOn(unzipHermes)
}

doLast {
def files = zipTree(HERMES_AAR).matching({ it.include "**/*.so", "prefab/modules/libhermes/include/**/*" })
Expand Down

0 comments on commit e9bd9a9

Please sign in to comment.