| 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' |
| // Allow the java executable to be specified via env/property for each architecture. |
| javaExecutable32 = properties['javaExecutable32'] ?: System.env.CONSCRYPT_JAVA_EXECUTABLE_32 |
| javaExecutable64 = properties['javaExecutable64'] ?: System.env.CONSCRYPT_JAVA_EXECUTABLE_64 |
| nativeClassifiers = [] |
| nativeClassifier64Bit = null |
| nativeClassifier32Bit = null |
| nativeConfiguration64Bit = null |
| nativeConfiguration32Bit = null |
| preferredNativeConfiguration = 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) |
| |
| nativeConfiguration64Bit = compileConfigurationName(nativeClassifier64Bit) |
| preferredNativeConfiguration = nativeConfiguration64Bit |
| } |
| if (build32Bit) { |
| nativeClassifier32Bit = classifierFor(osName, arch32Name) |
| nativeClassifiers += nativeClassifier32Bit |
| if (preferredClassifier == null) { |
| preferredClassifier = nativeClassifier32Bit |
| preferredSourceSet = sourceSetName(preferredClassifier) |
| preferredNativeFileDir = nativeResourcesDir(preferredClassifier) |
| } |
| |
| nativeConfiguration32Bit = compileConfigurationName(nativeClassifier32Bit) |
| if (preferredNativeConfiguration == null) { |
| preferredNativeConfiguration = nativeConfiguration32Bit |
| } |
| } |
| } |
| |
| sourceSets { |
| |
| main { |
| java { |
| srcDirs += "${rootDir}/common/src/main/java" |
| srcDirs += project(':conscrypt-constants').sourceSets.main.java.srcDirs |
| } |
| } |
| |
| platform { |
| java { |
| srcDirs = [ "src/main/java" ] |
| includes = [ "org/conscrypt/Platform.java" ] |
| } |
| } |
| |
| 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) |
| def testSourceSetName = testSourceSetName(nativeClassifier) |
| |
| // Main sources for the native build |
| "$sourceSetName" { |
| resources { |
| srcDirs = [nativeResourcesDir(nativeClassifier)] |
| } |
| } |
| |
| // Test sources for the native build |
| "${testSourceSetName}" { |
| java { |
| // Include the test source. |
| srcDirs = test.java.srcDirs |
| } |
| resources { |
| srcDirs = ["src/test/resources"] |
| srcDirs += sourceSets["$sourceSetName"].resources.srcDirs |
| } |
| } |
| } |
| } |
| |
| task platformJar(type: Jar) { |
| from sourceSets.platform.output |
| } |
| |
| configurations { |
| publicApiDocs |
| platform |
| } |
| |
| artifacts { |
| platform platformJar |
| } |
| |
| // Append the BoringSSL-Version to the manifest. |
| jar.manifest { |
| attributes 'BoringSSL-Version' : boringSslVersion |
| } |
| |
| dependencies { |
| // This is used for the @hide annotation processing in JavaDoc |
| publicApiDocs project(':conscrypt-api-doclet') |
| |
| compileOnly project(':conscrypt-constants'), |
| configurations.publicApiDocs |
| |
| testCompile project(':conscrypt-constants'), |
| project(':conscrypt-testing'), |
| libraries.junit, |
| libraries.mockito |
| |
| // Need to add the native artifact to classpath when running the tests. |
| testRuntime configurations["${preferredNativeConfiguration}"] |
| |
| // Configure the dependencies for the native tests. |
| nativeClassifiers.each { nativeClassifier -> |
| def testCompileConfigName = testSourceSet(nativeClassifier).compileConfigurationName |
| "${testCompileConfigName}" ( |
| sourceSets.main.output, // Explicitly add the main classes |
| project(':conscrypt-constants'), |
| project(':conscrypt-testing'), |
| libraries.junit, |
| libraries.mockito |
| ) |
| } |
| |
| 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) |
| |
| // Create the test task and have it auto run whenever the test task runs. |
| addNativeTest(nativeClassifier) |
| |
| // Build the classes as part of the standard build. |
| classes.dependsOn sourceSet(nativeClassifier).classesTaskName |
| testClasses.dependsOn testSourceSet(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 jarTaskName = sourceSet.jarTaskName |
| task "$jarTaskName"(type: Jar) { |
| // Depend on the regular classes task |
| dependsOn classes |
| manifest = jar.manifest |
| classifier = nativeClassifier |
| |
| from sourceSet.output + sourceSets.main.output |
| } |
| |
| def jarTask = tasks["$jarTaskName"] |
| |
| // Add the jar task to the standard build. |
| jar.dependsOn jarTask |
| |
| // Add it to the 'archives' configuration so that the artifact will be automatically built and |
| // installed/deployed. |
| artifacts.add('archives', jarTask) |
| } |
| |
| // Optionally adds a test task for the given platform |
| def addNativeTest(nativeClassifier) { |
| SourceSet testSourceSet = testSourceSet(nativeClassifier) |
| |
| // Just use the same name as the source set for the task. |
| def testTaskName = "${testSourceSet.name}" |
| def javaExecutable |
| def javaArchFlag |
| if (testSourceSet.name.endsWith("${arch32Name}Test")) { |
| // 32-bit test |
| javaExecutable = javaExecutable32 != null ? javaExecutable32 : test.executable |
| javaArchFlag = '-d32' |
| } else { |
| // 64-bit test |
| javaExecutable = javaExecutable64 != null ? javaExecutable64 : test.executable |
| javaArchFlag = '-d64' |
| } |
| |
| // Execute the java executable to see if it supports the architecture flag. |
| def javaError = new ByteArrayOutputStream() |
| exec { |
| executable javaExecutable |
| args = ["$javaArchFlag", '-version'] |
| ignoreExitValue true |
| errorOutput = javaError |
| } |
| |
| // Only add the test if the javaArchFlag is supported for the selected JVM |
| def archSupported = !javaError.toString().toLowerCase().contains('error') |
| if (archSupported) { |
| task "$testTaskName"(type: Test) { |
| dependsOn testSourceSet.classesTaskName |
| jvmArgs javaArchFlag |
| executable = javaExecutable |
| testClassesDir = testSourceSet.output.classesDir |
| |
| // Set the classpath just before we run the test so that the runtime classpath |
| // is fully resolved. |
| doFirst { |
| classpath = testSourceSet.runtimeClasspath |
| } |
| } |
| test.dependsOn "$testTaskName" |
| } |
| } |
| |
| // Exclude all test classes from the default test suite. |
| // We will test each available native artifact separately (see nativeClassifiers). |
| test.exclude("**") |
| |
| javadoc { |
| 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 "**/*.cpp" |
| } |
| } |
| } |
| |
| 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" |
| |
| // Static link to BoringSSL |
| linker.args "-O3", |
| "-fvisibility=hidden", |
| "-lstdc++", |
| libPath + "/ssl/libssl.a", |
| libPath + "/crypto/libcrypto.a" |
| } else if (toolChain in VisualCpp) { |
| cppCompiler.define "DLL_EXPORT" |
| cppCompiler.define "WIN32_LEAN_AND_MEAN" |
| 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 copyTaskName = "copyNativeLib${sourceSetName}" |
| task "$copyTaskName"(type: Copy, dependsOn: binary.buildTask) { |
| 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' |
| } |
| |
| // Make sure we build and copy the native library to the output directory. |
| compileJava.dependsOn "$copyTaskName" |
| |
| // Now define a task to strip the release binary (linux only) |
| def stripTask = binary.tasks.taskName("strip") |
| t.create(stripTask) { |
| dependsOn binary.tasks.link |
| doFirst { |
| if (osName == 'linux') { |
| ["strip", binary.tasks.link.outputFile].execute().waitForOrKill(1000) |
| } |
| } |
| } |
| binary.tasks.build.dependsOn stripTask |
| } |
| } |
| } |
| |
| String nativeResourcesDir(nativeClassifier) { |
| def sourceSetName = sourceSetName(nativeClassifier) |
| "${buildDir}/${sourceSetName}/resources" |
| } |
| |
| SourceSet sourceSet(classifier) { |
| sourceSets[sourceSetName(classifier)] |
| } |
| |
| SourceSet testSourceSet(classifier) { |
| sourceSets[testSourceSetName(classifier)] |
| } |
| |
| static String classifierFor(osName, archName) { |
| "${osName}-${archName}" |
| } |
| |
| static String sourceSetName(classifier) { |
| classifier.replaceAll("-", "_") |
| } |
| |
| static String testSourceSetName(classifier) { |
| "${sourceSetName(classifier)}Test" |
| } |
| |
| static String compileConfigurationName(classifier) { |
| sourceSetName(classifier) + "Compile" |
| } |
| |