diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/README.md b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/README.md index 2862c17572..61d489188c 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/README.md +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/README.md @@ -32,6 +32,8 @@ change with future releases. ## Change History __4.0.1:__ * New Ghidra module projects now contain a default `README.md` file. +* Fixed a bug that prevented an imported module source project from being discovered by Ghidra when + launched with the project's run/debug configuration. __4.0.0:__ * GhidraDev has been upgraded to be compatible with Ghidra 11.2 and later. It is not backwards diff --git a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraModuleUtils.java b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraModuleUtils.java index fbf377ff1c..97993967d8 100644 --- a/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraModuleUtils.java +++ b/GhidraBuild/EclipsePlugins/GhidraDev/GhidraDevPlugin/src/main/java/ghidradev/ghidraprojectcreator/utils/GhidraModuleUtils.java @@ -62,13 +62,14 @@ public class GhidraModuleUtils { } } - /** - * Stores a source folder and its corresponding output folder - * - * @param sourceFolder The source folder - * @param outputFolder The output folder - */ - private record SourceFolderInfo(IFolder sourceFolder, IFolder outputFolder) {} + private static String defaultOutputPath = "bin/main"; + + private static Map sourceToOutputMap = + Map.ofEntries(Map.entry("src/main/java", defaultOutputPath), + Map.entry("src/main/help", defaultOutputPath), + Map.entry("src/main/resources", defaultOutputPath), + Map.entry("src/test/java", "bin/test"), + Map.entry("ghidra_scripts", "bin/scripts")); /** * Creates a new Ghidra module project with the given name. @@ -97,28 +98,17 @@ public class GhidraModuleUtils { runConfigMemory, ghidraLayout, jythonInterpreterName, monitor); IProject project = javaProject.getProject(); - // Create source directories - List sourceFolderInfos = new ArrayList<>(); - sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/java"), - project.getFolder("bin/main"))); - sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/help"), - project.getFolder("bin/main"))); - sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/main/resources"), - project.getFolder("bin/main"))); - sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("src/test/java"), - project.getFolder("bin/test"))); - sourceFolderInfos.add(new SourceFolderInfo(project.getFolder("ghidra_scripts"), - project.getFolder("bin/scripts"))); - for (SourceFolderInfo sourceFolderInfo : sourceFolderInfos) { - GhidraProjectUtils.createFolder(sourceFolderInfo.sourceFolder(), monitor); - } - - // Put the source directories in the project's classpath + // Set default output location + javaProject.setOutputLocation(project.getFolder(defaultOutputPath).getFullPath(), monitor); + + // Create source directories and add them to the project's classpath List classpathEntries = new LinkedList<>(); - for (SourceFolderInfo sourceFolderInfo : sourceFolderInfos) { - classpathEntries - .add(JavaCore.newSourceEntry(sourceFolderInfo.sourceFolder().getFullPath(), - new IPath[0], sourceFolderInfo.outputFolder().getFullPath())); + for (String sourcePath : sourceToOutputMap.keySet()) { + IFolder sourceFolder = project.getFolder(sourcePath); + IFolder outputFolder = project.getFolder(sourceToOutputMap.get(sourcePath)); + GhidraProjectUtils.createFolder(sourceFolder, monitor); + classpathEntries.add(JavaCore.newSourceEntry(sourceFolder.getFullPath(), new IPath[0], + outputFolder.getFullPath())); } GhidraProjectUtils.addToClasspath(javaProject, classpathEntries, monitor); @@ -256,42 +246,30 @@ public class GhidraModuleUtils { createRunConfig, runConfigMemory, ghidraLayout, jythonInterpreterName, monitor); IProject project = javaProject.getProject(); - // Find source directory paths - List sourcePaths = new ArrayList<>(); - IFolder srcFolder = project.getFolder("src"); - List srcSubFolders = getSubFolders(srcFolder); - if (!srcSubFolders.isEmpty()) { - for (IFolder srcSubFolder : srcSubFolders) { - List subSubFolders = getSubFolders(srcSubFolder); - if (!subSubFolders.isEmpty()) { - sourcePaths.addAll(subSubFolders.stream().map(e -> e.getFullPath()).toList()); - } - else { - sourcePaths.add(srcSubFolder.getFullPath()); - } - } - } - else { - sourcePaths.add(srcFolder.getFullPath()); - } + // Set default output location + IFolder defaultOutputFolder = project.getFolder(defaultOutputPath); + javaProject.setOutputLocation(defaultOutputFolder.getFullPath(), monitor); - // Find jar file paths - List jarPaths = new ArrayList<>(); + // Put the source and jar paths in the project's classpath + List classpathEntries = new LinkedList<>(); + for (String sourcePath : sourceToOutputMap.keySet()) { + IFolder sourceFolder = project.getFolder(sourcePath); + IFolder outputFolder = project.getFolder(sourceToOutputMap.get(sourcePath)); + GhidraProjectUtils.createFolder(sourceFolder, monitor); + classpathEntries.add(JavaCore.newSourceEntry(sourceFolder.getFullPath(), new IPath[0], + outputFolder.getFullPath())); + } IFolder libFolder = project.getFolder("lib"); if (libFolder.exists()) { for (IResource resource : libFolder.members()) { if (resource.getType() == IResource.FILE && resource.getFileExtension().equals("jar")) { - jarPaths.add(resource.getFullPath()); + classpathEntries + .add(JavaCore.newLibraryEntry(resource.getFullPath(), null, null)); } } } - - // Put the source and jar paths in the project's classpath - List cp = new ArrayList<>(); - cp.addAll(sourcePaths.stream().map(e -> JavaCore.newSourceEntry(e)).toList()); - cp.addAll(jarPaths.stream().map(e -> JavaCore.newLibraryEntry(e, null, null)).toList()); - GhidraProjectUtils.addToClasspath(javaProject, cp, monitor); + GhidraProjectUtils.addToClasspath(javaProject, classpathEntries, monitor); // Update language ant properties file GhidraModuleUtils.writeAntProperties(project, ghidraLayout);