Improve build system and create combined artifact packages

- Create a complete package containing both plugin and bridge script
- Update GitHub Actions workflow to use Maven-generated artifacts
- Add Maven profiles to selectively build plugin-only or complete-package
- Improve Maven configuration with UTF-8 encoding and dependency cleanup
- Fix Maven warnings for system paths and unused dependencies
- Upgrade Java version to 21 for compatibility with latest Ghidra
- Update README with enhanced build instructions
This commit is contained in:
Teal Bauer 2025-03-30 00:40:44 +01:00
parent 5b62a9823b
commit a349bdff70
4 changed files with 204 additions and 63 deletions

View File

@ -52,16 +52,6 @@ jobs:
- name: Build with Maven
run: mvn -B package
- name: Create Complete Package
run: |
mkdir -p package
cp target/GhydraMCP-*.zip package/
cp bridge_mcp_hydra.py package/
cd package
zip -r GhydraMCP-Complete-${{ steps.set_version.outputs.BUILD_VERSION }}.zip *
mv GhydraMCP-Complete-${{ steps.set_version.outputs.BUILD_VERSION }}.zip ..
cd ..
- name: Upload nightly artifacts
if: github.ref_type != 'tag'
@ -71,7 +61,7 @@ jobs:
path: |
target/GhydraMCP-*.zip
bridge_mcp_hydra.py
GhydraMCP-Complete-${{ steps.set_version.outputs.BUILD_VERSION }}.zip
target/GhydraMCP-Complete-*.zip
- name: Generate Release Notes
if: github.ref_type == 'tag'
@ -113,6 +103,6 @@ jobs:
files: |
target/GhydraMCP-*.zip
bridge_mcp_hydra.py
GhydraMCP-Complete-${{ steps.set_version.outputs.BUILD_VERSION }}.zip
target/GhydraMCP-Complete-*.zip
draft: false
prerelease: false

View File

@ -149,12 +149,35 @@ client.use_tool("ghydra", "register_instance", {"port": 8193})
3. Command: `python /ABSOLUTE_PATH_TO/bridge_mcp_hydra.py`
# Building from Source
Build with Maven by running:
`mvn clean package assembly:single`
You can build different artifacts with Maven:
The generated zip file includes the built Ghidra plugin and its resources. These files are required for Ghidra to recognize the new extension.
## Build Everything (Default)
Build both the Ghidra plugin and the complete package:
```
mvn clean package
```
This creates:
- `target/GhydraMCP-[version].zip` - The Ghidra plugin only
- `target/GhydraMCP-Complete-[version].zip` - Complete package with plugin and bridge script
## Build Ghidra Plugin Only
If you only need the Ghidra plugin:
```
mvn clean package -P plugin-only
```
## Build Complete Package Only
If you only need the combined package:
```
mvn clean package -P complete-only
```
The Ghidra plugin includes these files required for Ghidra to recognize the extension:
- lib/GhydraMCP.jar
- extensions.properties
- extension.properties
- Module.manifest

173
pom.xml
View File

@ -4,101 +4,108 @@
<modelVersion>4.0.0</modelVersion>
<groupId>eu.starsong.ghidra</groupId>
<artifactId>GhydraMCP</artifactId>
<artifactId>GhydraMCP</artifactId>
<packaging>jar</packaging>
<version>1.1</version>
<name>GhydraMCP</name>
<url>https://github.com/teal-bauer/GhydraMCP</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<ghidra.jar.location>${project.basedir}/lib</ghidra.jar.location>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
</properties>
<dependencies>
<!-- Ghidra JARs as system-scoped dependencies -->
<!-- Ghidra JARs as system-scoped dependencies for runtime -->
<dependency>
<groupId>ghidra</groupId>
<artifactId>Generic</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Generic.jar</systemPath>
<systemPath>${ghidra.jar.location}/Generic.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>SoftwareModeling</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/SoftwareModeling.jar</systemPath>
<systemPath>${ghidra.jar.location}/SoftwareModeling.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>Project</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Project.jar</systemPath>
<systemPath>${ghidra.jar.location}/Project.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>Docking</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Docking.jar</systemPath>
<systemPath>${ghidra.jar.location}/Docking.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>Decompiler</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Decompiler.jar</systemPath>
<systemPath>${ghidra.jar.location}/Decompiler.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>Utility</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Utility.jar</systemPath>
<systemPath>${ghidra.jar.location}/Utility.jar</systemPath>
</dependency>
<dependency>
<groupId>ghidra</groupId>
<artifactId>Base</artifactId>
<version>11.3.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/Base.jar</systemPath>
<systemPath>${ghidra.jar.location}/Base.jar</systemPath>
</dependency>
<!-- JUnit (test only) -->
<!-- Test dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Set Java version -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<!-- Use custom MANIFEST.MF -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<build>
<plugins>
<!-- Set Java version -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>21</source>
<target>21</target>
<!-- Ignore warning about system paths -->
<compilerArgument>-Xlint:-path</compilerArgument>
</configuration>
</plugin>
<!-- Use custom MANIFEST.MF -->
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
</archive>
<!-- Set a fixed name for the JAR without version -->
<finalName>GhydraMCP</finalName>
<!-- Exclude the App class -->
<excludes>
<exclude>**/App.class</exclude>
</excludes>
<!-- Make sure output directory is target for consistency -->
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
@ -108,36 +115,48 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<!-- Using the custom assembly descriptor -->
<descriptors>
<descriptor>src/assembly/ghidra-extension.xml</descriptor>
</descriptors>
<!-- The name of the final zip -->
<finalName>GhydraMCP-${project.version}</finalName>
<!-- Don't append the assembly ID -->
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<!-- Default execution for the plugin only -->
<execution>
<id>make-assembly</id>
<id>plugin-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/ghidra-extension.xml</descriptor>
</descriptors>
<finalName>GhydraMCP-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
<!-- Execution for the complete package -->
<execution>
<id>complete-package</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/complete-package.xml</descriptor>
</descriptors>
<finalName>GhydraMCP-Complete-${project.version}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
</executions>
</plugin>
<!-- Copy dependencies to target/lib for the assembly -->
<!-- Copy dependencies and validate system paths -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<version>3.6.1</version>
<executions>
<!-- Copy dependencies to target/lib for the assembly -->
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
@ -149,8 +168,68 @@
<includeScope>runtime</includeScope>
</configuration>
</execution>
<!-- Validate system dependency paths -->
<execution>
<id>validate-system-dependencies</id>
<phase>validate</phase>
<goals>
<goal>analyze-only</goal>
</goals>
<configuration>
<failOnWarning>false</failOnWarning>
<ignoredUnusedDeclaredDependencies>
<ignoredUnusedDeclaredDependency>ghidra:Docking</ignoredUnusedDeclaredDependency>
</ignoredUnusedDeclaredDependencies>
<ignoredSystemDependencies>
<ignoredSystemDependency>ghidra:*</ignoredSystemDependency>
</ignoredSystemDependencies>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<!-- Profile for building just the Ghidra plugin -->
<profile>
<id>plugin-only</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>complete-package</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- Profile for building just the complete package -->
<profile>
<id>complete-only</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>plugin-assembly</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,49 @@
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3
http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<!-- Complete package with Ghidra plugin and bridge Python script -->
<id>complete-package</id>
<!-- We want a .zip file -->
<formats>
<format>zip</format>
</formats>
<!-- Don't put everything in an extra top-level directory named after the assembly ID -->
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<!-- 1) Include the bridge Python script in the root -->
<fileSet>
<directory>${project.basedir}</directory>
<includes>
<include>bridge_mcp_hydra.py</include>
<include>README.md</include>
<include>LICENSE</include>
</includes>
<outputDirectory></outputDirectory>
</fileSet>
<!-- 2) Include the Ghidra plugin files -->
<fileSet>
<directory>${project.build.directory}</directory>
<includes>
<include>GhydraMCP.jar</include>
</includes>
<outputDirectory>GhydraMCP/lib</outputDirectory>
</fileSet>
<!-- 3) Include required Ghidra plugin metadata -->
<fileSet>
<directory>src/main/resources</directory>
<includes>
<include>extension.properties</include>
<include>Module.manifest</include>
</includes>
<outputDirectory>GhydraMCP</outputDirectory>
</fileSet>
</fileSets>
</assembly>