mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00

Gradle Wrapper: https://docs.gradle.org/current/userguide/gradle_wrapper.html Is "recommended way to execute any Gradle build" so more and more extensions have the wrapper files in the repository. They serve no purpose once built, so ignore it from the zip.
281 lines
8.8 KiB
Groovy
281 lines
8.8 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
|
|
}
|
|
|
|
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
|
|
}
|
|
|