422 lines
15 KiB
Groovy
422 lines
15 KiB
Groovy
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"
|
|
}
|
|
|