GP-3140: Ghidra can now run from development/repository mode using Gradle's compiled classes/jars, instead of just relying on Eclipse's compilation output

This commit is contained in:
Ryan Kurtz 2023-03-03 16:02:58 -05:00
parent 59371bfb36
commit 0069538469
7 changed files with 61 additions and 22 deletions

View File

@ -150,6 +150,7 @@ task generateDevGhidraServerClasspath {
int idx = 0
configurations.runGhidraServer.each { jarFile ->
def JAR_PATH = jarFile.absolutePath
def JAR_PATH_ECLIPSE = null
// There might be dependencies in the gradle cache, which could be anywhere
// (including a different drive). We can only use relative paths if the jar is in
@ -160,10 +161,16 @@ task generateDevGhidraServerClasspath {
JAR_PATH = JAR_PATH.replace('\\','/') // necessary for windows
def index = JAR_PATH.indexOf("/build/")
if (index != -1) {
// Use Module's bin/ class directory (produced by Eclipse) instead of jar
JAR_PATH = JAR_PATH.substring(0, index) + "/bin/main"
// Also use Module's bin/ class directory (produced by Eclipse) in addition to
// jar (even if Eclipse will not be used)
JAR_PATH_ECLIPSE = JAR_PATH.substring(0, index) + "/bin/main"
}
if (!jarFile.path.contains("/libsForBuild/")) {
// Ensure Eclipse's compiled classes have precedence over the jars built by
// Gradle by putting them first
if (JAR_PATH_ECLIPSE) {
out.println("wrapper.java.classpath.${++idx}=${JAR_PATH_ECLIPSE}")
}
out.println("wrapper.java.classpath.${++idx}=${JAR_PATH}")
}
}

View File

@ -140,7 +140,14 @@ public class GhidraLauncher {
Map<String, GModule> modules = getOrderedModules(layout);
if (SystemUtilities.isInDevelopmentMode()) {
// First add Eclipse's module "bin" paths. If we didn't find any, assume Ghidra was
// compiled with Gradle, and add the module jars Gradle built.
addModuleBinPaths(classpathList, modules);
if (classpathList.isEmpty()) {
addModuleJarPaths(classpathList, modules);
}
addExternalJarPaths(classpathList, layout.getApplicationRootDirs());
}
else {

View File

@ -208,23 +208,27 @@ public class ModuleUtilities {
}
/**
* Gets the "lib" directories from the given modules.
* Gets the library directories from the given modules.
* <p>
* In {@link SystemUtilities#isInReleaseMode() release mode}, we expect these directories to
* be in each module's <code>lib</code> subdirectory.
* <p>
* If not in release mode (i.e., {@link SystemUtilities#isInDevelopmentMode() development mode},
* {@link SystemUtilities#isInTestingMode() testing mode}, etc), we expect these directories to
* be in each module's <code>build/libs</code> subdirectory.
* <p>
* NOTE: If Eclipse is being used this method may still return jars built by Gradle. It is up
* to the caller of this method to determine if they should be used instead of the classes
* compiled by Eclipse.
*
* @param modules The modules to get the lib directories of.
* @return A collection of lib directories from the given modules.
* @param modules The modules to get the library directories of.
* @return A collection of library directories from the given modules.
*/
public static Collection<ResourceFile> getModuleLibDirectories(Map<String, GModule> modules) {
List<ResourceFile> libraryDirectories = new ArrayList<>();
for (GModule module : modules.values()) {
module.collectExistingModuleDirs(libraryDirectories, "lib");
// In testing mode, we run out of an intermediate build state...the module jars
// live in a build/libs directory. We only want to look in here when testing because
// other run modes (such as a Ghidra release launched from a user's Eclipse) may contain
// build remnants that could cause problems if discovered.
if (SystemUtilities.isInTestingMode()) {
module.collectExistingModuleDirs(libraryDirectories, "libs");
}
module.collectExistingModuleDirs(libraryDirectories, "libs");
}
return libraryDirectories;
}

View File

@ -93,13 +93,19 @@ if [ -d "${SCRIPT_DIR}/../Ghidra" ]; then
LS_CPATH="${GHIDRA_HOME}/support/LaunchSupport.jar"
else
# Development Environment
# Development Environment (Eclipse classes or "gradle jar")
GHIDRA_HOME="${SCRIPT_DIR}/../../../.."
WRAPPER_CONF="${SCRIPT_DIR}/../../Common/server/server.conf"
DATA_DIR="${GHIDRA_HOME}/${MODULE_DIR}/build/data"
OS_DIR="${GHIDRA_HOME}/${MODULE_DIR}/os/${OS_DIRNAME}"
CLASSPATH_FRAG="${GHIDRA_HOME}/${MODULE_DIR}/build/dev-meta/classpath.frag"
LS_CPATH="${GHIDRA_HOME}/GhidraBuild/LaunchSupport/bin/main"
if ! [ -d "${LS_CPATH}" ]; then
LS_CPATH="${GHIDRA_HOME}/GhidraBuild/LaunchSupport/build/libs/LaunchSupport.jar"
if ! [ -f "${LS_CPATH}" ]; then
reportError "Cannot launch from repo because Ghidra has not been compiled with Eclipse or Gradle."
fi
fi
fi
WRAPPER_HOME=$(find "${DATA_DIR}" -maxdepth 1 -name "${WRAPPER_NAME_PREFIX}*" -type d | head -n 1)

View File

@ -111,15 +111,19 @@ if [ -f "${SUPPORT_DIR}/launch.properties" ]; then
DEBUG_LOG4J="${SUPPORT_DIR}/debug.log4j.xml"
else
# Development Environment
# Development Environment (Eclipse classes or "gradle jar")
INSTALL_DIR="${SUPPORT_DIR}/../../../.."
CPATH="${INSTALL_DIR}/Ghidra/Framework/Utility/bin/main"
LS_CPATH="${INSTALL_DIR}/GhidraBuild/LaunchSupport/bin/main"
DEBUG_LOG4J="${INSTALL_DIR}/Ghidra/RuntimeScripts/Common/support/debug.log4j.xml"
if ! [ -d "${LS_CPATH}" ]; then
echo "Ghidra cannot launch in development mode because Eclipse has not compiled its class files."
exit 1
CPATH="${INSTALL_DIR}/Ghidra/Framework/Utility/build/libs/Utility.jar"
LS_CPATH="${INSTALL_DIR}/GhidraBuild/LaunchSupport/build/libs/LaunchSupport.jar"
if ! [ -f "${LS_CPATH}" ]; then
echo "Cannot launch from repo because Ghidra has not been compiled with Eclipse or Gradle."
exit 1
fi
fi
DEBUG_LOG4J="${INSTALL_DIR}/Ghidra/RuntimeScripts/Common/support/debug.log4j.xml"
fi
# Make sure some kind of java is on the path. It's required to run the LaunchSupport program.

View File

@ -76,12 +76,19 @@ rem NOTE: If adjusting JAVA command assignment - do not attempt to add parameter
rem NOTE: Variables that get accessed in server.conf must be lowercase
rem Development Environment
rem Development Environment (Eclipse classes or "gradle jar")
set "ghidra_home=%SERVER_DIR%\..\..\..\.."
set "WRAPPER_CONF=%SERVER_DIR%\..\..\Common\server\server.conf"
set "DATA_DIR=%ghidra_home%\%MODULE_DIR%\build\data"
set "classpath_frag=%ghidra_home%\%MODULE_DIR%\build\dev-meta\classpath.frag"
set "LS_CPATH=%ghidra_home%\GhidraBuild\LaunchSupport\bin\main"
if not exist "%LS_CPATH%" (
set "LS_CPATH=%ghidra_home%\GhidraBuild\LaunchSupport\build\libs\LaunchSupport.jar"
)
if not exist "%LS_CPATH%" (
set ERROR=ERROR: Cannot launch from repo because Ghidra has not been compiled with Eclipse or Gradle.
goto reportError
)
goto lab1

View File

@ -84,17 +84,21 @@ set "DEBUG_LOG4J=%SUPPORT_DIR%\debug.log4j.xml"
if exist "%INSTALL_DIR%\Ghidra" goto continue2
::
:: Development Environment
:: Development Environment (Eclipse classes or "gradle jar")
::
set "INSTALL_DIR=%INSTALL_DIR%\..\..\.."
set "CPATH=%INSTALL_DIR%\Ghidra\Framework\Utility\bin\main"
set "LS_CPATH=%INSTALL_DIR%\GhidraBuild\LaunchSupport\bin\main"
set "DEBUG_LOG4J=%INSTALL_DIR%\Ghidra\RuntimeScripts\Common\support\debug.log4j.xml"
if not exist "%LS_CPATH%" (
echo Ghidra cannot launch in development mode because Eclipse has not compiled its class files.
set "CPATH=%INSTALL_DIR%\Ghidra\Framework\Utility\build\libs\Utility.jar"
set "LS_CPATH=%INSTALL_DIR%\GhidraBuild\LaunchSupport\build\libs\LaunchSupport.jar"
)
if not exist "%LS_CPATH%" (
echo Cannot launch from repo because Ghidra has not been compiled with Eclipse or Gradle.
set ERRORLEVEL=1
goto exit1
)
set "DEBUG_LOG4J=%INSTALL_DIR%\Ghidra\RuntimeScripts\Common\support\debug.log4j.xml"
:continue2