/* ### * IP: GHIDRA * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ def checkPythonVersion(String pyCmd) { try { def stdout = new ByteArrayOutputStream() exec { commandLine pyCmd, "-c", "import sys; print('{0}.{1}'.format(*sys.version_info))" standardOutput = stdout errorOutput = OutputStream.nullOutputStream() } def version = "$stdout".strip() return version } catch (Exception e) { return "ABSENT" } } ext.MIN_PIP_VERSION = [20, 2] // 20.2+ def checkPipVersion(String pyCmd) { try { def stdout = new ByteArrayOutputStream() exec { commandLine pyCmd, "-c", "import pip; print(pip.__version__)" standardOutput = stdout errorOutput = OutputStream.nullOutputStream() } def version = "$stdout".strip(); if (version.length() == 0) { println("Warning: python pip not installed (required for build)") } else { println("Found python pip version ${version}") def (majorVer, minorVer) = version.tokenize('.') def major = majorVer.toInteger() def minor = minorVer.toInteger() if (major < MIN_PIP_VERSION[0] || (major == MIN_PIP_VERSION[0] && minor < MIN_PIP_VERSION[1])) { println("Warning: python pip may require upgrade") } } return version } catch (Exception e) { println("Warning: python pip not installed") } } ext.SUPPORTED_PY_VERSIONS = ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] def findPython3() { for (pyCmd in ['py', 'python3', 'python']) { def pyVer = checkPythonVersion(pyCmd) if (pyVer in SUPPORTED_PY_VERSIONS) { println("Using python command: ${pyCmd} (version ${pyVer})") checkPipVersion(pyCmd) return pyCmd } } for (pyVer in SUPPORTED_PY_VERSIONS) { def pyCmd = "python${pyVer}" if (checkPythonVersion(pyCmd) in SUPPORTED_PY_VERSIONS) { println("Using python command: ${pyCmd}") checkPipVersion(pyCmd) return pyCmd } } // Don't fail until task execution. Just let "python3" fail. // Force use of non-existent python3.7 instead of unsupported python version // which should fail if a python build is performed. return 'python3.7' } ext.PYTHON3 = findPython3() ext.findPyDep = { name -> File inDeps = file("${DEPS_DIR}/${project.name}/${name}") File inRepo = file("${BIN_REPO}/${getGhidraRelativePath(project)}/${name}") if (inDeps.exists()) { return inDeps } if (inRepo.exists()) { return inRepo } println("Warning: Could not find '${name}' for ${project.name}") return inDeps } task assemblePyPackage(type: Copy) { from "src/main/py" into "build/pypkg/" } task buildPyPackage { ext.dist = { file("build/pypkg/dist") } inputs.files(assemblePyPackage) outputs.dir(dist) doLast { File setuptools = project(":Debugger-rmi-trace").findPyDep(".") exec { workingDir { "build/pypkg" } commandLine PYTHON3, "-m", "pip" args "wheel", "-w", "dist/", "--no-index", "--no-deps" args "-f", setuptools args "." } } } // At the moment, any module with a python package also distributes it. // We can separate this into `distributePythonPackage` later, if necessary. rootProject.assembleDistribution { dependsOn(buildPyPackage) def p = this.project def zipPath = getZipPath(p) from (p.assemblePyPackage) { exclude '**/*.pyc' exclude '**/*.pyo' exclude '**/__pycache__/**' exclude 'dist/*.tar.gz' into { zipPath + "/pypkg" } } } ext.distributePyDep = { name -> File dep = findPyDep(name) def zipPath = getZipPath(project) rootProject.assembleDistribution { into ("${zipPath}/pypkg/dist") { from dep } } }