Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
def dummyFiles = [ '**/*/impl/Dummy**' ]
def iosFiles = [ '**/*/impl/IOS**', '**/**ios.json', '**/ios' ]
def androidFiles = [ '**/*/impl/Android**', '**/**android.json', '**/dalvik' ]
def desktopFiles = [ '**/impl/Desktop**', '**/**darwin.json', '**/**linux.json', '**/**windows.json' ]
def projectClasses = "$project.buildDir/classes/java/main"
def projectResources = "$project.buildDir/resources/main"
def projectIOSResources = "$project.projectDir/src/ios/resources/"
def projectAndroidResources = "$project.projectDir/src/android/resources/"
def projectDesktopResources = "$project.projectDir/src/desktop/resources/"
def sdkPath(String platform) {
return "/Applications/Xcode.app/Contents/Developer/Platforms/${platform}.platform/Developer/SDKs/${platform}${IOS_VERSION}.sdk";
}
def AndroidPlatform = 31
task androidBuild {
group = "native"
dependsOn build
doLast {
def serviceName = getServiceName(project.name)
File aar = aarBuild ("$project.buildDir", "$project.projectDir", serviceName, 'android')
if (aar == null) {
println "Error creating $aar"
}
nativeBuildLib("$project.buildDir", "$project.projectDir", serviceName, 'android')
}
}
task androidJar (type: Jar, dependsOn: androidBuild) {
group = "native"
from projectClasses, projectResources, projectAndroidResources
exclude dummyFiles
exclude iosFiles
exclude desktopFiles
archiveClassifier.set('android')
afterEvaluate {
into("native") {
from ("$project.buildDir/native/android") {
include 'lib*.a'
}
}
}
}
task iosBuild {
enabled = System.getProperty('os.name').toLowerCase().contains("mac")
group = "native"
dependsOn build
doLast {
def serviceName = getServiceName(project.name)
nativeBuildLib("$project.buildDir", "$project.projectDir", serviceName, 'ios')
}
}
task iosJar (type: Jar, dependsOn: iosBuild) {
enabled = System.getProperty('os.name').toLowerCase().contains("mac")
group = "native"
from projectClasses, projectResources, projectIOSResources
exclude dummyFiles
exclude desktopFiles
exclude androidFiles
archiveClassifier.set('ios')
afterEvaluate {
def serviceName = getServiceName(project.name)
into("native") {
from "$project.buildDir/native/ios/lib${serviceName}.a"
}
}
}
task desktopBuild {
enabled = project.name != "util"
group = "native"
dependsOn build
doLast {
def serviceName = getServiceName(project.name)
nativeBuildLib("$project.buildDir", "$project.projectDir", serviceName, 'desktop')
}
}
task desktopJar (type: Jar, dependsOn: desktopBuild) {
enabled = project.name != "util"
group = "native"
from projectClasses, projectResources, projectDesktopResources
exclude dummyFiles
exclude iosFiles
exclude androidFiles
archiveClassifier.set('desktop')
afterEvaluate {
def serviceName = getServiceName(project.name)
into("native") {
from "$project.buildDir/native/desktop/lib${serviceName}.a"
}
}
}
task nativeBuild {
dependsOn androidBuild, iosBuild, desktopBuild
group = "native"
description = "Runs native build for android, ios and desktop"
}
ext.aarBuild = { buildDir, projectDir, name, os ->
def JAVAHOME = System.getenv("JAVA_HOME")
def sdk = System.getenv("ANDROID_SDK")
if (sdk == null) {
throw new GradleException("Error: ANDROID_SDK can't be null")
}
def androidJar = sdk + "/platforms/android-${AndroidPlatform}/android.jar"
if (!file(androidJar).exists()) {
throw new GradleException("Error: path for ${androidJar} doesn't exist")
}
// copy android_project
File androidDir = file("$projectDir/../../gradle/android_project")
def tempDir = file("${buildDir}/aar")
mkdir tempDir
project.copy {
from androidDir
exclude "**/gradlew"
into tempDir
}
project.copy {
from file("$androidDir/gradlew").getAbsolutePath()
into tempDir
fileMode 0744
}
// copy service dalvik sources
File sourcesDir = file("$projectDir/src/main/native/$os/dalvik")
project.copy {
from sourcesDir
into file("$tempDir/library/src/main/java/com/gluonhq/helloandroid")
}
if (name != "Util") {
def util = file("$projectDir/../util/build/tmp/util_classes.jar")
if (!util.exists()) {
// compile util
File sourcesUtilDir = file("$projectDir/../util/src/main/native/$os/dalvik")
def javaSources = [sourcesUtilDir.listFiles()].flatten()
def javac = "$JAVAHOME/bin/javac"
def javacArgs = ["-d", file("$tempDir/classes").getAbsolutePath(),
"-source", "1.7", "-target", "1.7",
"-bootclasspath", androidJar,
javaSources].flatten()
exec {
executable javac
args javacArgs
}
// create jar
def jar = "$JAVAHOME/bin/jar"
file(util.getParent()).mkdirs()
def jarArgs = ["cf", util.getAbsolutePath(), "-C",
file("$tempDir/classes").getAbsolutePath(), "."].flatten()
exec {
executable jar
args jarArgs
}
}
// copy util jar
project.copy {
from util
into file("$tempDir/libs")
}
}
// use build
File build = file("$projectDir/src/main/resources/META-INF/substrate/dalvik/build.gradle")
if (build != null && build.exists()) {
file("$tempDir/library/build.gradle").delete()
project.copy {
from build
into file("$tempDir/library/")
}
}
// use manifest
File manifest = file("$projectDir/src/main/resources/META-INF/substrate/dalvik/AndroidManifest.xml")
if (manifest != null && manifest.exists()) {
file("$tempDir/library/src/main/AndroidManifest.xml").delete()
project.copy {
from manifest
into file("$tempDir/library/src/main/")
}
}
// use res
File res = file("$projectDir/src/main/resources/META-INF/substrate/dalvik/res/xml/file_provider_paths.xml")
if (res != null && res.exists()) {
project.copy {
from res
into file("$tempDir/library/src/main/res/xml/")
}
}
// use dalvik assets
File assetsDir = file("$projectDir/src/main/resources/META-INF/substrate/dalvik/assets")
project.copy {
from assetsDir
into file("$tempDir/library/src/main/assets")
}
// prepare output
def dalvikOutput = "${buildDir}/resources/main/META-INF/substrate/dalvik/"
project.delete(files(dalvikOutput))
// build aar
file("$tempDir/gradlew")
def aarArgs = ["-p", file("$tempDir/library").getAbsolutePath(), "assembleDebug"].flatten()
exec {
environment ANDROID_HOME: sdk, JAVA_HOME: JAVAHOME
executable file("$tempDir/gradlew").getAbsolutePath()
args aarArgs
}
// copy aar, dependencies
project.copy {
from file("$tempDir/library/build/outputs/aar/library-debug.aar")
from file("$projectDir/src/main/resources/META-INF/substrate/dalvik/android-dependencies.txt")
into dalvikOutput
rename { fileName -> fileName.replace('library-debug', "$name") }
}
println("build for ${name}.aar finished")
File a = new File("$dalvikOutput/${name}.aar")
if (a.exists()) {
a
}
}
ext.nativeBuildLib = { buildDir, projectDir, name, os ->
println("native build for $name started")
File shareDir = file("$projectDir/src/main/native/share")
if (!shareDir.exists()) {
// TODO
//println("No share lib dir found for $name")
//return
}
def sharedSources = shareDir.listFiles()
def osSources = []
File osDir = file("$projectDir/src/main/native/$os")
if (osDir.exists()) {
osSources = osDir.listFiles()
} else {
println("No native lib dir found for $name at $osDir")
return
}
def JAVAHOME = System.getenv("JAVA_HOME")
def includeFlags = [
"-I$JAVAHOME/include",
"-I$projectDir/../../gradle/include",
]
def osIncludeFlags = ""
if (os == "ios") {
osIncludeFlags = "-I$JAVAHOME/include/darwin"
def linkerOutputs = []
def lipoOutput = "$buildDir/native/ios/lib${name}.a"
def buildSystems = ["iPhoneOS+arm64", "iPhoneSimulator+x86_64"]
buildSystems.each { buildSystem ->
def (platform, arch) = buildSystem.tokenize("+")
if (!file(sdkPath(platform)).exists()) {
println "Skipping native-build on iOS: path for ${platform} doesn't exist"
return
}
osSources = "$projectDir/src/main/native/$os/${name}.m"
def compileOutput = "$buildDir/native/ios/$arch"
new File(compileOutput).mkdirs()
def compileOutputs = ["$buildDir/native/ios/$arch/${name}.o"]
def linkerOutput = "$buildDir/native/ios/$arch/lib${name}.a"
def clangArgs = [
"-xobjective-c",
"-mios-version-min=11.0",
includeFlags,
osIncludeFlags,
"-c",
"-fPIC",
"-arch", arch,
"-isysroot",
sdkPath(platform),
osSources].flatten()
exec {
executable "clang"
args clangArgs
workingDir compileOutput
}
def linkerArgs = [
"-static",
"-framework", "Foundation",
"-framework", "CoreGraphics",
"-framework", "CoreBluetooth",
"-framework", "CoreLocation",
"-framework", "CoreMotion",
"-framework", "CoreText",
"-framework", "UIKit",
"-framework", "QuartzCore",
"-framework", "OpenGLES",
"-framework", "StoreKit",
"-framework", "UserNotifications",
"-arch_only", arch,
"-syslibroot", sdkPath(platform),
"-L${sdkPath(platform)}/usr/lib",
"-o", linkerOutput,
compileOutputs
].flatten()
exec {
executable "libtool"
args linkerArgs
workingDir compileOutput
}
linkerOutputs.add(linkerOutput)
}
// execute lipo to combine all linker output in one archive
def lipoArgs = ["-create", linkerOutputs, "-o", lipoOutput].flatten()
exec {
executable "lipo"
args lipoArgs
}
println("native build for $name finished")
File n = new File(lipoOutput)
if (n.exists()) {
n
}
} else if (os == "android") {
def ndk = System.getenv("ANDROID_NDK")
if (ndk == null) {
throw new GradleException("Error: ANDROID_NDK can't be null")
}
def host = System.getProperty('os.name').toLowerCase().contains("mac") ?
"darwin" : "linux"
def arch = "arm64-v8a"
def compileOutput = "$buildDir/native/$os/$arch"
File outputDir = file(compileOutput)
outputDir.mkdirs()
def platform="aarch64-linux-android21"
def toolchainHome = "$ndk/toolchains/llvm"
def compilerHome = "$toolchainHome/prebuilt/${host}-x86_64"
def compiler = file("$compilerHome/bin/clang").getAbsolutePath()
def linker = file("$compilerHome/bin/llvm-ar").getAbsolutePath()
osIncludeFlags = ["-I$JAVAHOME/include/$host",
"-I$projectDir/../../gradle/include/android",
"-I$projectDir/../util/src/main/native/$os/c"].flatten()
File nativeSourcesDir = file("$projectDir/src/main/native/$os/c/")
osSources = [nativeSourcesDir.listFiles().findAll {it.name.endsWith(".c")}].flatten()
def compilerArgs = ["-target", platform, "-Werror", "-c", "-fPIC",
includeFlags, osIncludeFlags, osSources].flatten()
exec {
executable compiler
args compilerArgs
workingDir compileOutput
}
def linkerObj = [outputDir.listFiles().findAll {it.name.endsWith(".o")}].flatten()
def linkerOutput = "$buildDir/native/$os/lib${name.toLowerCase()}.a"
def linkerArgs = ["rcs", linkerOutput, linkerObj].flatten()
exec {
executable linker
args linkerArgs
}
println("native build for $name finished")
File a = new File(linkerOutput)
if (a.exists()) {
a
}
} else {
// TODO
def compileOutput = "$buildDir/native/$os"
new File(compileOutput).mkdirs()
def compiler = "gcc"
def cargs = [
"-c", includeFlags, osIncludeFlags, sharedSources, osSources
].flatten()
exec {
executable "/usr/bin/gcc"
args cargs
workingDir compileOutput
}
// TODO
File n = new File("$buildDir/native/${os}")
if (n.exists()) {
fileTree("$buildDir/native/${os}").filter { it.isFile() }.files
.first()
}
}
}
private String getServiceName(projectName) {
if (projectName.contains("-")) { // in-app-billing -> InAppBilling
def values = projectName.tokenize("-")
return values.inject("") { name, pn -> name + pn.capitalize() }
}
return projectName.capitalize()
}