Files
SliceBeam/app/build.gradle
T
2026-02-23 03:18:21 +00:00

714 lines
29 KiB
Groovy

import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JavaToolchainService
plugins {
id 'com.android.application'
}
def commit = getGitCommitHash(file('.'))
def prodCloudBaseUrl = "https://santoku.dark98.co.uk/v1/"
def prodBeamBaseUrl = "https://santoku.dark98.co.uk"
android {
namespace 'com.dark98.santoku'
compileSdk 35
defaultConfig {
applicationId "com.dark98.santoku"
minSdk 21
targetSdk 35
versionCode 1
versionName "0.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
buildConfigField "String", "CLOUD_BASE_URL_PROD", "\"" + prodCloudBaseUrl + "\""
buildConfigField "String", "BEAM_BASE_URL_PROD", "\"" + prodBeamBaseUrl + "\""
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_shared', '-DANDROID_PLATFORM=21',
'-DCMAKE_BUILD_TYPE=Release', // Disabling this results in drastically degradation of slicing times on debug builds
"-DSLIC3R_VERSION=${defaultConfig.versionName}",
"-DSLIC3R_BUILD_ID=${defaultConfig.versionCode}"
}
}
}
sourceSets {
main {
jniLibs.srcDirs += file('src/main/occt/jniLibs')
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "String", "COMMIT", "\"" + commit + "\""
ndk {
//noinspection ChromeOsAbiSupport
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
debug {
applicationIdSuffix ".debug"
resValue "string", "AppName", "Santoku (Debug)"
buildConfigField "String", "COMMIT", "\"" + commit + "\""
ndk {
debugSymbolLevel 'NONE'
//noinspection ChromeOsAbiSupport
abiFilters "arm64-v8a"
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
externalNativeBuild {
cmake {
path file('CMakeLists.txt')
}
ndkVersion "29.0.14206865"
}
buildFeatures {
buildConfig true
}
applicationVariants.all { variant ->
variant.outputs.all {
def isDebug = variant.buildType.name == "debug"
def suffix = isDebug ? "_debug" : ""
outputFileName = "Santoku_" + commit + suffix + ".apk"
}
}
}
def javaToolchainService = extensions.getByType(JavaToolchainService)
tasks.withType(JavaCompile).configureEach {
javaCompiler = javaToolchainService.compilerFor {
languageVersion = JavaLanguageVersion.of(21)
}
}
static String getGitCommitHash(File dir) {
try {
File gitDir = new File(dir, ".git")
if (!gitDir.exists()) {
return "non-git"
}
// Worktree/submodule support: .git may be a file with "gitdir: <path>".
if (gitDir.isFile()) {
String pointer = gitDir.text.trim()
if (pointer.startsWith("gitdir:")) {
gitDir = new File(dir, pointer.substring("gitdir:".length()).trim())
}
}
if (!gitDir.exists() || !gitDir.isDirectory()) {
return "non-git"
}
File headFile = new File(gitDir, "HEAD")
if (!headFile.exists()) {
return "non-git"
}
String head = headFile.text.trim()
String fullHash = null
if (head.startsWith("ref:")) {
String refPath = head.substring("ref:".length()).trim()
File refFile = new File(gitDir, refPath)
if (refFile.exists()) {
fullHash = refFile.text.trim()
} else {
File packedRefs = new File(gitDir, "packed-refs")
if (packedRefs.exists()) {
String prefix = refPath + " "
for (String line : packedRefs.readLines()) {
if (line.startsWith("#") || line.startsWith("^") || line.trim().isEmpty()) {
continue
}
int space = line.indexOf(' ')
if (space > 0 && line.substring(space + 1).trim() == refPath) {
fullHash = line.substring(0, space).trim()
break
}
}
}
}
} else {
// Detached HEAD.
fullHash = head
}
if (!fullHash || fullHash.length() < 10) {
return "non-git"
}
return fullHash.substring(0, 10)
} catch (Exception ignored) {
return "non-git"
}
}
dependencies {
implementation project(":eventbus")
implementation project(":eventbus_api")
annotationProcessor project(":eventbus_processor")
implementation project(":sapil")
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.github.instacart:truetime-android:4.0.0.alpha'
implementation 'com.github.mrudultora:Colorpicker:1.2.0'
implementation 'com.github.bumptech.glide:glide:4.16.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'com.loopj.android:android-async-http:1.4.11'
implementation 'androidx.activity:activity:1.10.1'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}
def loadLocalProperties() {
def props = new Properties()
def propsFile = rootProject.file("local.properties")
if (propsFile.exists()) {
propsFile.withInputStream { props.load(it) }
}
return props
}
def toWslPath(String winPath) {
return winPath.replaceAll('^([A-Za-z]):') { m -> "/mnt/${m[1].toLowerCase()}" }.replace('\\', '/')
}
def localProps = loadLocalProperties()
def sdkDir = localProps.getProperty("sdk.dir") ?: System.getenv("ANDROID_SDK_ROOT") ?: System.getenv("ANDROID_HOME")
if (!sdkDir) {
throw new GradleException("Missing sdk.dir in local.properties and ANDROID_SDK_ROOT/ANDROID_HOME is not set")
}
def ndkDir = "${sdkDir}/ndk/${android.ndkVersion}"
if (!file(ndkDir).exists()) {
throw new GradleException("NDK not found at ${ndkDir} (ndkVersion=${android.ndkVersion})")
}
def cmakeRoot = file("${sdkDir}/cmake")
def cmakeDir = cmakeRoot.listFiles()?.findAll { it.isDirectory() }?.sort { a, b -> b.name <=> a.name }?.first()
if (!cmakeDir) {
throw new GradleException("No CMake found under ${sdkDir}/cmake")
}
def osName = System.getProperty("os.name").toLowerCase()
def isWindows = osName.contains("windows")
def isMac = osName.contains("mac")
def cmakeExe = "${cmakeDir}/bin/cmake" + (isWindows ? ".exe" : "")
def ninjaExe = "${cmakeDir}/bin/ninja" + (isWindows ? ".exe" : "")
def toolchainFile = "${ndkDir}/build/cmake/android.toolchain.cmake"
def wslExe = "${System.getenv("SystemRoot") ?: "C:/Windows"}/System32/wsl.exe"
def prebuiltTag = isWindows ? "windows-x86_64" : (isMac ? "darwin-x86_64" : "linux-x86_64")
def llvmBinDir = "${ndkDir}/toolchains/llvm/prebuilt/${prebuiltTag}/bin"
def pageSizeLinkerFlags = "-Wl,-z,common-page-size=16384 -Wl,-z,max-page-size=16384"
def forceNativeRebuild = project.hasProperty("forceNativeRebuild") && project.property("forceNativeRebuild").toString().toLowerCase() == "true"
def tbbSrc = "${rootDir}/third_party/openvdb-android/tbb-aarch64"
def tbbBuildArm64 = "${rootDir}/third_party/openvdb-android/build-tbb-android-21-arm64"
def tbbInstallArm64 = "${rootDir}/third_party/openvdb-android/dist-android-21-arm64"
def tbbBuildArmv7 = "${rootDir}/third_party/openvdb-android/build-tbb-android-21-armv7"
def tbbInstallArmv7 = "${rootDir}/third_party/openvdb-android/dist-android-21-armv7"
def occtSrc = "${rootDir}/third_party/occt"
def occtBuildArm64 = "${rootDir}/third_party/occt/build-android-arm64-v8a"
def occtDistArm64 = "${rootDir}/third_party/occt/dist/android-arm64-v8a"
def occtBuildArmv7 = "${rootDir}/third_party/occt/build-android-armeabi-v7a"
def occtDistArmv7 = "${rootDir}/third_party/occt/dist/android-armeabi-v7a"
def boostDir = "${rootDir}/third_party/Boost-for-Android"
def boostOutArm64 = "${boostDir}/build/out/arm64-v8a"
def boostOutArmv7 = "${boostDir}/build/out/armeabi-v7a"
def rootPathForTasks = rootProject.projectDir.absolutePath
def appProjectPath = project.projectDir.absolutePath
def boostArm64OutLib = "${appProjectPath}/src/main/jniImports/boost/lib/arm64-v8a/lib/libboost_atomic-clang-mt-a64-1_85.a"
def boostArmv7OutLib = "${appProjectPath}/src/main/jniImports/boost/lib/armeabi-v7a/lib/libboost_atomic-clang-mt-a32-1_85.a"
def boostHeadersOut = "${appProjectPath}/src/main/jniImports/boost/include/boost/variant.hpp"
def tbbArm64LibA = "${appProjectPath}/src/main/jniImports/oneTBB/lib/arm64-v8a/libtbb.a"
def tbbArm64MallocA = "${appProjectPath}/src/main/jniImports/oneTBB/lib/arm64-v8a/libtbbmalloc.a"
def tbbArm64So = "${appProjectPath}/src/main/jniLibs/arm64-v8a/libtbb.so"
def tbbArm64MallocSo = "${appProjectPath}/src/main/jniLibs/arm64-v8a/libtbbmalloc.so"
def tbbArmv7LibA = "${appProjectPath}/src/main/jniImports/oneTBB/lib/armeabi-v7a/libtbb.a"
def tbbArmv7MallocA = "${appProjectPath}/src/main/jniImports/oneTBB/lib/armeabi-v7a/libtbbmalloc.a"
def tbbArmv7So = "${appProjectPath}/src/main/jniLibs/armeabi-v7a/libtbb.so"
def tbbArmv7MallocSo = "${appProjectPath}/src/main/jniLibs/armeabi-v7a/libtbbmalloc.so"
def tbbHeaderOut = "${appProjectPath}/src/main/jniImports/oneTBB/include/tbb/tbb.h"
def occtArm64So = "${appProjectPath}/src/main/occt/jniLibs/arm64-v8a/libTKDESTEP.so"
def occtArmv7So = "${appProjectPath}/src/main/occt/jniLibs/armeabi-v7a/libTKDESTEP.so"
def occtHeaderArm64Out = "${appProjectPath}/src/main/occt/include/arm64-v8a/STEPCAFControl_Reader.hxx"
def occtHeaderArmv7Out = "${appProjectPath}/src/main/occt/include/armeabi-v7a/STEPCAFControl_Reader.hxx"
tasks.register("ensureThirdParty") {
doLast {
def rootPath = rootPathForTasks
def thirdPartyDir = new File(rootPath, "third_party")
if (!thirdPartyDir.exists()) {
thirdPartyDir.mkdirs()
}
def repos = [
[path: "${rootPath}/third_party/Boost-for-Android", url: "https://github.com/moritz-wundke/Boost-for-Android.git"],
[path: "${rootPath}/third_party/openvdb-android", url: "https://github.com/syoyo/openvdb-android.git"],
[path: "${rootPath}/third_party/occt", url: "https://github.com/Open-Cascade-SAS/OCCT.git"]
]
def runCommand = { List<String> cmd, File workDir ->
Process process = new ProcessBuilder(cmd)
.directory(workDir)
.inheritIO()
.start()
int exitCode = process.waitFor()
if (exitCode != 0) {
throw new GradleException("Command failed (${exitCode}): ${cmd.join(' ')}")
}
}
for (def repo : repos) {
if (!new File(repo.path).exists()) {
runCommand(["git", "clone", "--depth", "1", repo.url, repo.path], new File(rootPath))
}
}
def vdbRoot = new File(rootPath, "third_party/openvdb-android")
if (new File(vdbRoot, ".gitmodules").exists() && !new File(vdbRoot, "tbb-aarch64/CMakeLists.txt").exists()) {
runCommand(["git", "submodule", "update", "--init", "--recursive"], vdbRoot)
}
}
}
tasks.register("patchBoostForAndroid") {
dependsOn("ensureThirdParty")
doLast {
def boostRoot = new File(rootPathForTasks, "third_party/Boost-for-Android")
def scriptFile = new File(boostRoot, "build-android.sh")
if (scriptFile.exists()) {
def scriptText = scriptFile.getText("UTF-8")
def changed = false
if (!scriptText.contains("FORCE_PLATFORM_OS")) {
def marker = "# Check platform patch"
def markerIdx = scriptText.indexOf(marker)
if (markerIdx >= 0) {
def esacIdx = scriptText.indexOf("esac", markerIdx)
if (esacIdx >= 0) {
def insertPos = scriptText.indexOf("\n", esacIdx)
if (insertPos >= 0) {
insertPos += 1
def insert = 'if [ -n "${FORCE_PLATFORM_OS}" ]; then\n' +
' PlatformOS="${FORCE_PLATFORM_OS}"\n' +
'fi\n\n'
scriptText = scriptText.substring(0, insertPos) + insert + scriptText.substring(insertPos)
changed = true
}
}
}
}
if (!scriptText.contains("CXXPATH.exe")) {
def marker = 'if [ -n "${AndroidSourcesDetected}"'
if (scriptText.contains(marker)) {
def insert = 'if [ ! -f "$CXXPATH" ] && [ -f "$CXXPATH.exe" ]; then\n' +
' CXXPATH="$CXXPATH.exe"\n' +
'fi\n\n'
scriptText = scriptText.replace(marker, insert + marker)
changed = true
}
}
if (changed) {
scriptFile.write(scriptText, "UTF-8")
}
}
def commonFile = new File(boostRoot, "configs/user-config-ndk23-1_85_0-common.jam")
if (commonFile.exists()) {
def commonText = commonFile.getText("UTF-8")
def commonChanged = false
if (!commonText.contains("AndroidToolSuffix")) {
def header = 'import os ;\n' +
'local AndroidToolSuffix = [ os.environ AndroidToolSuffix ] ;\n' +
'if ! $(AndroidToolSuffix) { AndroidToolSuffix = "" ; }\n\n'
commonText = header + commonText.trim() + "\n"
commonChanged = true
}
if (!commonText.contains('llvm-ar$(AndroidToolSuffix)')) {
commonText = commonText.replace('<archiver>$(AndroidBinariesPath)/llvm-ar', '<archiver>$(AndroidBinariesPath)/llvm-ar$(AndroidToolSuffix)')
commonChanged = true
}
if (!commonText.contains('llvm-ranlib$(AndroidToolSuffix)')) {
commonText = commonText.replace('<ranlib>$(AndroidBinariesPath)/llvm-ranlib', '<ranlib>$(AndroidBinariesPath)/llvm-ranlib$(AndroidToolSuffix)')
commonChanged = true
}
if (commonChanged) {
commonFile.write(commonText, "UTF-8")
}
}
def arm64File = new File(boostRoot, "configs/user-config-ndk23-1_85_0-arm64-v8a.jam")
if (arm64File.exists()) {
def text = arm64File.getText("UTF-8")
if (!text.contains("<arch>")) {
text = "<arch>arm\n<address-model>64\n<binary-format>elf\n<abi>aapcs\n" + text
arm64File.write(text, "UTF-8")
}
}
def armv7File = new File(boostRoot, "configs/user-config-ndk23-1_85_0-armeabi-v7a.jam")
if (armv7File.exists()) {
def text = armv7File.getText("UTF-8")
if (!text.contains("<arch>")) {
text = "<arch>arm\n<address-model>32\n<binary-format>elf\n<abi>aapcs\n" + text
armv7File.write(text, "UTF-8")
}
}
}
}
tasks.register("buildTbbArm64") {
dependsOn("ensureThirdParty")
onlyIf {
forceNativeRebuild ||
!new File(tbbArm64LibA).exists() ||
!new File(tbbArm64MallocA).exists() ||
!new File(tbbArm64So).exists() ||
!new File(tbbArm64MallocSo).exists()
}
doLast {
exec {
commandLine cmakeExe, "-G", "Ninja",
"-S", tbbSrc,
"-B", tbbBuildArm64,
"-DCMAKE_MAKE_PROGRAM=${ninjaExe}",
"-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"-DCMAKE_TOOLCHAIN_FILE=${toolchainFile}",
"-DANDROID_ABI=arm64-v8a",
"-DANDROID_PLATFORM=android-21",
"-DANDROID_STL=c++_shared",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_SHARED_LINKER_FLAGS=${pageSizeLinkerFlags}",
"-DCMAKE_INSTALL_PREFIX=${tbbInstallArm64}",
"-DTBB_BUILD_TESTS=Off"
}
exec {
commandLine cmakeExe, "--build", tbbBuildArm64, "--target", "install"
}
}
}
tasks.register("buildTbbArmv7") {
dependsOn("ensureThirdParty")
onlyIf {
forceNativeRebuild ||
!new File(tbbArmv7LibA).exists() ||
!new File(tbbArmv7MallocA).exists() ||
!new File(tbbArmv7So).exists() ||
!new File(tbbArmv7MallocSo).exists()
}
doLast {
exec {
commandLine cmakeExe, "-G", "Ninja",
"-S", tbbSrc,
"-B", tbbBuildArmv7,
"-DCMAKE_MAKE_PROGRAM=${ninjaExe}",
"-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"-DCMAKE_TOOLCHAIN_FILE=${toolchainFile}",
"-DANDROID_ABI=armeabi-v7a",
"-DANDROID_PLATFORM=android-21",
"-DANDROID_STL=c++_shared",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_SHARED_LINKER_FLAGS=${pageSizeLinkerFlags}",
"-DCMAKE_INSTALL_PREFIX=${tbbInstallArmv7}",
"-DTBB_BUILD_TESTS=Off"
}
exec {
commandLine cmakeExe, "--build", tbbBuildArmv7, "--target", "install"
}
}
}
tasks.register("copyTbbArm64", Copy) {
dependsOn("buildTbbArm64")
onlyIf {
forceNativeRebuild ||
!new File(tbbArm64LibA).exists() ||
!new File(tbbArm64MallocA).exists() ||
!new File(tbbArm64So).exists() ||
!new File(tbbArm64MallocSo).exists()
}
from("${tbbInstallArm64}/lib") {
include "libtbb_static.a"
include "libtbbmalloc_static.a"
include "libtbb.so"
include "libtbbmalloc.so"
}
into("${projectDir}/src/main/jniImports/oneTBB/tmp-arm64")
doLast {
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-arm64/libtbb_static.a"
into "${projectDir}/src/main/jniImports/oneTBB/lib/arm64-v8a"
rename { "libtbb.a" }
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-arm64/libtbbmalloc_static.a"
into "${projectDir}/src/main/jniImports/oneTBB/lib/arm64-v8a"
rename { "libtbbmalloc.a" }
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-arm64/libtbb.so"
into "${projectDir}/src/main/jniLibs/arm64-v8a"
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-arm64/libtbbmalloc.so"
into "${projectDir}/src/main/jniLibs/arm64-v8a"
}
delete("${projectDir}/src/main/jniImports/oneTBB/tmp-arm64")
}
}
tasks.register("copyTbbArmv7", Copy) {
dependsOn("buildTbbArmv7")
onlyIf {
forceNativeRebuild ||
!new File(tbbArmv7LibA).exists() ||
!new File(tbbArmv7MallocA).exists() ||
!new File(tbbArmv7So).exists() ||
!new File(tbbArmv7MallocSo).exists()
}
from("${tbbInstallArmv7}/lib") {
include "libtbb_static.a"
include "libtbbmalloc_static.a"
include "libtbb.so"
include "libtbbmalloc.so"
}
into("${projectDir}/src/main/jniImports/oneTBB/tmp-armv7")
doLast {
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-armv7/libtbb_static.a"
into "${projectDir}/src/main/jniImports/oneTBB/lib/armeabi-v7a"
rename { "libtbb.a" }
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-armv7/libtbbmalloc_static.a"
into "${projectDir}/src/main/jniImports/oneTBB/lib/armeabi-v7a"
rename { "libtbbmalloc.a" }
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-armv7/libtbb.so"
into "${projectDir}/src/main/jniLibs/armeabi-v7a"
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/tmp-armv7/libtbbmalloc.so"
into "${projectDir}/src/main/jniLibs/armeabi-v7a"
}
delete("${projectDir}/src/main/jniImports/oneTBB/tmp-armv7")
}
}
tasks.register("copyTbbHeaders") {
dependsOn("buildTbbArm64")
onlyIf { !new File(tbbHeaderOut).exists() }
doLast {
copy {
from "${tbbInstallArm64}/include/tbb"
into "${projectDir}/src/main/jniImports/oneTBB/include/tbb"
}
copy {
from "${projectDir}/src/main/jniImports/oneTBB/include/tbb"
into "${projectDir}/src/main/jniImports/oneTBB/include/oneapi/tbb"
}
}
}
tasks.register("buildBoostArm64") {
dependsOn("patchBoostForAndroid")
onlyIf { !new File(boostArm64OutLib).exists() }
doLast {
if (isWindows) {
if (!new File(wslExe).exists()) {
throw new GradleException("WSL is required to build Boost on Windows. Install WSL or provide prebuilt Boost libs.")
}
def ndkWsl = toWslPath(ndkDir)
def boostWsl = toWslPath(boostDir)
def binWsl = toWslPath(llvmBinDir)
def cmd = "set -euo pipefail; cd ${boostWsl}; chmod +x ${binWsl}/aarch64-linux-android21-clang++ ${binWsl}/llvm-ar.exe ${binWsl}/llvm-ranlib.exe || true; FORCE_PLATFORM_OS=windows AndroidCompilerSuffix= AndroidToolSuffix=.exe ./build-android.sh ${ndkWsl} --boost=1.85.0 --arch=arm64-v8a --target-version=21 --without-libraries=context,coroutine,fiber,python"
Process p = new ProcessBuilder([wslExe, "bash", "-lc", cmd]).inheritIO().start()
if (p.waitFor() != 0) {
throw new GradleException("Boost arm64 build failed")
}
} else {
def cmd = "set -euo pipefail; cd ${boostDir}; chmod +x ${llvmBinDir}/aarch64-linux-android21-clang++ ${llvmBinDir}/llvm-ar ${llvmBinDir}/llvm-ranlib || true; ./build-android.sh ${ndkDir} --boost=1.85.0 --arch=arm64-v8a --target-version=21 --without-libraries=context,coroutine,fiber,python"
Process p = new ProcessBuilder(["bash", "-lc", cmd]).inheritIO().start()
if (p.waitFor() != 0) {
throw new GradleException("Boost arm64 build failed")
}
}
}
}
tasks.register("buildBoostArmv7") {
dependsOn("patchBoostForAndroid")
onlyIf { !new File(boostArmv7OutLib).exists() }
doLast {
if (isWindows) {
if (!new File(wslExe).exists()) {
throw new GradleException("WSL is required to build Boost on Windows. Install WSL or provide prebuilt Boost libs.")
}
def ndkWsl = toWslPath(ndkDir)
def boostWsl = toWslPath(boostDir)
def binWsl = toWslPath(llvmBinDir)
def cmd = "set -euo pipefail; cd ${boostWsl}; chmod +x ${binWsl}/armv7a-linux-androideabi21-clang++ ${binWsl}/llvm-ar.exe ${binWsl}/llvm-ranlib.exe || true; FORCE_PLATFORM_OS=windows AndroidCompilerSuffix= AndroidToolSuffix=.exe ./build-android.sh ${ndkWsl} --boost=1.85.0 --arch=armeabi-v7a --target-version=21 --without-libraries=context,coroutine,fiber,python"
Process p = new ProcessBuilder([wslExe, "bash", "-lc", cmd]).inheritIO().start()
if (p.waitFor() != 0) {
throw new GradleException("Boost armv7 build failed")
}
} else {
def cmd = "set -euo pipefail; cd ${boostDir}; chmod +x ${llvmBinDir}/armv7a-linux-androideabi21-clang++ ${llvmBinDir}/llvm-ar ${llvmBinDir}/llvm-ranlib || true; ./build-android.sh ${ndkDir} --boost=1.85.0 --arch=armeabi-v7a --target-version=21 --without-libraries=context,coroutine,fiber,python"
Process p = new ProcessBuilder(["bash", "-lc", cmd]).inheritIO().start()
if (p.waitFor() != 0) {
throw new GradleException("Boost armv7 build failed")
}
}
}
}
tasks.register("copyBoostArm64", Copy) {
dependsOn("buildBoostArm64")
onlyIf { !new File(boostArm64OutLib).exists() }
from("${boostOutArm64}/lib") {
include "libboost_*.a"
}
into("${projectDir}/src/main/jniImports/boost/lib/arm64-v8a/lib")
}
tasks.register("copyBoostArmv7", Copy) {
dependsOn("buildBoostArmv7")
onlyIf { !new File(boostArmv7OutLib).exists() }
from("${boostOutArmv7}/lib") {
include "libboost_*.a"
}
into("${projectDir}/src/main/jniImports/boost/lib/armeabi-v7a/lib")
}
tasks.register("copyBoostHeaders", Copy) {
dependsOn("ensureThirdParty")
onlyIf { !new File(boostHeadersOut).exists() }
from("${boostDir}/boost_1_85_0/boost")
into("${projectDir}/src/main/jniImports/boost/include/boost")
}
tasks.register("buildOcctArm64") {
dependsOn("ensureThirdParty")
onlyIf { forceNativeRebuild || !new File(occtArm64So).exists() }
doLast {
List<String> cfgCmd = [
cmakeExe, "-G", "Ninja",
"-S", occtSrc,
"-B", occtBuildArm64,
"-DCMAKE_MAKE_PROGRAM=${ninjaExe}",
"-DCMAKE_TOOLCHAIN_FILE=${toolchainFile}",
"-DANDROID_ABI=arm64-v8a",
"-DANDROID_PLATFORM=android-21",
"-DCMAKE_BUILD_TYPE=Release",
"-DBUILD_LIBRARY_TYPE=Shared",
"-DCMAKE_SHARED_LINKER_FLAGS=${pageSizeLinkerFlags}",
"-DINSTALL_DIR_LIB=libs/arm64-v8a",
"-DINSTALL_DIR_INCLUDE=inc",
"-DBUILD_DOC_Overview=OFF",
"-DBUILD_DOC_RefMan=OFF",
"-DUSE_FREETYPE=OFF",
"-DUSE_RAPIDJSON=OFF",
"-DUSE_DRACO=OFF",
"-DCMAKE_INSTALL_PREFIX=${occtDistArm64}"
]
Process p1 = new ProcessBuilder(cfgCmd).inheritIO().start()
if (p1.waitFor() != 0) throw new GradleException("OCCT arm64 configure failed")
Process p2 = new ProcessBuilder([cmakeExe, "--build", occtBuildArm64, "--target", "install", "--config", "Release", "--", "-j2"]).inheritIO().start()
if (p2.waitFor() != 0) throw new GradleException("OCCT arm64 build failed")
}
}
tasks.register("buildOcctArmv7") {
dependsOn("ensureThirdParty")
onlyIf { forceNativeRebuild || !new File(occtArmv7So).exists() }
doLast {
List<String> cfgCmd = [
cmakeExe, "-G", "Ninja",
"-S", occtSrc,
"-B", occtBuildArmv7,
"-DCMAKE_MAKE_PROGRAM=${ninjaExe}",
"-DCMAKE_TOOLCHAIN_FILE=${toolchainFile}",
"-DANDROID_ABI=armeabi-v7a",
"-DANDROID_PLATFORM=android-21",
"-DCMAKE_BUILD_TYPE=Release",
"-DBUILD_LIBRARY_TYPE=Shared",
"-DCMAKE_SHARED_LINKER_FLAGS=${pageSizeLinkerFlags}",
"-DINSTALL_DIR_LIB=libs/armeabi-v7a",
"-DINSTALL_DIR_INCLUDE=inc",
"-DBUILD_DOC_Overview=OFF",
"-DBUILD_DOC_RefMan=OFF",
"-DUSE_FREETYPE=OFF",
"-DUSE_RAPIDJSON=OFF",
"-DUSE_DRACO=OFF",
"-DCMAKE_INSTALL_PREFIX=${occtDistArmv7}"
]
Process p1 = new ProcessBuilder(cfgCmd).inheritIO().start()
if (p1.waitFor() != 0) throw new GradleException("OCCT armv7 configure failed")
Process p2 = new ProcessBuilder([cmakeExe, "--build", occtBuildArmv7, "--target", "install", "--config", "Release", "--", "-j2"]).inheritIO().start()
if (p2.waitFor() != 0) throw new GradleException("OCCT armv7 build failed")
}
}
tasks.register("copyOcctArm64", Copy) {
dependsOn("buildOcctArm64")
onlyIf { forceNativeRebuild || !new File(occtArm64So).exists() }
from("${occtDistArm64}/libs/arm64-v8a") {
include "*.so"
}
into("${projectDir}/src/main/occt/jniLibs/arm64-v8a")
}
tasks.register("copyOcctArmv7", Copy) {
dependsOn("buildOcctArmv7")
onlyIf { forceNativeRebuild || !new File(occtArmv7So).exists() }
from("${occtDistArmv7}/libs/armeabi-v7a") {
include "*.so"
}
into("${projectDir}/src/main/occt/jniLibs/armeabi-v7a")
}
tasks.register("copyOcctHeadersArm64", Copy) {
dependsOn("buildOcctArm64")
onlyIf { !new File(occtHeaderArm64Out).exists() }
from("${occtDistArm64}/inc")
into("${projectDir}/src/main/occt/include/arm64-v8a")
}
tasks.register("copyOcctHeadersArmv7", Copy) {
dependsOn("buildOcctArmv7")
onlyIf { !new File(occtHeaderArmv7Out).exists() }
from("${occtDistArmv7}/inc")
into("${projectDir}/src/main/occt/include/armeabi-v7a")
}
tasks.register("prepareNativeDeps") {
dependsOn(
"copyTbbArm64",
"copyTbbArmv7",
"copyTbbHeaders",
"copyBoostArm64",
"copyBoostArmv7",
"copyBoostHeaders",
"copyOcctArm64",
"copyOcctArmv7",
"copyOcctHeadersArm64",
"copyOcctHeadersArmv7"
)
}
afterEvaluate {
tasks.matching { it.name.startsWith("buildCMake") }.configureEach {
dependsOn("prepareNativeDeps")
}
}