Python3 support

This commit is contained in:
DC3-TSD
2024-09-09 09:56:46 -04:00
parent d7c1f65f43
commit 92d0f1dacf
101 changed files with 11413 additions and 13 deletions
+1
View File
@@ -183,6 +183,7 @@ plugins.withType(JavaPlugin) {
}
from (p.projectDir.toString() + "/ghidra_scripts") {
exclude 'bin/'
exclude '**/__pycache__/**'
into { zipPath + "/ghidra_scripts" }
}
+3 -1
View File
@@ -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" }
}
}
+4
View File
@@ -28,3 +28,7 @@ rootProject.createJavadocs {
rootProject.createJsondocs {
source sourceSets.main.allJava
}
rootProject.createPythonTypeStubs {
source sourceSets.main.allJava
}
+95
View File
@@ -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
+17
View File
@@ -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
+94 -8
View File
@@ -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)
}