import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
apply plugin: 'groovy'
apply plugin: 'cpp'
allprojects {
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'maven'
repositories {
mavenCentral()
maven { url "http://repo.gradle.org/gradle/libs-releases-local" }
maven { url "http://repo.gradle.org/gradle/libs-snapshots-local" }
}
dependencies {
testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
}
group = 'net.rubygrapefruit'
version = '0.14'
if (!project.hasProperty('release')) {
version = "${version}-dev"
}
sourceCompatibility = 1.5
targetCompatibility = 1.5
tasks.withType(Upload) {
repositories {
mavenDeployer {
if (project.hasProperty('release')) {
repository(url: uri("https://gradle.artifactoryonline.com/gradle/libs-releases-local")) {
authentication(userName: artifactoryUserName, password: artifactoryPassword)
}
} else if (project.hasProperty('snapshot')) {
repository(url: uri("https://gradle.artifactoryonline.com/gradle/libs-snapshots-local")) {
authentication(userName: artifactoryUserName, password: artifactoryPassword)
}
} else {
repository(url: uri("$rootProject.buildDir/repo"))
}
}
}
}
}
dependencies {
testCompile 'org.codehaus.groovy:groovy-all:2.4.1'
}
def nativeHeadersDir = file("$buildDir/nativeHeaders")
task nativeHeaders {
def outputFile = file("$nativeHeadersDir/native.h")
def classes = [
'net.rubygrapefruit.platform.internal.jni.NativeLibraryFunctions',
'net.rubygrapefruit.platform.internal.jni.PosixFileFunctions',
'net.rubygrapefruit.platform.internal.jni.PosixFileSystemFunctions',
'net.rubygrapefruit.platform.internal.jni.PosixProcessFunctions',
'net.rubygrapefruit.platform.internal.jni.PosixTerminalFunctions',
'net.rubygrapefruit.platform.internal.jni.TerminfoFunctions',
'net.rubygrapefruit.platform.internal.jni.WindowsConsoleFunctions',
'net.rubygrapefruit.platform.internal.jni.WindowsHandleFunctions',
'net.rubygrapefruit.platform.internal.jni.WindowsRegistryFunctions',
'net.rubygrapefruit.platform.internal.jni.WindowsFileFunctions',
'net.rubygrapefruit.platform.internal.jni.FileEventFunctions',
'net.rubygrapefruit.platform.internal.jni.PosixTypeFunctions',
'net.rubygrapefruit.platform.internal.jni.MemoryFunctions',
'net.rubygrapefruit.platform.internal.jni.OsxMemoryFunctions'
]
inputs.files sourceSets.main.output
inputs.property('classes', classes)
outputs.file outputFile
doLast {
outputFile.parentFile.mkdirs()
exec {
executable org.gradle.internal.jvm.Jvm.current().getExecutable('javah')
args '-o', outputFile
args '-classpath', sourceSets.main.output.classesDir
args classes
}
}
}
configurations {
jni
}
def deployer = uploadJni.repositories.mavenDeployer
def publications = new LinkedHashSet()
// Using internal classes here to make this simple
def os = new DefaultNativePlatform("current").operatingSystem
def arch = new DefaultNativePlatform("current").architecture
def ncursesVersion = inferNCursesVersion(os)
model {
platforms {
osx_i386 {
architecture "i386"
operatingSystem "osx"
}
osx_amd64 {
architecture "amd64"
operatingSystem "osx"
}
linux_i386 {
architecture "i386"
operatingSystem "linux"
}
linux_i386_ncurses5 {
architecture "i386"
operatingSystem "linux"
}
linux_i386_ncurses6 {
architecture "i386"
operatingSystem "linux"
}
linux_amd64 {
architecture "amd64"
operatingSystem "linux"
}
linux_amd64_ncurses5 {
architecture "amd64"
operatingSystem "linux"
}
linux_amd64_ncurses6 {
architecture "amd64"
operatingSystem "linux"
}
windows_i386 {
architecture "i386"
operatingSystem "windows"
}
windows_amd64 {
architecture "amd64"
operatingSystem "windows"
}
freebsd_i386_libcpp {
architecture "i386"
operatingSystem "freebsd"
}
freebsd_i386_libstdcpp {
architecture "i386"
operatingSystem "freebsd"
}
freebsd_amd64_libcpp {
architecture "amd64"
operatingSystem "freebsd"
}
freebsd_amd64_libstdcpp {
architecture "amd64"
operatingSystem "freebsd"
}
}
toolChains {
gcc(Gcc) {
eachPlatform {
// Use GCC to build for libstdc++ on FreeBSD
if (platform.operatingSystem.freeBSD) {
if (platform.name.contains('libstdcpp')) {
cCompiler.executable = 'cc'
cppCompiler.executable = 'c++'
linker.executable = 'c++'
} else {
// Use a dummy so that GCC is not selected
cCompiler.executable = 'dummy'
cppCompiler.executable = 'dummy'
objcCompiler.executable = 'dummy'
objcppCompiler.executable = 'dummy'
assembler.executable = 'dummy'
linker.executable = 'dummy'
staticLibArchiver.executable = 'dummy'
}
}
}
}
clang(Clang) {
eachPlatform {
// Use Clang to build for libc++ on FreeBSD
if (platform.operatingSystem.freeBSD) {
if (platform.name.contains('libcpp')) {
cCompiler.executable = 'cc'
cppCompiler.executable = 'c++'
linker.executable = 'c++'
} else {
// Use a dummy so that Clang is not selected
cCompiler.executable = 'dummy'
cppCompiler.executable = 'dummy'
objcCompiler.executable = 'dummy'
objcppCompiler.executable = 'dummy'
assembler.executable = 'dummy'
linker.executable = 'dummy'
staticLibArchiver.executable = 'dummy'
}
}
}
}
visualCpp(VisualCpp)
}
components {
nativePlatform(NativeLibrarySpec) {
baseName 'native-platform'
// TODO - this should be the default. Figure out why this is not working
$.platforms.each { p ->
if (p.name.contains("ncurses")) {
return
}
targetPlatform p.name
}
sources {
cpp {
source.srcDirs = ['src/shared/cpp', 'src/main/cpp']
exportedHeaders.srcDirs = ['src/shared/headers']
}
}
}
nativePlatformCurses(NativeLibrarySpec) {
baseName 'native-platform-curses'
$.platforms.each { p ->
if (p.operatingSystem.windows) {
return
}
if (p.operatingSystem.linux && !p.name.contains("ncurses")) {
return
}
targetPlatform p.name
}
sources {
cpp {
source.srcDirs = ['src/shared/cpp', 'src/curses/cpp']
exportedHeaders.srcDirs = ['src/shared/headers']
}
}
binaries.all {
if (targetPlatform.operatingSystem.linux && !targetPlatform.name.contains("curses${ncursesVersion}")) {
buildable = false
}
linker.args "-lcurses"
}
}
all {
binaries.all {
if (targetPlatform.operatingSystem.name in ['linux', 'freebsd'] && targetPlatform.architecture != arch) {
// Native plugins don't detect whether multilib support is available or not. Assume not for now
buildable = false
}
if (targetPlatform.operatingSystem.macOsX) {
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/darwin"
cppCompiler.args '-mmacosx-version-min=10.4'
linker.args '-mmacosx-version-min=10.4'
} else if (targetPlatform.operatingSystem.linux) {
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/linux"
cppCompiler.args '-D_FILE_OFFSET_BITS=64'
} else if (targetPlatform.operatingSystem.windows) {
cppCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cppCompiler.args "-I${org.gradle.internal.jvm.Jvm.current().javaHome}/include/win32"
linker.args "Shlwapi.lib", "Advapi32.lib"
} else if (targetPlatform.operatingSystem.freeBSD) {
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include"
cppCompiler.args '-I', "${org.gradle.internal.jvm.Jvm.current().javaHome}/include/freebsd"
}
cppCompiler.args "-I${nativeHeadersDir}"
tasks.withType(CppCompile) { task ->
task.dependsOn project.tasks.nativeHeaders
}
}
binaries.withType(SharedLibraryBinarySpec) { binary ->
def variantName = targetPlatform.name.replace('_', '-')
publications << variantName
if (!buildable) {
return
}
def taskName = "jar-${variantName}"
def nativeJar = project.tasks.findByName(taskName)
if (nativeJar == null) {
nativeJar = project.tasks.create(taskName, Jar) {
baseName = "native-platform-$variantName"
}
artifacts {
jni nativeJar
runtime nativeJar
}
def jniPom = deployer.addFilter(variantName) { artifact, file ->
return file == nativeJar.archivePath
}
jniPom.groupId = project.group
jniPom.artifactId = nativeJar.baseName
jniPom.version = project.version
jniPom.scopeMappings.mappings.clear()
}
binary.tasks.withType(LinkSharedLibrary) { builderTask ->
nativeJar.into("net/rubygrapefruit/platform/$variantName") { from builderTask.outputFile }
nativeJar.dependsOn builderTask
}
project.tasks.test {
dependsOn nativeJar
classpath.from nativeJar
}
}
}
}
}
javadoc {
exclude '**/internal/**'
}
task sourceZip(type: Zip) {
from sourceSets.main.allSource
classifier = 'sources'
extension = 'jar'
}
task javadocZip(type: Zip) {
from javadoc
classifier = 'javadoc'
extension = 'jar'
}
artifacts {
archives sourceZip
archives javadocZip
}
def mainPom = uploadArchives.repositories.mavenDeployer.pom
mainPom.groupId = project.group
mainPom.artifactId = jar.baseName
mainPom.version = project.version
mainPom.scopeMappings.mappings.clear()
mainPom.withXml { provider ->
def node = provider.asNode()
def deps = node.appendNode('dependencies')
publications.each { p ->
def dep = deps.appendNode('dependency')
dep.appendNode('groupId', project.group)
dep.appendNode('artifactId', "native-platform-${p}")
dep.appendNode('version', project.version)
}
}
String inferNCursesVersion(def os) {
if (!os.linux) {
return "5"
}
for (def d: ["/lib", "/lib64", "/lib/x86_64-linux-gnu"]) {
if (new File("$d/libncurses.so.6").file) {
return "6"
}
if (new File("$d/libncurses.so.5").file) {
return "5"
}
}
throw new IllegalArgumentException("Could not determine ncurses version installed on this machine.")
}