Codebase list libnative-platform-java / HEAD build.gradle
HEAD

Tree @HEAD (Download .tar.gz)

build.gradle @HEADraw · history · blame

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.")
}