// 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/make').exists() } args 'clean' } task prepareJvm { onlyIf { jreFile.canonicalPath != targetJreFile.canonicalPath } doLast { // FIXME: We probably should check if source path is different and delete old JRE in that case ant.copy(todir: targetJreFile, overwrite: true) { fileset(dir: jreFile) } ant.chmod(file: new File(targetJreFile, 'bin/java'), perm: '0755') } } task checkMercurial(description: 'Verify Mercurial is installed') << { def os = new ByteArrayOutputStream() try { def result = exec { executable 'hg' args 'help', 'qinit' standardOutput = os errorOutput = os ignoreExitValue = true } if (result.getExitValue() != 0) { throw new GradleException("Mercurial does not have mq extension installed! Consult README.md for details.") } } catch (GradleException e) { throw new GradleException("Failed to execute 'hg'. Make sure you have Mercurial installed!") } } task init(description: 'Initialize HotSpot repository', dependsOn: checkMercurial) << { file('hotspot').mkdir() exec { executable 'hg' args 'init' ignoreExitValue = true } } task pull(description: 'Pull OpenJDK HotSpot changes', dependsOn: init) { doLast { def hotspotRepository = hotspotTag.contains('jdk7') ? 'http://hg.openjdk.java.net/jdk7u/jdk7u/hotspot' : 'http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot' exec { executable 'hg' args 'pull', hotspotRepository } } } task patch(description: 'Patch HotSpot sources', dependsOn: pull) { doLast { exec { executable 'hg' args 'qpop', '-a' ignoreExitValue = true } 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])) } } def guards = [flavor, hotspotTag.contains('jdk7') ? 'jdk7' : 'jdk8', hotspotTag, flavor + '-' + hotspotTag] exec { executable 'hg' args 'qselect' args guards } exec { executable 'hg' args 'qpush', '-a' } } } 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') } } } } configure([project(':agent'), project(':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 '-shared' args 'natives.c' if (os == Os.UNIX) { args "-I${jre}/../include/linux" args '-fPIC' args '-o' args 'build/libnatives.so' args(arch == Arch.X86 ? '-m32' : '-m64') } else if (os == Os.MAC) { args "-I${jre}/../include/darwin" args '-o' args 'build/libnatives.dylib' } } 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: 'org.ow2.asm', name: 'asm-all', version: '5.0.2' 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}" jvmArgs "-Djava.library.path=../native/build" ignoreFailures = true outputs.upToDateWhen { false } useJUnit { excludeCategories('com.github.dcevm.test.category.' + (flavor == 'light' ? 'Full' : 'Light')) } } test.dependsOn project(':native').tasks['compile'] 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(java.util.Locale.ENGLISH)) } } } // 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' } }