mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
ebf746b1f9
Summary: CMake on Windows uses "Visual Studio **" generators are [multi-configuration](https://cgold.readthedocs.io/en/latest/glossary/multi-config.html), which requires the hermes cli and hermes runtime build flavors to be compatible. Using the "MakeFile" generator will avoid the requirement and keeps the gradle script simpler. Please note that the "Makefile" generator is the default when only "Visual Studio Community edition" with default packages is available. Use NMake generator for Hermes build on Windows ## Changelog CMake on Windows uses "Visual Studio **" generators are [multi-configuration](https://cgold.readthedocs.io/en/latest/glossary/multi-config.html), which requires the hermes cli and hermes runtime build flavors to be compatible. Using the "MakeFile" generator will avoid the requirement and keeps the gradle script simpler. Please note that the "Makefile" generator is the default when only "Visual Studio Community edition" with default packages is available. [Android] [Fixed] - Use NMake generator for Hermes build on Windows Pull Request resolved: https://github.com/facebook/react-native/pull/34790 Test Plan: Verified that RN build on Windows with multiple SKUs of Visual studio.d Reviewed By: cortinico Differential Revision: D39889332 Pulled By: cortinico fbshipit-source-id: f2d39d981e7c58c8cb93a4322155c844cb6bded3
261 lines
8.7 KiB
Groovy
261 lines
8.7 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.
|
|
*/
|
|
|
|
import org.apache.tools.ant.taskdefs.condition.Os
|
|
|
|
plugins {
|
|
id("de.undercouch.download")
|
|
id("com.android.library")
|
|
id("maven-publish")
|
|
}
|
|
|
|
group = "com.facebook.react"
|
|
version = parent.publishing_version
|
|
|
|
def cmakeVersion = "3.18.1"
|
|
/**
|
|
* We use the bundled version of CMake in the Android SDK if available, to don't force Android
|
|
* users to install CMake externally.
|
|
*/
|
|
def findCmakePath(cmakeVersion) {
|
|
if (System.getenv("ANDROID_SDK_ROOT")) {
|
|
return "${System.getenv("ANDROID_SDK_ROOT")}/cmake/${cmakeVersion}/bin/cmake"
|
|
}
|
|
if (System.getenv("ANDROID_HOME")) {
|
|
return "${System.getenv("ANDROID_HOME")}/cmake/${cmakeVersion}/bin/cmake"
|
|
}
|
|
return "cmake"
|
|
}
|
|
|
|
def reactNativeRootDir = project(':ReactAndroid').projectDir.parent;
|
|
def customDownloadDir = System.getenv("REACT_NATIVE_DOWNLOADS_DIR")
|
|
def downloadsDir = customDownloadDir ? new File(customDownloadDir) : new File(reactNativeRootDir, "sdks/download")
|
|
|
|
// 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 overrideHermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") != null
|
|
def hermesDir = System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR") ?: new File(reactNativeRootDir, "sdks/hermes")
|
|
def hermesBuildDir = new File("$buildDir/hermes")
|
|
|
|
def hermesVersion = "main"
|
|
def hermesVersionFile = new File(reactNativeRootDir, "sdks/.hermesversion")
|
|
if (hermesVersionFile.exists()) {
|
|
hermesVersion = hermesVersionFile.text
|
|
}
|
|
def ndkBuildJobs = Runtime.runtime.availableProcessors().toString()
|
|
def prefabHeadersDir = new File("$buildDir/prefab-headers")
|
|
|
|
// By setting REACT_NATIVE_HERMES_SKIP_PREFAB you can skip prefab publishing, to
|
|
// reduce the size of the Hermes published .AAR.
|
|
def skipPrefabPublishing = System.getenv("REACT_NATIVE_HERMES_SKIP_PREFAB") != null
|
|
|
|
// We inject the JSI directory used inside the Hermes build with the -DJSI_DIR config.
|
|
def jsiDir = new File(reactNativeRootDir, "ReactCommon/jsi")
|
|
|
|
// The .aar is placed inside the ./android folder at the top level.
|
|
// There it will be placed alongside the React Android .aar
|
|
def AAR_OUTPUT_URL = "file://${rootDir}/android"
|
|
|
|
task downloadHermes(type: Download) {
|
|
src("https://github.com/facebook/hermes/tarball/${hermesVersion}")
|
|
onlyIfNewer(true)
|
|
overwrite(false)
|
|
dest(new File(downloadsDir, "hermes.tar.gz"))
|
|
}
|
|
|
|
task installArchives {
|
|
dependsOn("publishAllPublicationsToNpmRepository")
|
|
}
|
|
|
|
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 configureBuildForHermes(type: Exec) {
|
|
workingDir(hermesDir)
|
|
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), Os.isFamily(Os.FAMILY_WINDOWS) ? "-GNMake Makefiles" : "", "-S", ".", "-B", hermesBuildDir.toString(), "-DJSI_DIR=" + jsiDir.absolutePath))
|
|
}
|
|
|
|
task buildHermes(dependsOn: configureBuildForHermes, type: Exec) {
|
|
workingDir(hermesDir)
|
|
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), "--build", hermesBuildDir.toString(), "--target", "hermesc", "-j", ndkBuildJobs))
|
|
}
|
|
|
|
task prepareHeadersForPrefab(type: Copy) {
|
|
from("$hermesDir/API")
|
|
from("$hermesDir/public")
|
|
include("**/*.h")
|
|
exclude("jsi/**")
|
|
into(prefabHeadersDir)
|
|
}
|
|
|
|
static def windowsAwareCommandLine(String... commands) {
|
|
def newCommands = []
|
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
newCommands = ['cmd', '/c']
|
|
}
|
|
newCommands.addAll(commands)
|
|
return newCommands
|
|
}
|
|
|
|
def reactNativeArchitectures() {
|
|
def value = project.getProperties().get("reactNativeArchitectures")
|
|
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
|
}
|
|
|
|
android {
|
|
compileSdkVersion 31
|
|
buildToolsVersion = "31.0.0"
|
|
|
|
// Used to override the NDK path/version on internal CI or by allowing
|
|
// users to customize the NDK path/version from their root project (e.g. for M1 support)
|
|
if (rootProject.hasProperty("ndkPath")) {
|
|
ndkPath rootProject.ext.ndkPath
|
|
}
|
|
if (rootProject.hasProperty("ndkVersion")) {
|
|
ndkVersion rootProject.ext.ndkVersion
|
|
}
|
|
|
|
defaultConfig {
|
|
minSdkVersion 21
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
arguments "-DHERMES_IS_ANDROID=True"
|
|
arguments "-DANDROID_STL=c++_shared"
|
|
arguments "-DANDROID_PIE=True"
|
|
arguments "-DANDROID_LD=lld"
|
|
arguments "-DIMPORT_HERMESC=${new File(hermesBuildDir, "ImportHermesc.cmake").toString()}"
|
|
arguments "-DJSI_DIR=${jsiDir}"
|
|
arguments "-DHERMES_SLOW_DEBUG=False"
|
|
arguments "-DHERMES_BUILD_SHARED_JSI=True"
|
|
arguments "-DHERMES_RELEASE_VERSION=for RN ${version}"
|
|
// We intentionally build Hermes with Intl support only. This is to simplify
|
|
// the build setup and to avoid overcomplicating the build-type matrix.
|
|
arguments "-DHERMES_ENABLE_INTL=True"
|
|
targets "libhermes"
|
|
}
|
|
}
|
|
ndk {
|
|
abiFilters (*reactNativeArchitectures())
|
|
}
|
|
}
|
|
|
|
externalNativeBuild {
|
|
cmake {
|
|
version cmakeVersion
|
|
path "$hermesDir/CMakeLists.txt"
|
|
}
|
|
}
|
|
|
|
buildTypes {
|
|
debug {
|
|
externalNativeBuild {
|
|
cmake {
|
|
// JS developers aren't VM developers.
|
|
// Therefore we're passing as build type Release, to provide a faster build.
|
|
// This has the (unlucky) side effect of letting AGP call the build
|
|
// tasks `configureCMakeRelease` while is actually building the debug flavor.
|
|
arguments "-DCMAKE_BUILD_TYPE=Release"
|
|
}
|
|
}
|
|
}
|
|
release {
|
|
externalNativeBuild {
|
|
cmake {
|
|
arguments "-DHERMES_ENABLE_DEBUGGER=False"
|
|
arguments "-DCMAKE_BUILD_TYPE=MinSizeRel"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sourceSets {
|
|
main {
|
|
manifest.srcFile "$hermesDir/android/hermes/src/main/AndroidManifest.xml"
|
|
java.srcDirs = [
|
|
"$hermesDir/lib/Platform/Intl/java"
|
|
]
|
|
}
|
|
}
|
|
|
|
buildFeatures {
|
|
prefab true
|
|
prefabPublishing !skipPrefabPublishing
|
|
}
|
|
|
|
dependencies {
|
|
implementation("com.facebook.fbjni:fbjni:0.2.2")
|
|
implementation("com.facebook.soloader:soloader:0.10.3")
|
|
implementation("com.facebook.yoga:proguard-annotations:1.19.0")
|
|
implementation("androidx.annotation:annotation:1.3.0")
|
|
}
|
|
|
|
packagingOptions {
|
|
exclude "**/libc++_shared.so"
|
|
exclude "**/libjsi.so"
|
|
exclude "**/libfbjni.so"
|
|
}
|
|
|
|
publishing {
|
|
multipleVariants {
|
|
withSourcesJar()
|
|
allVariants()
|
|
}
|
|
}
|
|
|
|
prefab {
|
|
libhermes {
|
|
headers prefabHeadersDir.absolutePath
|
|
libraryName "libhermes"
|
|
}
|
|
}
|
|
}
|
|
|
|
afterEvaluate {
|
|
if (!overrideHermesDir) {
|
|
// If you're not specifying a Hermes Path override, we want to
|
|
// download/unzip Hermes from Github then.
|
|
configureBuildForHermes.dependsOn(unzipHermes)
|
|
prepareHeadersForPrefab.dependsOn(unzipHermes)
|
|
}
|
|
preBuild.dependsOn(buildHermes)
|
|
preBuild.dependsOn(prepareHeadersForPrefab)
|
|
// Needed as some of the native sources needs to be downloaded
|
|
// before configureCMakeRelease/configureCMakeMinSizeRel could be executed.
|
|
reactNativeArchitectures().each { architecture ->
|
|
tasks.findByName("configureCMakeMinSizeRel[${architecture}]")?.configure { dependsOn(preBuild) }
|
|
tasks.findByName("configureCMakeRelease[${architecture}]")?.configure { dependsOn(preBuild) }
|
|
}
|
|
configureCMakeRelease.dependsOn(preBuild)
|
|
configureCMakeMinSizeRel.dependsOn(preBuild)
|
|
|
|
publishing {
|
|
publications {
|
|
release(MavenPublication) {
|
|
from components.default
|
|
artifactId = "hermes-engine"
|
|
}
|
|
}
|
|
repositories {
|
|
maven {
|
|
name = "npm"
|
|
url = AAR_OUTPUT_URL
|
|
}
|
|
}
|
|
}
|
|
}
|