mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 21:51:47 +00:00
229 lines
9.0 KiB
Groovy
229 lines
9.0 KiB
Groovy
/****************************************************************************
|
|
* nativeBuildProperties.gradle
|
|
*
|
|
* This script contains global settings used by all projects that have
|
|
* native build requirements.
|
|
*
|
|
* This is NOT a complete build script for those
|
|
* projects; it is only meant to capture items that are common to all so
|
|
* we don't need to define them over and over again.
|
|
****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Always apply the cpp and c plugin, for obvious reasons
|
|
****************************************************************************/
|
|
apply plugin: 'cpp'
|
|
apply plugin: 'c'
|
|
|
|
// Unclear if we can rely on the VisualCpp plugin to identify the correct Visual Studio paths
|
|
|
|
project.ext.VISUAL_STUDIO_BASE_DIR = "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017"
|
|
project.ext.WINDOWS_KITS_DIR = "C:\\Program Files (x86)\\Windows Kits\\10"
|
|
|
|
project.ext.VISUAL_STUDIO_INSTALL_DIR = "/"
|
|
project.ext.VISUAL_STUDIO_VCVARS_CMD = "UNKNOWN"
|
|
project.ext.MSVC_SDK_VERSION = "UNKNOWN"
|
|
project.ext.MSVC_TOOLS_VERSION = "UNKNOWN"
|
|
|
|
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
|
|
|
|
project.ext.VISUAL_STUDIO_INSTALL_DIR = project.ext.VISUAL_STUDIO_BASE_DIR + "\\Professional"
|
|
if (!file(project.ext.VISUAL_STUDIO_INSTALL_DIR).exists()) {
|
|
project.ext.VISUAL_STUDIO_INSTALL_DIR = project.ext.VISUAL_STUDIO_BASE_DIR + "\\Community"
|
|
}
|
|
if (file(project.ext.VISUAL_STUDIO_INSTALL_DIR).exists()) {
|
|
|
|
println "Visual Studio Path: ${VISUAL_STUDIO_INSTALL_DIR}"
|
|
|
|
project.ext.VISUAL_STUDIO_VCVARS_CMD = "\"${VISUAL_STUDIO_INSTALL_DIR}\\VC\\Auxiliary\\Build\\vcvarsall.bat\" x86_amd64"
|
|
|
|
// NOTE: Windows 7 targeting requires the use of the Windows 8.1 SDK and setting the
|
|
// WINVER property a value of "0x0601" which may be specified to the compiler/linker.
|
|
// If using a VS Solution this must be specified within the project file(s).
|
|
project.ext.WINVER = "0x0601"
|
|
|
|
// Rely on vcvars script to supply SDK versions
|
|
def COMMAND = "cmd /c ${VISUAL_STUDIO_VCVARS_CMD} > nul && cmd /c echo"
|
|
project.ext.MSVC_SDK_VERSION = "${COMMAND} %WINDOWSSDKVERSION%".execute().text.trim().replace('\\', '')
|
|
println "Visual Studio SDK Version: ${MSVC_SDK_VERSION}"
|
|
project.ext.MSVC_TOOLS_VERSION = "${COMMAND} %VCTOOLSVERSION%".execute().text.trim().replace('\\', '')
|
|
println "Visual Studio VCTools Version: ${MSVC_TOOLS_VERSION}"
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Defines the platforms we have to support in Ghidra. This model is used
|
|
* for all native builds and should be extended by each module as-needed.
|
|
****************************************************************************/
|
|
model {
|
|
|
|
// define the platforms that we support in ghidra
|
|
platforms {
|
|
win32 {
|
|
architecture 'x86'
|
|
operatingSystem 'windows'
|
|
}
|
|
win64 {
|
|
architecture 'x86_64'
|
|
operatingSystem 'windows'
|
|
}
|
|
linux64 {
|
|
architecture 'x86_64'
|
|
operatingSystem 'linux'
|
|
}
|
|
osx64 {
|
|
architecture 'x86_64'
|
|
operatingSystem 'osx'
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************************
|
|
* Task: verify presence of correct tool chain version for current platform
|
|
******************************************************************************************/
|
|
task CheckToolChain {
|
|
// Native C/Cpp plugins will trigger failure if no tool chain found
|
|
doFirst {
|
|
if (org.gradle.internal.os.OperatingSystem.current().isWindows()) {
|
|
// ensure that required MS Visual Studio is installed where expected
|
|
String msg = "Microsoft Visual Studio install not found: ${VISUAL_STUDIO_BASE_DIR}\n" +
|
|
"Adjust path in Ghidra/GPL/nativeBuildProperties.gradle if needed."
|
|
if (!file(VISUAL_STUDIO_BASE_DIR).exists() ||
|
|
!file(VISUAL_STUDIO_INSTALL_DIR).exists()) {
|
|
throw new GradleException(msg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************************
|
|
* If task1 contains the given platform name, then it needs to be executed before
|
|
* task2. The task1 must be of type LinkExecutable or LinkSharedLibrary so that the
|
|
* targetPlatform may be inspected.
|
|
*
|
|
******************************************************************************************/
|
|
def addTaskDependencyForMyPlatform(task1, task2, platform) {
|
|
if (platform.equals(task1.targetPlatform.get().name)) {
|
|
task2.dependsOn task1.path
|
|
task1.dependsOn CheckToolChain
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************************
|
|
* Returns true if the given task is a custom Make task (starts with the platform name and
|
|
* ends with "Make").
|
|
*
|
|
* Note that this is a Ghidra-specific task and is not one created dynamically by Gradle.
|
|
*
|
|
******************************************************************************************/
|
|
def isNativeBinaryMakeTask(Task task, String platform) {
|
|
if (task.name.startsWith(platform) && task.name.endsWith("Make")) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
/*******************************************************************************************
|
|
* Task Rule : builds all the natives in this module for a given platform.
|
|
*
|
|
* Example : gradle buildNatives_win64 will build all win64 native executables and shared libraries.
|
|
*
|
|
* NOTE: you must be on the appropriate platform for this to work.
|
|
*
|
|
******************************************************************************************/
|
|
tasks.addRule("Pattern: buildNatives_<platform name>]: build all natives for given platform") { String taskName ->
|
|
|
|
if (taskName.startsWith("buildNatives_")) {
|
|
String platform = taskName - "buildNatives_"
|
|
|
|
task(taskName) { myTask ->
|
|
|
|
project.tasks.withType(LinkExecutable) { t ->
|
|
addTaskDependencyForMyPlatform(t, myTask, platform)
|
|
}
|
|
project.tasks.withType(LinkSharedLibrary) { t ->
|
|
addTaskDependencyForMyPlatform(t, myTask, platform)
|
|
}
|
|
project.tasks.each { t ->
|
|
if (isNativeBinaryMakeTask(t, platform)) {
|
|
myTask.dependsOn t.path
|
|
t.dependsOn CheckToolChain
|
|
}
|
|
}
|
|
|
|
// add callbacks to look for native build tasks when new tasks are added later
|
|
project.tasks.withType(LinkExecutable).whenTaskAdded { t ->
|
|
addTaskDependencyForMyPlatform(t, myTask, platform)
|
|
}
|
|
project.tasks.withType(LinkSharedLibrary).whenTaskAdded { t ->
|
|
addTaskDependencyForMyPlatform(t, myTask, platform)
|
|
}
|
|
project.tasks.whenTaskAdded { t ->
|
|
if (isNativeBinaryMakeTask(t, platform)) {
|
|
myTask.dependsOn t.path
|
|
t.dependsOn CheckToolChain
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************************
|
|
* Task Rule : builds all the natives in this module for a given platform and copies the
|
|
* results to the bin repo.
|
|
*
|
|
* Example : gradle prebuildNatives_win64 will build all win64 native executables and shared
|
|
* libraries and copy the results to the appropriate project/os directory in the bin
|
|
* repo.
|
|
*
|
|
* NOTE: you must be on the appropriate platform for this to work.
|
|
*
|
|
******************************************************************************************/
|
|
tasks.addRule("Pattern: prebuildNatives_<platform name>]: build all natives for given platform") { String taskName ->
|
|
if (taskName.startsWith("prebuildNatives_")) {
|
|
String platform = taskName - "prebuildNatives_"
|
|
|
|
task(taskName) { myTask ->
|
|
dependsOn "buildNatives_$platform"
|
|
|
|
doLast {
|
|
copy {
|
|
from "${projectDir}/build/os/${platform}"
|
|
into "${getProjectLocationInBinRepo(project)}/os/${platform}"
|
|
exclude "*.exp"
|
|
exclude "*.lib"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* The following block of code changes the output directory for native builds
|
|
* to <projectDir>/build/os/<platform>/<executable> ?? is there a better way to do this?
|
|
****************************************************************************************/
|
|
gradle.taskGraph.whenReady {
|
|
def p = this.project
|
|
p.tasks.withType(LinkExecutable).each { t ->
|
|
File f = t.linkedFile.getAsFile().get()
|
|
String filename = f.getName()
|
|
NativePlatform platform = t.targetPlatform.get()
|
|
String osName = platform.getName()
|
|
t.linkedFile = p.file("build/os/${osName}/$filename")
|
|
}
|
|
p.tasks.withType(LinkSharedLibrary).each { t ->
|
|
File f = t.linkedFile.getAsFile().get()
|
|
String filename = f.getName()
|
|
NativePlatform platform = t.targetPlatform.get()
|
|
String osName = platform.getName()
|
|
t.linkedFile = p.file("build/os/${osName}/$filename")
|
|
}
|
|
}
|
|
|
|
/*****************************************************************************************
|
|
* The following block of code ensures that the buildNatives_<platform> task is used
|
|
* during assembly to ensure that missing toolchain generates an appropriate error
|
|
****************************************************************************************/
|
|
def currentPlatform = getCurrentPlatformName()
|
|
assemble.dependsOn "buildNatives_$currentPlatform"
|