blob: 495bf65f4f64bd5b1310fcf888d6e4b3941ecf19 [file] [log] [blame]
import groovy.json.JsonSlurper
import java.nio.charset.StandardCharsets
import org.robolectric.gradle.DeployedRoboJavaModulePlugin
import org.robolectric.gradle.RoboJavaModulePlugin
apply plugin: RoboJavaModulePlugin
apply plugin: DeployedRoboJavaModulePlugin
static def osName() {
def osName = System.getProperty("os.name").toLowerCase(Locale.US);
if (osName.contains("linux")) {
return "linux"
} else if (osName.contains("mac")) {
return "mac"
} else if (osName.contains("win")) {
return "windows"
}
return "unknown"
}
static def arch() {
def arch = System.getProperty("os.arch").toLowerCase(Locale.US);
if (arch.equals("x86_64") || arch.equals("amd64")) {
return "x86_64"
}
return arch
}
static def authHeader() {
def user = System.getenv('GITHUB_USER')
if (!user) {
throw new GradleException("Missing GITHUB_USER environment variable")
}
def token = System.getenv('GITHUB_TOKEN')
if (!token) {
throw new GradleException("Missing GITHUB_TOKEN environment variable")
}
def lp = "$user:$token"
def encoded = Base64.getEncoder().encodeToString(lp.getBytes(StandardCharsets.UTF_8))
return "Basic $encoded"
}
task cmakeNativeRuntime {
doLast {
mkdir "$buildDir/cpp"
exec {
workingDir "$buildDir/cpp"
commandLine 'cmake', "-B", ".", "-S","$projectDir/cpp/", "-G", "Ninja"
}
}
}
task configureICU {
onlyIf { !System.getenv('ICU_ROOT_DIR') }
doLast {
def os = osName()
if (!file("$projectDir/external/icu/icu4c/source").exists()) {
throw new GradleException("ICU submodule not detected. Please run `git submodule update --init`")
}
if (file("$projectDir/external/icu/icu4c/source/Makefile").exists()) {
println("ICU Makefile detected, skipping ICU configure")
} else {
exec {
workingDir "$projectDir/external/icu/icu4c/source"
if (os.contains("linux")) {
environment "CFLAGS", "-fPIC"
environment "CXXFLAGS", "-fPIC"
commandLine './runConfigureICU', 'Linux', '--enable-static', '--disable-shared'
} else if (os.contains("mac")) {
commandLine './runConfigureICU', 'MacOSX', '--enable-static', '--disable-shared'
} else if (os.contains("win")) {
commandLine 'sh', './runConfigureICU', 'MinGW', '--enable-static', '--disable-shared'
} else {
println("ICU configure not supported for OS '${System.getProperty("os.name")}'")
}
}
}
}
}
task buildICU {
onlyIf { !System.getenv('ICU_ROOT_DIR') }
dependsOn configureICU
doLast {
exec {
def os = osName()
if (os.contains("linux") || os.contains("mac") || os.contains("win")) {
workingDir "$projectDir/external/icu/icu4c/source"
commandLine 'make', '-j4'
}
}
}
}
task makeNativeRuntime {
dependsOn buildICU
dependsOn cmakeNativeRuntime
doLast {
exec {
workingDir "$buildDir/cpp"
commandLine 'ninja'
}
}
}
task copyNativeRuntimeToResources {
def os = osName()
if (System.getenv('SKIP_NATIVERUNTIME_BUILD')) {
println("Skipping the nativeruntime build");
} else if (!os.contains("linux") && !os.contains("mac") && !os.contains("win")) {
println("Building the nativeruntime not supported for OS '${System.getProperty("os.name")}'")
} else {
dependsOn makeNativeRuntime
outputs.dir "$buildDir/resources/main/native"
doLast {
copy {
from ("$buildDir/cpp")
include '*libnativeruntime.*'
rename { String fileName ->
if (os.contains("win")) {
fileName.replace("libnativeruntime", "robolectric-nativeruntime")
} else {
fileName.replace("libnativeruntime", "librobolectric-nativeruntime")
}
}
into "$buildDir/resources/main/native/$os/${arch()}/"
}
}
}
}
task copyNativeRuntimeFromGithubAction {
outputs.dir "$buildDir/resources/main/native"
doLast {
def checkRunId = System.getenv('NATIVERUNTIME_ACTION_RUN_ID')
def artifactsUrl = "https://api.github.com/repos/robolectric/robolectric/actions/runs/$checkRunId/artifacts"
def downloadDir = new File("$buildDir/robolectric-nativeruntime-artifacts-$checkRunId")
downloadDir.mkdirs()
new JsonSlurper().parseText(new URL(artifactsUrl).text).artifacts.each { artifact ->
def f = new File(downloadDir, "${artifact.name}.zip")
if (!f.exists()) {
println("Fetching ${artifact.name}.zip to $f")
def conn = (HttpURLConnection) new URL(artifact.archive_download_url).openConnection()
conn.instanceFollowRedirects = true
conn.setRequestProperty("Authorization", authHeader())
f.withOutputStream { out ->
conn.inputStream.with { inp ->
out << inp
inp.close()
out.close()
}
}
}
copy {
from zipTree(f)
include "librobolectric*"
rename { String fileName ->
fileName = fileName.replaceFirst("librobolectric.*dylib", "librobolectric-nativeruntime.dylib")
return fileName.replaceFirst("librobolectric.*so", "librobolectric-nativeruntime.so")
}
def os = "linux"
if (artifact.name.contains("-mac")) {
os = "mac"
}
def arch = "x86_64"
if (artifact.name.contains("-arm64")) {
arch = "aarch64"
}
into "$buildDir/resources/main/native/$os/$arch/"
}
}
}
}
processResources {
if (System.getenv('NATIVERUNTIME_ACTION_RUN_ID')) {
dependsOn copyNativeRuntimeFromGithubAction
} else {
dependsOn copyNativeRuntimeToResources
}
}
dependencies {
api project(":utils")
api project(":utils:reflector")
api "com.google.guava:guava:$guavaJREVersion"
annotationProcessor "com.google.auto.service:auto-service:$autoServiceVersion"
compileOnly "com.google.auto.service:auto-service-annotations:$autoServiceVersion"
compileOnly AndroidSdk.MAX_SDK.coordinates
testCompileOnly AndroidSdk.MAX_SDK.coordinates
testRuntimeOnly AndroidSdk.MAX_SDK.coordinates
testImplementation project(":robolectric")
testImplementation "junit:junit:${junitVersion}"
testImplementation "com.google.truth:truth:${truthVersion}"
}