287 lines
9.0 KiB
Groovy
287 lines
9.0 KiB
Groovy
import org.apache.tools.ant.filters.ReplaceTokens
|
|
|
|
defaultTasks 'buildExtension'
|
|
|
|
apply plugin: 'java'
|
|
|
|
/*****************************************************************************************
|
|
*
|
|
* Reads the application.properties file and sets properties for the version,
|
|
* release name, and distro prefix (ghidira_<version>)
|
|
*
|
|
*****************************************************************************************/
|
|
def ghidraDir = buildscript.sourceFile.getAbsolutePath() + "/../../Ghidra"
|
|
def ghidraProps = new Properties()
|
|
file(ghidraDir + "/application.properties").withReader { reader ->
|
|
ghidraProps.load(reader)
|
|
project.ext.ghidra_version = ghidraProps.getProperty('application.version')
|
|
project.ext.RELEASE_NAME = ghidraProps.getProperty('application.release.name')
|
|
project.ext.DISTRO_PREFIX = "ghidra_${ghidra_version}"
|
|
}
|
|
|
|
configurations {
|
|
helpPath
|
|
}
|
|
|
|
artifacts {
|
|
helpPath jar
|
|
}
|
|
|
|
compileJava {
|
|
sourceCompatibility = ghidraProps.getProperty('application.java.compiler')
|
|
targetCompatibility = ghidraProps.getProperty('application.java.compiler')
|
|
}
|
|
|
|
dependencies {
|
|
compile fileTree(dir: 'lib', include: "*.jar")
|
|
compile fileTree(dir: ghidraDir + '/Framework', include: "**/*.jar")
|
|
compile fileTree(dir: ghidraDir + '/Features', include: "**/*.jar")
|
|
helpPath fileTree(dir: ghidraDir + '/Features/Base', include: "**/Base.jar")
|
|
}
|
|
|
|
def ZIP_NAME_PREFIX = "${DISTRO_PREFIX}_${RELEASE_NAME}_${getCurrentDate()}"
|
|
def DISTRIBUTION_DIR = file("dist")
|
|
|
|
def pathInZip = "${project.name}"
|
|
|
|
task zipSource (type: Zip) {
|
|
|
|
// Define some metadata about the zip (name, location, version, etc....)
|
|
it.baseName project.name + "-src"
|
|
it.extension 'zip'
|
|
it.destinationDir file(project.projectDir.path + "/build/tmp/src")
|
|
|
|
// We MUST copy from a directory, and not just grab a list of source files.
|
|
// This is the only way to preserve the directory structure.
|
|
it.from project.projectDir
|
|
it.include 'src/**/*'
|
|
}
|
|
|
|
|
|
task buildExtension (type: Zip) {
|
|
|
|
baseName "${ZIP_NAME_PREFIX}_${project.name}"
|
|
extension 'zip'
|
|
destinationDir DISTRIBUTION_DIR
|
|
version ''
|
|
|
|
// Make sure that we don't try to copy the same file with the same path into the
|
|
// zip (this can happen!)
|
|
duplicatesStrategy 'exclude'
|
|
|
|
// This filtered property file copy must appear before the general
|
|
// copy to ensure that it is prefered over the unmodified file
|
|
File propFile = new File(project.projectDir, "extension.properties")
|
|
from (propFile) {
|
|
String version = "${ghidra_version}"
|
|
String name = "${project.name}"
|
|
filter (ReplaceTokens, tokens: [extversion: version])
|
|
filter (ReplaceTokens, tokens: [extname: name])
|
|
into pathInZip
|
|
}
|
|
|
|
from (project.jar) {
|
|
into pathInZip + "/lib"
|
|
}
|
|
|
|
from (project.projectDir) {
|
|
exclude 'build/**'
|
|
exclude '*.gradle'
|
|
exclude 'certification.manifest'
|
|
exclude 'dist/**'
|
|
exclude 'bin/**'
|
|
exclude 'src/**'
|
|
exclude '.gradle/**'
|
|
exclude '.classpath'
|
|
exclude '.project'
|
|
exclude '.settings/**'
|
|
exclude 'developer_scripts'
|
|
exclude '.antProperties.xml'
|
|
exclude 'gradlew'
|
|
exclude 'gradlew.bat'
|
|
exclude 'gradle/wrapper/gradle-wrapper.jar'
|
|
exclude 'gradle/wrapper/gradle-wrapper.properties'
|
|
|
|
into pathInZip
|
|
}
|
|
|
|
/////////////////
|
|
// SOURCE
|
|
/////////////////
|
|
from (tasks["zipSource"]) {
|
|
into pathInZip + "/lib"
|
|
}.dependsOn(zipSource)
|
|
|
|
|
|
/////////////////
|
|
// GLOBALS
|
|
/////////////////
|
|
|
|
// First get a list of all files that are under 'src/global'.
|
|
FileTree fileTree = project.fileTree('src/global') {
|
|
include '**/*'
|
|
}
|
|
|
|
|
|
// Now loop over each one, copying it into the zip we're creating. Each will be placed
|
|
// at the root level, starting with the first folder AFTER 'src/global/'.
|
|
//
|
|
// eg: If the file is '/Ghidra/Extensions/Sample/src/global/docs/hello.html', then
|
|
// the file in the zip will be at /docs/hello.html
|
|
//
|
|
fileTree.each { File file ->
|
|
String filePath = stripGlobalFilePath(file)
|
|
from (file) {
|
|
into filePath
|
|
}
|
|
}
|
|
|
|
doLast {
|
|
println "\nCreated " + baseName + "." + extension + " in " + destinationDir
|
|
}
|
|
}
|
|
|
|
// task for calling the java help indexer
|
|
task indexHelp(type: JavaExec) {
|
|
File helpRootDir = file('src/main/help') // this the root dir for the help source
|
|
File outputFile = file("build/help/main/help/${project.name}_JavaHelpSearch")
|
|
onlyIf {helpRootDir.exists()}
|
|
|
|
dependsOn configurations.helpPath
|
|
|
|
inputs.dir helpRootDir
|
|
outputs.dir outputFile
|
|
|
|
classpath = sourceSets.main.runtimeClasspath // this modules runtime classpath (contains jhall.jar)
|
|
|
|
main = 'com.sun.java.help.search.Indexer' // main class to call
|
|
|
|
// tell the indexer where send its output
|
|
|
|
args '-db', outputFile.absolutePath
|
|
|
|
|
|
// The index has a config file parameter. The only thing we use in the config file
|
|
// is a root directory path that should be stripped off all the help references to
|
|
// make them relative instead of absolute
|
|
|
|
File configFile = file('build/helpconfig') // this is the config file that we will create
|
|
|
|
// create the config file when the task runs and not during configuration.
|
|
doFirst {
|
|
configFile.parentFile.mkdirs();
|
|
configFile.write "IndexRemove ${helpRootDir.absolutePath}" + File.separator + "\n"
|
|
}
|
|
|
|
// pass the config file we created as an argument to the indexer
|
|
args '-c',"$configFile"
|
|
|
|
// gather up all the help files into a file collection
|
|
FileTree helpFiles = fileTree('src/main/help') {
|
|
include '**/*.htm'
|
|
include '**/*.html'
|
|
}
|
|
|
|
doFirst {
|
|
// for each help file that was found, add it as an argument to the indexer
|
|
helpFiles.each { File file ->
|
|
args "${file.absolutePath}"
|
|
}
|
|
}
|
|
|
|
group "private"
|
|
description "indexes the helps files for this module. [gradle/helpProject.gradle]"
|
|
}
|
|
|
|
// task for building Ghidra help files - depends on the output from the help indexer
|
|
task buildHelp(type: JavaExec, dependsOn: indexHelp) {
|
|
|
|
File helpRootDir = file('src/main/help/help') // help root where topics dir lives
|
|
File outputDir = file('build/help/main/help') // dir where we want the help files to be generated
|
|
onlyIf {helpRootDir.exists()}
|
|
|
|
inputs.dir helpRootDir
|
|
outputs.dir outputDir
|
|
|
|
classpath = sourceSets.main.runtimeClasspath // this modules runtime classpath (contains jhall.jar)
|
|
|
|
main = 'help.GHelpBuilder' // program to run to build help files.
|
|
|
|
args '-n', "${project.name}" // use the modules name as the base for the help file name
|
|
|
|
args '-o', "${outputDir.absolutePath}" // set the output directory arg
|
|
|
|
doFirst {
|
|
configurations.helpPath.each {
|
|
args "-hp"
|
|
args "${it.absolutePath}"
|
|
}
|
|
args "${helpRootDir.absolutePath}" // tell the help builder what help dir to process
|
|
}
|
|
description " Builds the help for this module. [gradle/helpProject.gradle]\n"
|
|
}
|
|
|
|
// include the help into the module's jar
|
|
jar {
|
|
from "build/help/main" // include the generated help index files
|
|
from "src/main/help" // include the help source files
|
|
version = ""
|
|
}
|
|
|
|
// build the help whenever this module's jar file is built
|
|
jar.dependsOn 'buildHelp'
|
|
|
|
|
|
|
|
/*********************************************************************************
|
|
* Takes the given file and returns a string representing the file path with everything
|
|
* up-to and including 'src/global' removed, as well as the filename.
|
|
*
|
|
* eg: If the file path is '/Ghidra/Configurations/Common/src/global/docs/hello.html',
|
|
* the returned string will be at /docs
|
|
*
|
|
* Note: We have to use 'File.separator' instead of a slash ('/') because of how
|
|
* windows/unix handle slashes ('/' vs. '\'). We only need to do this in cases where we're
|
|
* using java string manipulation libraries (eg String.replace); Gradle already
|
|
* understands how to use the proper slash.
|
|
*********************************************************************************/
|
|
String stripGlobalFilePath(File file) {
|
|
|
|
// First strip off everything before 'src/global/ in the file path.
|
|
def slashIndex = file.path.indexOf('src' + File.separator + 'global')
|
|
String filePath = file.path.substring(slashIndex);
|
|
|
|
// Now remove 'src/global/' from the string.
|
|
filePath = filePath.replace('src' + File.separator + 'global' + File.separator, "");
|
|
|
|
// Now we need to strip off the filename itself, which we do by finding the last
|
|
// instance of a slash ('/') in the string. Unfortunately, groovy doesn't give
|
|
// us a "lastIndexOf('/')" or something nice like that, so we reverse the string
|
|
// and look for the slash that way, remove the filename, then reverse it back.
|
|
//
|
|
// Note that it's possible there is no slash (all we have is a filename), meaning
|
|
// this file will be placed at the root level.
|
|
//
|
|
String reverseFilePath = filePath.reverse()
|
|
slashIndex = reverseFilePath.indexOf(File.separator)
|
|
if (slashIndex != -1) {
|
|
reverseFilePath = reverseFilePath.substring(slashIndex)
|
|
filePath = reverseFilePath.reverse()
|
|
}
|
|
else {
|
|
filePath = ""
|
|
}
|
|
|
|
return filePath
|
|
}
|
|
/*********************************************************************************
|
|
* Returns the current date formatted as yyyyMMdd.
|
|
*********************************************************************************/
|
|
def getCurrentDate() {
|
|
|
|
def date = new Date()
|
|
def formattedDate = date.format('yyyyMMdd')
|
|
return formattedDate
|
|
}
|
|
|