mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-31 10:11:21 +08:00
Python3 support
This commit is contained in:
@@ -183,6 +183,7 @@ plugins.withType(JavaPlugin) {
|
||||
}
|
||||
from (p.projectDir.toString() + "/ghidra_scripts") {
|
||||
exclude 'bin/'
|
||||
exclude '**/__pycache__/**'
|
||||
into { zipPath + "/ghidra_scripts" }
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,9 @@ rootProject.assembleDistribution {
|
||||
exclude '**/*.pyc'
|
||||
exclude '**/*.pyo'
|
||||
exclude '**/__pycache__/**'
|
||||
exclude 'dist/*.tar.gz'
|
||||
exclude '**/.pytest_cache'
|
||||
exclude '**/*.egg-info'
|
||||
exclude 'build'
|
||||
into { zipPath + "/pypkg" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,3 +28,7 @@ rootProject.createJavadocs {
|
||||
rootProject.createJsondocs {
|
||||
source sourceSets.main.allJava
|
||||
}
|
||||
|
||||
rootProject.createPythonTypeStubs {
|
||||
source sourceSets.main.allJava
|
||||
}
|
||||
|
||||
@@ -194,6 +194,94 @@ task createJsondocs(type: Javadoc, description: 'Generate JSON docs for all proj
|
||||
}
|
||||
}
|
||||
|
||||
task createPythonTypeStubs(type: Javadoc, description: 'Generate pyi stubs for all projects', group: 'Documentation') {
|
||||
|
||||
group 'private'
|
||||
|
||||
String ROOT_PROJECT_DIR = rootProject.projectDir.toString()
|
||||
|
||||
destinationDir file(ROOT_PROJECT_DIR + "/build/typestubs/src")
|
||||
|
||||
failOnError false
|
||||
|
||||
// Must add classpath for main and test source sets. Javadoc will fail if it cannot
|
||||
// find referenced classes.
|
||||
classpath = rootProject.ext.ghidraPath
|
||||
|
||||
|
||||
// Generate at package level because user may try to get help directly on an object they have
|
||||
// rather than its public interface.
|
||||
options.addBooleanOption("package", true)
|
||||
|
||||
// Set the ghidra flag to enable the creation of the ghidra_builtins pseudo package
|
||||
options.addBooleanOption("ghidra", true)
|
||||
|
||||
// Newer versions of gradle set this to true by default.
|
||||
// The JsonDoclet doesn't have the -notimestamp option so ensure it isn't set.
|
||||
options.setNoTimestamp(false)
|
||||
|
||||
// Some internal packages are not public and need to be exported.
|
||||
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt=ALL-UNNAMED"])
|
||||
|
||||
options.doclet = "ghidra.doclets.typestubs.PythonTypeStubDoclet"
|
||||
doFirst {
|
||||
options.docletpath = new ArrayList(configurations.jsondoc.files)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
task createGhidraStubsWheel {
|
||||
group 'private'
|
||||
description "Creates the ghidra-stubs wheel for the Ghidra api. [gradle/root/distribution.gradle]"
|
||||
|
||||
dependsOn("createPythonTypeStubs")
|
||||
|
||||
String ROOT_PROJECT_DIR = rootProject.projectDir.toString()
|
||||
|
||||
def cwd = file(ROOT_PROJECT_DIR + "/build/typestubs")
|
||||
def destinationDir = file(cwd.toString() + "/dist")
|
||||
|
||||
it.outputs.file(destinationDir.toString() + "/ghidra_stubs-${project.version}-py3-none-any.whl")
|
||||
|
||||
doFirst {
|
||||
copy {
|
||||
from(file(ROOT_PROJECT_DIR + "/LICENSE"))
|
||||
into cwd
|
||||
}
|
||||
|
||||
def manifest = file(cwd.toString() + "/MANIFEST.in" )
|
||||
manifest.write("graft src\n")
|
||||
|
||||
def pyproject = file(cwd.toString() + "/pyproject.toml" )
|
||||
pyproject.write("""\
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "ghidra-stubs"
|
||||
version = "${project.version}"
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Typing :: Stubs Only",
|
||||
]
|
||||
""".stripIndent()
|
||||
)
|
||||
}
|
||||
|
||||
doLast {
|
||||
File setuptools = project(":Debugger-rmi-trace").findPyDep(".")
|
||||
exec {
|
||||
workingDir { cwd.toString() }
|
||||
commandLine rootProject.PYTHON3, "-m", "pip"
|
||||
args "wheel", "-w", destinationDir.toString(), "--no-index"
|
||||
args "-f", setuptools
|
||||
args "."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
* JAVADOCS - ZIP
|
||||
*
|
||||
@@ -336,6 +424,13 @@ task assembleDistribution (type: Copy) {
|
||||
from (zipJavadocs) {
|
||||
into 'docs'
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
// Ghidra Python type stubs
|
||||
////////////////////////////
|
||||
from (createGhidraStubsWheel) {
|
||||
into 'docs'
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Patch Readme
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
/******************************************************************************************
|
||||
* TASK createPythonVirtualEnvironment
|
||||
*
|
||||
* Summary: Creates a Python virtual environment directory at "build/venv"
|
||||
******************************************************************************************/
|
||||
task createPythonVirtualEnvironment(type: Exec) {
|
||||
def venvDir = "build/venv"
|
||||
def binDir = isCurrentWindows() ? "Scripts" : "bin"
|
||||
def suffix = isCurrentWindows() ? ".exe" : "3"
|
||||
project.ext.PYTHON3_VENV = "${rootProject.projectDir}/${venvDir}/${binDir}/python${suffix}"
|
||||
project.ext.PIP3_VENV = "${rootProject.projectDir}/${venvDir}/${binDir}/pip${suffix}"
|
||||
|
||||
commandLine rootProject.PYTHON3, "-m", "venv", venvDir, "--copies"
|
||||
}
|
||||
|
||||
rootProject.prepDev.dependsOn createPythonVirtualEnvironment
|
||||
@@ -182,7 +182,7 @@ ext.deps = [
|
||||
name: "setuptools-68.0.0-py3-none-any.whl",
|
||||
url: "https://files.pythonhosted.org/packages/c7/42/be1c7bbdd83e1bfb160c94b9cafd8e25efc7400346cf7ccdbdb452c467fa/setuptools-68.0.0-py3-none-any.whl",
|
||||
sha256: "11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f",
|
||||
destination: file("${DEPS_DIR}/Debugger-rmi-trace/")
|
||||
destination: [file("${DEPS_DIR}/Debugger-rmi-trace/"), file("${DEPS_DIR}/Pyhidra/")]
|
||||
],
|
||||
[
|
||||
name: "wheel-0.37.1-py2.py3-none-any.whl",
|
||||
@@ -213,6 +213,84 @@ ext.deps = [
|
||||
url: "https://files.pythonhosted.org/packages/83/1c/25b79fc3ec99b19b0a0730cc47356f7e2959863bf9f3cd314332bddb4f68/pywin32-306-cp312-cp312-win_amd64.whl",
|
||||
sha256: "37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e",
|
||||
destination: file("${DEPS_DIR}/Debugger-agent-dbgeng/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/5d/cf/7b89469bcede4b2fd69c2db7d1d61e8759393cfeec46f7b0c84f5006a691/JPype1-1.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
sha256: "f7aa1469d75f9b310f709b61bb2faa4cef4cbd4d670531ad1d1bb53e29cfda05",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp39-cp39-win_amd64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/b9/fd/d38a8e401b089adce04c48021ddcb366891d1932db2f7653054feb470ae6/JPype1-1.5.0-cp39-cp39-win_amd64.whl",
|
||||
sha256: "6bfdc101c56cab0b6b16e974fd8cbb0b3f7f14178286b8b55413c5d82d5f2bea",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",
|
||||
url: "https://files.pythonhosted.org/packages/84/9c/80d5edf6d610f82d0658b6402cdf3f8cdd6a7d4f36afb2149da90e0cad47/JPype1-1.5.0-cp310-cp310-macosx_10_9_universal2.whl",
|
||||
sha256: "7b6b1af3f9e0033080e3532c2686a224cd14706f36c14ef36160a2a1db751a17",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/74/98/d6517002355b0585d0e66f7b0283c7f6e2271c898a886e1ebac09836b100/JPype1-1.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
sha256: "a02b2f05621c119d35f4acc501b4261eeb48a4af7cc13d9afc2e9eb316c4bd29",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp310-cp310-win_amd64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/da/5f/253c1c1dba6f7f457b6c3aa2ea9c517287d49764e0ee1042d5818c36e781/JPype1-1.5.0-cp310-cp310-win_amd64.whl",
|
||||
sha256: "0b40c76e075d4fed2c83340bb30b7b95bbc396fd370c564c6b608faab00ea4ef",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",
|
||||
url: "https://files.pythonhosted.org/packages/98/37/0049866cbfecb879b46d8e9f9b70944624ab17152a282ad5cf60909054ec/JPype1-1.5.0-cp311-cp311-macosx_10_9_universal2.whl",
|
||||
sha256: "85a31b30b482eaf788b21af421e0750aa0be7758307314178143a76632b0ad04",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/17/1e/7728ae8fb41e8fbf3a7309f8936d07b0b1622f2860733df0e7ec30b1ce76/JPype1-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
sha256: "5ef976e0f3b2e9604469f449f30bb2031941a159a0637f4c16adb2c5076f3e81",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp311-cp311-win_amd64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/1f/19/144f3a767b563ba5c6d4aa534ea1f3fad9a5067c3917df4458a6e1afe0ef/JPype1-1.5.0-cp311-cp311-win_amd64.whl",
|
||||
sha256: "2bc987205ff8d2d8e36dfbef05430e0638e85d4fee1166ba58ebfa6f7a67cdf8",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp312-cp312-macosx_10_9_universal2.whl",
|
||||
url: "https://files.pythonhosted.org/packages/30/0d/9ac6f0e59427fc5ebf4547c2fdbb38e347b46c2dc20b430490236d037ed8/JPype1-1.5.0-cp312-cp312-macosx_10_9_universal2.whl",
|
||||
sha256: "8714bfaf09d6877160bc7ac97812016ccb09f6d7ba5ea2a9f519178aefcca93f",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/7d/ed/549766039d17550da6e3fa59ed776a021b400324d7766358d3b6e33d8b28/JPype1-1.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
|
||||
sha256: "8649b526eccb4047881ad60bdb1974eb71a09cdb7f8bda17c96fdc0f9a3f2d1e",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0-cp312-cp312-win_amd64.whl",
|
||||
url: "https://files.pythonhosted.org/packages/20/47/9606af72e21703e5fca5e29e5bd5e345506977b6ba492c549648adef47ef/JPype1-1.5.0-cp312-cp312-win_amd64.whl",
|
||||
sha256: "9aafc00b00bf8c1b624081e5d4ab87f7752e6c7ee6a141cfc332250b05c6d42f",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "JPype1-1.5.0.tar.gz",
|
||||
url: "https://files.pythonhosted.org/packages/25/42/8ca50a0e27e3053829545829e7bcba071cbfa4d5d8fd7fc5d1d988f325b1/JPype1-1.5.0.tar.gz",
|
||||
sha256: "425a6e1966afdd5848b60c2688bcaeb7e40ba504a686f1114589668e0631e878",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
],
|
||||
[
|
||||
name: "packaging-23.2-py3-none-any.whl",
|
||||
url: "https://files.pythonhosted.org/packages/ec/1a/610693ac4ee14fcdf2d9bf3c493370e4f2ef7ae2e19217d7a237ff42367d/packaging-23.2-py3-none-any.whl",
|
||||
sha256: "8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7",
|
||||
destination: file("${DEPS_DIR}/Pyhidra/")
|
||||
]
|
||||
]
|
||||
|
||||
@@ -231,12 +309,20 @@ deps.each {
|
||||
// Copies the downloaded dependencies to their required destination.
|
||||
// Some downloads require pre-processing before their relevant pieces can be copied.
|
||||
deps.each {
|
||||
if (it.destination instanceof File) {
|
||||
def copier = { File fp ->
|
||||
if (!OFFLINE) {
|
||||
println "Copying " + it.name + " to " + it.destination
|
||||
println "Copying " + it.name + " to " + fp
|
||||
}
|
||||
mkdirs(fp)
|
||||
copyFile(new File(DOWNLOADS_DIR, it.name), new File(fp, it.name));
|
||||
}
|
||||
if (it.destination instanceof File) {
|
||||
copier(it.destination)
|
||||
}
|
||||
else if (it.destination instanceof List<File>) {
|
||||
it.destination.each { fp ->
|
||||
copier(fp)
|
||||
}
|
||||
mkdirs(it.destination)
|
||||
copyFile(new File(DOWNLOADS_DIR, it.name), new File(it.destination, it.name));
|
||||
}
|
||||
else if (it.destination instanceof Closure) {
|
||||
if (!OFFLINE) {
|
||||
@@ -267,7 +353,7 @@ def download(url, file) {
|
||||
println "curl -L -o " + relative(file) + " '" + url + "'"
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
println "URL: " + url
|
||||
def(InputStream istream, size) = establishConnection(url, NUM_RETRIES);
|
||||
assert istream != null : " ***CONNECTION FAILURE***\n max attempts exceeded; exiting\n"
|
||||
@@ -341,7 +427,7 @@ def unzip(sourceDir, targetDir, zipFileName) {
|
||||
println "unzip " + relative(zipFile) + " -d " + relative(targetDir)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
def zip = new ZipFile(zipFile)
|
||||
zip.entries().findAll { !it.directory }.each { e ->
|
||||
(e.name as File).with { f ->
|
||||
@@ -386,7 +472,7 @@ def copyFile(sourceFile, targetFile) {
|
||||
println "cp " + relative(sourceFile) + " " + relative(targetFile)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
FileUtils.copyFile(sourceFile, targetFile)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user