478 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Groovy
		
	
	
	
			
		
		
	
	
			478 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Groovy
		
	
	
	
plugins {
 | 
						|
    id 'com.github.johnrengelman.shadow' version '6.0.0'
 | 
						|
}
 | 
						|
 | 
						|
import aQute.bnd.gradle.BundleTaskConvention
 | 
						|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
 | 
						|
import org.codehaus.groovy.runtime.InvokerHelper
 | 
						|
 | 
						|
apply plugin: 'biz.aQute.bnd.builder'
 | 
						|
 | 
						|
description = 'Conscrypt: OpenJdk'
 | 
						|
 | 
						|
ext {
 | 
						|
    jniSourceDir = "$rootDir/common/src/jni"
 | 
						|
    assert file("$jniSourceDir").exists()
 | 
						|
 | 
						|
    // Build the list of classifiers that will be used in the build.
 | 
						|
    arch32Name = 'x86'
 | 
						|
    arch64Name = 'x86_64'
 | 
						|
    nativeClassifiers = []
 | 
						|
    nativeClassifier64Bit = null
 | 
						|
    nativeClassifier32Bit = null
 | 
						|
    preferredClassifier = null
 | 
						|
    preferredSourceSet = null
 | 
						|
    preferredNativeFileDir = null
 | 
						|
    if (build64Bit) {
 | 
						|
        // Add the 64-Bit classifier first, as the preferred classifier.
 | 
						|
        nativeClassifier64Bit = classifierFor(osName, arch64Name)
 | 
						|
        nativeClassifiers += nativeClassifier64Bit
 | 
						|
        preferredClassifier = nativeClassifier64Bit
 | 
						|
        preferredSourceSet = sourceSetName(preferredClassifier)
 | 
						|
        preferredNativeFileDir = nativeResourcesDir(preferredClassifier)
 | 
						|
    }
 | 
						|
    if (build32Bit) {
 | 
						|
        nativeClassifier32Bit = classifierFor(osName, arch32Name)
 | 
						|
        nativeClassifiers += nativeClassifier32Bit
 | 
						|
        if (preferredClassifier == null) {
 | 
						|
            preferredClassifier = nativeClassifier32Bit
 | 
						|
            preferredSourceSet = sourceSetName(preferredClassifier)
 | 
						|
            preferredNativeFileDir = nativeResourcesDir(preferredClassifier)
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
sourceSets {
 | 
						|
 | 
						|
    main {
 | 
						|
        java {
 | 
						|
            srcDirs += "${rootDir}/common/src/main/java"
 | 
						|
            srcDirs += project(':conscrypt-constants').sourceSets.main.java.srcDirs
 | 
						|
        }
 | 
						|
        resources {
 | 
						|
            srcDirs += "build/generated/resources"
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    platform {
 | 
						|
        java {
 | 
						|
            srcDirs = [ "src/main/java" ]
 | 
						|
            includes = [ "org/conscrypt/Platform.java" ]
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    test {
 | 
						|
        java {
 | 
						|
            srcDirs += "${rootDir}/common/src/test/java"
 | 
						|
        }
 | 
						|
        resources {
 | 
						|
            srcDirs += "${rootDir}/common/src/test/resources"
 | 
						|
            // This shouldn't be needed but seems to help IntelliJ locate the native artifact.
 | 
						|
            srcDirs += preferredNativeFileDir
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Add the source sets for each of the native build
 | 
						|
    nativeClassifiers.each { nativeClassifier ->
 | 
						|
        def sourceSetName = sourceSetName(nativeClassifier)
 | 
						|
 | 
						|
        // Main sources for the native build
 | 
						|
        "$sourceSetName" {
 | 
						|
            output.dir(nativeResourcesDir(nativeClassifier), builtBy: "copyNativeLib${sourceSetName}")
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
compileJava {
 | 
						|
    dependsOn generateProperties
 | 
						|
}
 | 
						|
 | 
						|
tasks.register("platformJar", Jar) {
 | 
						|
    from sourceSets.platform.output
 | 
						|
}
 | 
						|
 | 
						|
tasks.register("testJar", ShadowJar) {
 | 
						|
    classifier = 'tests'
 | 
						|
    configurations = [project.configurations.testRuntime]
 | 
						|
    from sourceSets.test.output
 | 
						|
}
 | 
						|
 | 
						|
if (isExecutableOnPath('cpplint')) {
 | 
						|
    def cpplint = tasks.register("cpplint", Exec) {
 | 
						|
        executable = 'cpplint'
 | 
						|
 | 
						|
        // TODO(nmittler): Is there a better way of getting the JNI sources?
 | 
						|
        def pattern = ['**/*.cc', '**/*.h']
 | 
						|
        def sourceFiles = fileTree(dir: jniSourceDir, includes: pattern).asPath.tokenize(':')
 | 
						|
        // Adding roots so that class #ifdefs don't require full path from the project root.
 | 
						|
        args = sourceFiles
 | 
						|
 | 
						|
        // Capture stderr from the process
 | 
						|
        errorOutput = new ByteArrayOutputStream();
 | 
						|
 | 
						|
        // Need to ignore exit value so that doLast will execute.
 | 
						|
        ignoreExitValue = true
 | 
						|
 | 
						|
        doLast {
 | 
						|
            // Create the report file.
 | 
						|
            def reportDir = file("${buildDir}/cpplint")
 | 
						|
            reportDir.mkdirs();
 | 
						|
            def reportFile = new File(reportDir, "report.txt")
 | 
						|
            def reportStream = new FileOutputStream(reportFile)
 | 
						|
 | 
						|
            try {
 | 
						|
                // Check for failure
 | 
						|
                if (execResult != null) {
 | 
						|
                    execResult.assertNormalExitValue()
 | 
						|
                }
 | 
						|
            } catch (Exception e) {
 | 
						|
                // The process failed - get the error report from the stderr.
 | 
						|
                String report = errorOutput.toString();
 | 
						|
 | 
						|
                // Write the report to the console.
 | 
						|
                System.err.println(report)
 | 
						|
 | 
						|
                // Also write the report file.
 | 
						|
                reportStream.write(report.bytes);
 | 
						|
 | 
						|
                // Extension method cpplint.output() can be used to obtain the report
 | 
						|
                ext.output = {
 | 
						|
                    return report
 | 
						|
                }
 | 
						|
 | 
						|
                // Rethrow the exception to terminate the build.
 | 
						|
                throw e;
 | 
						|
            } finally {
 | 
						|
                reportStream.close();
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    check.dependsOn cpplint
 | 
						|
}
 | 
						|
 | 
						|
configurations {
 | 
						|
    publicApiDocs
 | 
						|
    platform
 | 
						|
}
 | 
						|
 | 
						|
artifacts {
 | 
						|
    platform platformJar
 | 
						|
}
 | 
						|
 | 
						|
apply from: "$rootDir/gradle/publishing.gradle"
 | 
						|
publishing.publications.maven {
 | 
						|
    artifact sourcesJar
 | 
						|
    artifact javadocJar
 | 
						|
}
 | 
						|
 | 
						|
jar.manifest {
 | 
						|
    attributes ('BoringSSL-Version' : boringSslVersion,
 | 
						|
                'Automatic-Module-Name' : 'org.conscrypt',
 | 
						|
                'Bundle-SymbolicName': 'org.conscrypt',
 | 
						|
                '-exportcontents': 'org.conscrypt.*')
 | 
						|
}
 | 
						|
 | 
						|
dependencies {
 | 
						|
    // This is used for the @Internal annotation processing in JavaDoc
 | 
						|
    publicApiDocs project(':conscrypt-api-doclet')
 | 
						|
 | 
						|
    // This is listed as compile-only, but we absorb its contents.
 | 
						|
    compileOnly project(':conscrypt-constants')
 | 
						|
 | 
						|
    testCompile project(':conscrypt-constants'),
 | 
						|
            project(path: ':conscrypt-testing', configuration: 'runtime'),
 | 
						|
            libraries.junit,
 | 
						|
            libraries.mockito
 | 
						|
 | 
						|
    testRuntimeClasspath sourceSets["$preferredSourceSet"].output
 | 
						|
 | 
						|
    platformCompileOnly sourceSets.main.output
 | 
						|
}
 | 
						|
 | 
						|
nativeClassifiers.each { nativeClassifier ->
 | 
						|
    // Create the JAR task and add it's output to the published archives for this project
 | 
						|
    addNativeJar(nativeClassifier)
 | 
						|
 | 
						|
    // Build the classes as part of the standard build.
 | 
						|
    classes.dependsOn sourceSet(nativeClassifier).classesTaskName
 | 
						|
}
 | 
						|
 | 
						|
// Adds a JAR task for the native library.
 | 
						|
def addNativeJar(nativeClassifier) {
 | 
						|
    // Create a JAR for this configuration and add it to the output archives.
 | 
						|
    SourceSet sourceSet = sourceSet(nativeClassifier)
 | 
						|
    def jarTask = tasks.register(sourceSet.jarTaskName, Jar) { Jar t ->
 | 
						|
        // Depend on the regular classes task
 | 
						|
        dependsOn classes
 | 
						|
        manifest = jar.manifest
 | 
						|
        classifier = nativeClassifier
 | 
						|
 | 
						|
        from sourceSet.output + sourceSets.main.output
 | 
						|
 | 
						|
        // add OSGI headers
 | 
						|
        t.convention.plugins.bundle = new BundleTaskConvention(t)
 | 
						|
        t.doLast {
 | 
						|
            t.buildBundle()
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    // Add the jar task to the standard build.
 | 
						|
    jar.dependsOn jarTask
 | 
						|
 | 
						|
    // Add it to the publishing archives list.
 | 
						|
    publishing.publications.maven.artifact jarTask.get()
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Check which version
 | 
						|
def javaError = new ByteArrayOutputStream()
 | 
						|
exec {
 | 
						|
    executable test.executable
 | 
						|
    System.out.println("Running tests with java executable: " + test.executable + ".")
 | 
						|
    args = ['-version']
 | 
						|
    ignoreExitValue true
 | 
						|
    errorOutput = javaError
 | 
						|
}
 | 
						|
 | 
						|
def suiteClass = (javaError.toString() =~ /"1[.]7[.].*"/) ?
 | 
						|
        "org/conscrypt/ConscryptJava7Suite.class" : "org/conscrypt/ConscryptSuite.class";
 | 
						|
 | 
						|
test {
 | 
						|
    include suiteClass, "org/conscrypt/ConscryptOpenJdkSuite.class"
 | 
						|
}
 | 
						|
 | 
						|
def testFdSocket = tasks.register("testFdSocket", Test) {
 | 
						|
    include suiteClass, "org/conscrypt/ConscryptOpenJdkSuite.class"
 | 
						|
    InvokerHelper.setProperties(testLogging, test.testLogging.properties)
 | 
						|
    systemProperties = test.systemProperties
 | 
						|
    systemProperty "org.conscrypt.useEngineSocketByDefault", false
 | 
						|
}
 | 
						|
check.dependsOn testFdSocket
 | 
						|
 | 
						|
// Tests that involve interoperation with the OpenJDK TLS provider (generally to
 | 
						|
// test renegotiation, since we don't support initiating renegotiation but do
 | 
						|
// support peer-initiated renegotiation).  The JDK TLS provider doesn't work
 | 
						|
// if Conscrypt is installed as the default provider, so these need to live in
 | 
						|
// a different task than the other tests, most of which need Conscrypt to be
 | 
						|
// installed to function.
 | 
						|
def testInterop = tasks.register("testInterop", Test) {
 | 
						|
    include "org/conscrypt/ConscryptEngineTest.class"
 | 
						|
    include "org/conscrypt/RenegotiationTest.class"
 | 
						|
}
 | 
						|
check.dependsOn testInterop
 | 
						|
 | 
						|
jacocoTestReport {
 | 
						|
    additionalSourceDirs.from files("$rootDir/openjdk/src/test/java", "$rootDir/common/src/main/java")
 | 
						|
    executionData tasks.withType(Test)
 | 
						|
}
 | 
						|
 | 
						|
javadoc {
 | 
						|
    dependsOn(configurations.publicApiDocs)
 | 
						|
    options.doclet = "org.conscrypt.doclet.FilterDoclet"
 | 
						|
    options.docletpath = configurations.publicApiDocs.files as List
 | 
						|
}
 | 
						|
 | 
						|
model {
 | 
						|
    platforms {
 | 
						|
        x86 {
 | 
						|
            architecture arch32Name
 | 
						|
        }
 | 
						|
        x86_64 {
 | 
						|
            architecture arch64Name
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    buildTypes {
 | 
						|
        release
 | 
						|
    }
 | 
						|
 | 
						|
    components {
 | 
						|
        // Builds the JNI library.
 | 
						|
        conscrypt_openjdk_jni(NativeLibrarySpec) {
 | 
						|
            if (build32Bit) { targetPlatform arch32Name }
 | 
						|
            if (build64Bit) { targetPlatform arch64Name }
 | 
						|
 | 
						|
            sources {
 | 
						|
                cpp {
 | 
						|
                    source {
 | 
						|
                        srcDirs "$jniSourceDir/main/cpp"
 | 
						|
                        include "**/*.cc"
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            binaries {
 | 
						|
                // Build the JNI lib as a shared library.
 | 
						|
                withType (SharedLibraryBinarySpec) {
 | 
						|
                    cppCompiler.define "CONSCRYPT_OPENJDK"
 | 
						|
 | 
						|
                    // Set up 32-bit vs 64-bit build
 | 
						|
                    def building64Bit = false
 | 
						|
                    def libPath
 | 
						|
                    if (targetPlatform.getArchitecture().getName() == "x86") {
 | 
						|
                        libPath = "$boringssl32BuildDir"
 | 
						|
                    } else if (targetPlatform.getArchitecture().getName() == "x86-64") {
 | 
						|
                        libPath = "$boringssl64BuildDir"
 | 
						|
                        building64Bit = true
 | 
						|
                    } else {
 | 
						|
                        throw new GradleException("Unknown architecture: " +
 | 
						|
                                targetPlatform.getArchitecture().name)
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (toolChain in Clang || toolChain in Gcc) {
 | 
						|
                        cppCompiler.args "-Wall",
 | 
						|
                                "-fPIC",
 | 
						|
                                "-O3",
 | 
						|
                                "-std=c++11",
 | 
						|
                                "-I$jniSourceDir/main/include",
 | 
						|
                                "-I$jniSourceDir/unbundled/include",
 | 
						|
                                "-I$boringsslIncludeDir",
 | 
						|
                                "-I$jdkIncludeDir",
 | 
						|
                                "-I$jdkIncludeDir/linux",
 | 
						|
                                "-I$jdkIncludeDir/darwin",
 | 
						|
                                "-I$jdkIncludeDir/win32"
 | 
						|
                        if (rootProject.hasProperty('checkErrorQueue')) {
 | 
						|
                            System.out.println("Compiling with error queue checking enabled")
 | 
						|
                            cppCompiler.define "CONSCRYPT_CHECK_ERROR_QUEUE"
 | 
						|
                        }
 | 
						|
 | 
						|
                        // Static link to BoringSSL
 | 
						|
                        linker.args "-O3",
 | 
						|
                                "-fvisibility=hidden",
 | 
						|
                                "-lpthread",
 | 
						|
                                libPath + "/ssl/libssl.a",
 | 
						|
                                libPath + "/crypto/libcrypto.a"
 | 
						|
                        if (targetPlatform.operatingSystem.isLinux()) {
 | 
						|
                            // Static link libstdc++ and libgcc because
 | 
						|
                            // they are not available in some restrictive Linux
 | 
						|
                            // environments.
 | 
						|
                            linker.args "-static-libstdc++",
 | 
						|
                                    "-static-libgcc"
 | 
						|
                        } else {
 | 
						|
                            linker.args "-lstdc++"
 | 
						|
                        }
 | 
						|
                    } else if (toolChain in VisualCpp) {
 | 
						|
                        cppCompiler.define "DLL_EXPORT"
 | 
						|
                        cppCompiler.define "WIN32_LEAN_AND_MEAN"
 | 
						|
                        cppCompiler.define "NOMINMAX"
 | 
						|
                        if (building64Bit) {
 | 
						|
                            cppCompiler.define "WIN64"
 | 
						|
                        }
 | 
						|
                        cppCompiler.define "_WINDOWS"
 | 
						|
                        cppCompiler.define "UNICODE"
 | 
						|
                        cppCompiler.define "_UNICODE"
 | 
						|
                        cppCompiler.define "NDEBUG"
 | 
						|
 | 
						|
                        cppCompiler.args "/nologo",
 | 
						|
                                "/MT",
 | 
						|
                                "/WX-",
 | 
						|
                                "/Wall",
 | 
						|
                                "/O2",
 | 
						|
                                "/Oi",
 | 
						|
                                "/Ot",
 | 
						|
                                "/GL",
 | 
						|
                                "/GS",
 | 
						|
                                "/Gy",
 | 
						|
                                "/fp:precise",
 | 
						|
                                "-wd4514", // Unreferenced inline function removed
 | 
						|
                                "-wd4548", // Expression before comma has no effect
 | 
						|
                                "-wd4625", // Copy constructor was implicitly defined as deleted
 | 
						|
                                "-wd4626", // Assignment operator was implicitly defined as deleted
 | 
						|
                                "-wd4710", // function not inlined
 | 
						|
                                "-wd4711", // function inlined
 | 
						|
                                "-wd4820", // Extra padding added to struct
 | 
						|
                                "-wd4946", // reinterpret_cast used between related classes:
 | 
						|
                                "-wd4996", // Thread safety for strerror
 | 
						|
                                "-wd5027", // Move assignment operator was implicitly defined as deleted
 | 
						|
                                "-I$jniSourceDir/main/include",
 | 
						|
                                "-I$jniSourceDir/unbundled/include",
 | 
						|
                                "-I$boringsslIncludeDir",
 | 
						|
                                "-I$jdkIncludeDir",
 | 
						|
                                "-I$jdkIncludeDir/win32"
 | 
						|
 | 
						|
                        // Static link to BoringSSL
 | 
						|
                        linker.args "-WX",
 | 
						|
                                "ws2_32.lib",
 | 
						|
                                "advapi32.lib",
 | 
						|
                                "${libPath}\\ssl\\ssl.lib",
 | 
						|
                                "${libPath}\\crypto\\crypto.lib"
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                // Never build a static library.
 | 
						|
                withType(StaticLibraryBinarySpec) {
 | 
						|
                    buildable = false
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    tasks { t ->
 | 
						|
        $.binaries.withType(SharedLibraryBinarySpec).each { binary ->
 | 
						|
            // Build the native artifact classifier from the OS and architecture.
 | 
						|
            def archName = binary.targetPlatform.architecture.name.replaceAll('-', '_')
 | 
						|
            def classifier = classifierFor(osName, archName)
 | 
						|
            def sourceSetName = sourceSetName("$classifier")
 | 
						|
            def source = binary.sharedLibraryFile
 | 
						|
 | 
						|
            // Copies the native library to a resource location that will be included in the jar.
 | 
						|
            def copyTask = project.tasks.register("copyNativeLib${sourceSetName}", Copy) {
 | 
						|
                dependsOn binary.tasks.link
 | 
						|
                from source
 | 
						|
                // Rename the artifact to include the generated classifier
 | 
						|
                rename '(.+)(\\.[^\\.]+)', "\$1-$classifier\$2"
 | 
						|
                // Everything under will be included in the native jar.
 | 
						|
                into nativeResourcesDir(classifier) + '/META-INF/native'
 | 
						|
            }
 | 
						|
 | 
						|
            // Now define a task to strip the release binary (linux only)
 | 
						|
            if (osName == 'linux' && (!rootProject.hasProperty('nostrip') ||
 | 
						|
                    !rootProject.nostrip.toBoolean())) {
 | 
						|
                def stripTask = binary.tasks.taskName("strip")
 | 
						|
                project.tasks.register(stripTask as String, Exec) {
 | 
						|
                    dependsOn binary.tasks.link
 | 
						|
                    executable "strip"
 | 
						|
                    args binary.tasks.link.linkedFile.asFile.get()
 | 
						|
                }
 | 
						|
                copyTask.configure {
 | 
						|
                    dependsOn stripTask
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
boolean isExecutableOnPath(executable) {
 | 
						|
    FilenameFilter filter = new FilenameFilter() {
 | 
						|
        @Override
 | 
						|
        boolean accept(File dir, String name) {
 | 
						|
            return executable.equals(name);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    for(String folder : System.getenv('PATH').split("" + File.pathSeparatorChar)) {
 | 
						|
        File[] files = file(folder).listFiles(filter)
 | 
						|
        if (files != null && files.size() > 0) {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
String nativeResourcesDir(nativeClassifier) {
 | 
						|
    def sourceSetName = sourceSetName(nativeClassifier)
 | 
						|
    "${buildDir}/${sourceSetName}/native-resources"
 | 
						|
}
 | 
						|
 | 
						|
SourceSet sourceSet(classifier) {
 | 
						|
    sourceSets[sourceSetName(classifier)]
 | 
						|
}
 | 
						|
 | 
						|
static String classifierFor(osName, archName) {
 | 
						|
    "${osName}-${archName}"
 | 
						|
}
 | 
						|
 | 
						|
static String sourceSetName(classifier) {
 | 
						|
    classifier.replaceAll("-", "_")
 | 
						|
}
 | 
						|
 |