// Global settings project.ext { // Source JRE used for compilation, etc if (!project.hasProperty('jre')) { jre = System.getProperty('java.home') } os = Os.current() arch = Arch.current() if (!project.hasProperty('targetJre')) { targetJre = jre } } def targetJreFile = file(targetJre) def jreFile = file(jre) // HotSpot itself project('hotspot') { task clean(type: InvokeMake) { onlyIf { file('hotspot').exists() } args 'clean' } task prepareJvm { onlyIf { jreFile.canonicalPath != targetJreFile.canonicalPath } doLast { ant.copy(todir: targetJreFile) { fileset(dir: jreFile) } ant.chmod(file: new File(targetJreFile, 'bin/java'), perm: '0755') } } task clone(description: 'Clone HotSpot repository') { onlyIf { !file('hotspot').exists() } doLast { exec { workingDir '..' executable 'hg' args 'clone', hotspotRepository } } } task patch(description: 'Patch HotSpot sources', dependsOn: clone) << { exec { executable 'hg' args 'pull' } exec { executable 'hg' args 'update', '-C', '-r', hotspotTag } new ByteArrayOutputStream().withStream { os -> exec { workingDir 'hotspot' executable 'hg' args 'status' standardOutput os } // Purge unversioned files def str = os.toString() def matcher = str =~ /(?m)^\?\s+(.*)$/ matcher.each { ant.delete(file: new File(file('hotspot'), it[1])) } } // Use hg import since ant.patchfile requires 'patch' to be installed exec { executable 'hg' args 'import', '--no-commit', "../patches/${flavor}-${hotspotTag}.patch" } } def arguments = ['product': ['ENABLE_FULL_DEBUG_SYMBOLS=0'], 'fastdebug': ['ENABLE_FULL_DEBUG_SYMBOLS=1', 'STRIP_POLICY=no_strip', 'ZIP_DEBUGINFO_FILES=0']] ['product', 'fastdebug'].each { k -> // Compile given kind of DCEVM def compile = task("compile${k.capitalize()}", type: InvokeMake) { args arguments[k] args k doLast { ant.copy(todir: "build/${k}", overwrite: true) { fileset(dir: "build/${os.buildPath}/${os.buildPath}_${arch.buildArch}_${compiler}/${k}", includes: 'libjvm.so,libjsig.so,jvm.dll,jsig.dll,libjvm.dylib,libjsig.dylib') } } } compile.mustRunAfter(patch) // Install given kind of DCEVM into destination JRE task("install${k.capitalize()}", dependsOn: [prepareJvm, compile]) << { def installPath = new File(new File(targetJreFile, arch == Arch.X86 ? os.installPath32 : os.installPath64), jvmName) logger.info("Installing DCEVM runtime into JRE with JVM name '${jvmName}' and kind '${k}' at ${installPath}") ant.copy(todir: installPath, overwrite: true) { fileset(dir: "build/${os.buildPath}/${os.buildPath}_${arch.buildArch}_${compiler}/${k}", includes: 'libjvm.so,libjsig.so,jvm.dll,jsig.dll,libjvm.dylib,libjsig.dylib') } } } } // Java projects for testing DCEVM def setup(prjs, closure) { prjs.each { prj -> project(prj, closure) } } setup(['agent', 'dcevm'], { apply plugin: 'java' apply plugin: 'idea' repositories { mavenCentral() } }) project('agent') { jar { manifest { from "src/main/java/META-INF/MANIFEST.MF" } } } project('native') { apply plugin: 'base' task compile(type: Exec) { doFirst { buildDir.mkdirs() } if (os != Os.WINDOWS) { commandLine 'gcc' args "-I${jre}/../include" args "-I${jre}/../include/linux" args '-shared' args 'natives.c' args '-o' args 'build/libnatives.so' } else { commandLine 'cmd', '/c', 'compile.cmd' environment ARCH: arch == Arch.X86 ? 'x86' : 'x64' environment JAVA_HOME: jre } } } project('dcevm') { dependencies { compile project(':agent') compile group: 'asm', name: 'asm-all', version: '3.3.+' compile files(jre + '/../lib/tools.jar') testCompile group: 'junit', name: 'junit', version: '4.11' } def m = System.getProperty('java.version') =~ /^1\.([0-9]+)\.*/ def major = m[0][1].toInteger() if (major >= 7) { sourceSets.test.java.srcDirs += 'src/test/java7' } if (major >= 8) { sourceSets.test.java.srcDirs += 'src/test/java8' } test { executable new File(targetJreFile, 'bin/java') systemProperty 'dcevm.test.light', (flavor == 'light') if (kind == 'fastdebug') { jvmArgs '-XX:LogFile=build/hotspot.log' } jvmArgs "-XXaltjvm=${jvmName}" jvmArgs '-javaagent:../agent/build/libs/agent.jar' if (arch == Arch.X86_64) { jvmArgs(project.oops == "compressed" ? '-XX:+UseCompressedOops' : "-XX:-UseCompressedOops") } jvmArgs "-XX:TraceRedefineClasses=${traceRedefinition}" ignoreFailures = true outputs.upToDateWhen { false } useJUnit { excludeCategories ('com.github.dcevm.test.category.' + (flavor == 'light' ? 'Full' : 'Light')) } } test.dependsOn project(':hotspot').tasks[kind == 'fastdebug' ? 'installFastdebug' : 'installProduct'] } enum Arch { X86(["i386", "i486", "i586", "x86"], 'i486', 32), X86_64(["x86_64", "x64", "amd64"], 'amd64', 64) final List names final String buildArch final int bits Arch(List names, String buildArch, int bits) { this.names = names this.buildArch = buildArch this.bits = bits } static Arch find(String token) { Arch res = values().find({ v -> v.names.contains(token) }) return res } static Arch current() { return find(System.getProperty("os.arch")) } } enum Os { MAC('bsd', 'lib', 'lib'), WINDOWS('windows', 'bin', 'bin'), UNIX('linux', 'lib/i386', 'lib/amd64') final String buildPath; final String installPath32; final String installPath64; Os(String buildPath, String installPath32, String installPath64) { this.buildPath = buildPath this.installPath32 = installPath32 this.installPath64 = installPath64 } static Os current() { return values().find { os -> org.apache.tools.ant.taskdefs.condition.Os.isFamily(os.name().toLowerCase()) } } } // Helper task to run make targets against hotspot class InvokeMake extends org.gradle.api.tasks.Exec { InvokeMake() { def root = project.rootProject logging.captureStandardOutput LogLevel.INFO if (root.os != Os.WINDOWS) { commandLine 'make', '-C', 'make' } else { // Using launcher script commandLine 'cmd', '/c', '..\\build.cmd' environment ARCH: root.arch == Arch.X86 ? 'x86' : 'x64' } args 'OPENJDK=true' args "HOTSPOT_BUILD_VERSION=dcevm${root.flavor}-${root.buildNumber}" args "ARCH_DATA_MODEL=${root.arch.bits}" args "ALT_BOOTDIR=${root.jre.replace('\\', '/')}/.." // Replacing backslashes is essential for Windows! args 'COMPILER_WARNINGS_FATAL=false' // Clang is very serious about warnings args 'HOTSPOT_BUILD_JOBS=4' } }