nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 stdenv,
3 fetchFromGitHub,
4 lib,
5 callPackage,
6 gradle_8,
7 makeBinaryWrapper,
8 openjdk21,
9 unzip,
10 makeDesktopItem,
11 copyDesktopItems,
12 desktopToDarwinBundle,
13 xcbuild,
14 protobuf,
15 ghidra-extensions,
16 python3,
17 python3Packages,
18}:
19
20let
21 pkg_path = "$out/lib/ghidra";
22 pname = "ghidra";
23 version = "11.3.2";
24
25 isMacArm64 = stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isAarch64;
26
27 releaseName = "NIX";
28 distroPrefix = "ghidra_${version}_${releaseName}";
29 src = fetchFromGitHub {
30 owner = "NationalSecurityAgency";
31 repo = "Ghidra";
32 rev = "Ghidra_${version}_build";
33 hash = "sha256-EvIOC/VIUaEl7eneVzgEt2fhLSP9DaawMAutk4ouFp8=";
34 # populate values that require us to use git. By doing this in postFetch we
35 # can delete .git afterwards and maintain better reproducibility of the src.
36 leaveDotGit = true;
37 postFetch = ''
38 cd "$out"
39 git rev-parse HEAD > $out/COMMIT
40 # 1970-Jan-01
41 date -u -d "@$(git log -1 --pretty=%ct)" "+%Y-%b-%d" > $out/SOURCE_DATE_EPOCH
42 # 19700101
43 date -u -d "@$(git log -1 --pretty=%ct)" "+%Y%m%d" > $out/SOURCE_DATE_EPOCH_SHORT
44 find "$out" -name .git -print0 | xargs -0 rm -rf
45 '';
46 };
47
48 patches = [
49 # Use our own protoc binary instead of the prebuilt one
50 ./0001-Use-protobuf-gradle-plugin.patch
51
52 # Override installation directory to allow loading extensions
53 ./0002-Load-nix-extensions.patch
54
55 # Remove build dates from output filenames for easier reference
56 ./0003-Remove-build-datestamp.patch
57 ];
58
59 postPatch = ''
60 # Set name of release (eg. PUBLIC, DEV, etc.)
61 sed -i -e 's/application\.release\.name=.*/application.release.name=${releaseName}/' Ghidra/application.properties
62
63 # Set build date and git revision
64 echo "application.build.date=$(cat SOURCE_DATE_EPOCH)" >> Ghidra/application.properties
65 echo "application.build.date.short=$(cat SOURCE_DATE_EPOCH_SHORT)" >> Ghidra/application.properties
66 echo "application.revision.ghidra=$(cat COMMIT)" >> Ghidra/application.properties
67
68 # Tells ghidra to use our own protoc binary instead of the prebuilt one.
69 tee -a Ghidra/Debug/Debugger-{isf,rmi-trace}/build.gradle <<HERE
70 protobuf {
71 protoc {
72 path = '${protobuf}/bin/protoc'
73 }
74 }
75 HERE
76 '';
77
78 # "Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0."
79 gradle = gradle_8;
80
81in
82stdenv.mkDerivation (finalAttrs: {
83 inherit
84 pname
85 version
86 src
87 patches
88 postPatch
89 ;
90
91 # Don't create .orig files if the patch isn't an exact match.
92 patchFlags = [
93 "--no-backup-if-mismatch"
94 "-p1"
95 ];
96
97 desktopItems = [
98 (makeDesktopItem {
99 name = "ghidra";
100 exec = "ghidra";
101 icon = "ghidra";
102 desktopName = "Ghidra";
103 genericName = "Ghidra Software Reverse Engineering Suite";
104 categories = [ "Development" ];
105 terminal = false;
106 startupWMClass = "ghidra-Ghidra";
107 })
108 ];
109
110 nativeBuildInputs = [
111 gradle
112 unzip
113 makeBinaryWrapper
114 copyDesktopItems
115 protobuf
116 python3
117 python3Packages.pip
118 ]
119 ++ lib.optionals stdenv.hostPlatform.isDarwin [
120 xcbuild
121 desktopToDarwinBundle
122 ];
123
124 dontStrip = true;
125
126 __darwinAllowLocalNetworking = true;
127
128 mitmCache = gradle.fetchDeps {
129 inherit pname;
130 data = ./deps.json;
131 };
132
133 gradleFlags = [
134 "-Dorg.gradle.java.home=${openjdk21}"
135 ]
136 ++ lib.optionals isMacArm64 [
137 # For some reason I haven't been able to figure out yet, ghidra builds for
138 # arm64 seems to build the x64 binaries of the decompiler. These fail to
139 # build due to trying to link the x64 object files with arm64 stdc++
140 # library, which obviously fails.
141 #
142 # Those binaries are entirely unnecessary anyways, since we're targeting
143 # arm64 build here, so let's exclude them from the build.
144 "-x"
145 "Decompiler:linkSleighMac_x86_64Executable"
146 "-x"
147 "Decompiler:linkDecompileMac_x86_64Executable"
148 ];
149
150 preBuild = ''
151 export JAVA_TOOL_OPTIONS="-Duser.home=$NIX_BUILD_TOP/home"
152 gradle -I gradle/support/fetchDependencies.gradle
153 '';
154
155 gradleBuildTask = "buildGhidra";
156
157 installPhase = ''
158 runHook preInstall
159
160 mkdir -p "${pkg_path}" "$out/share/applications"
161
162 ZIP=build/dist/$(ls build/dist)
163 echo $ZIP
164 unzip $ZIP -d ${pkg_path}
165 f=("${pkg_path}"/*)
166 mv "${pkg_path}"/*/* "${pkg_path}"
167 rmdir "''${f[@]}"
168
169 for f in Ghidra/Framework/Gui/src/main/resources/images/GhidraIcon*.png; do
170 res=$(basename "$f" ".png" | cut -d"_" -f3 | cut -c11-)
171 install -Dm444 "$f" "$out/share/icons/hicolor/''${res}x''${res}/apps/ghidra.png"
172 done;
173 # improved macOS icon support
174 install -Dm444 Ghidra/Framework/Gui/src/main/resources/images/GhidraIcon64.png $out/share/icons/hicolor/32x32@2/apps/ghidra.png
175
176 runHook postInstall
177 '';
178
179 postFixup = ''
180 mkdir -p "$out/bin"
181 ln -s "${pkg_path}/ghidraRun" "$out/bin/ghidra"
182 ln -s "${pkg_path}/support/analyzeHeadless" "$out/bin/ghidra-analyzeHeadless"
183 wrapProgram "${pkg_path}/support/launch.sh" \
184 --set-default NIX_GHIDRAHOME "${pkg_path}/Ghidra" \
185 --prefix PATH : ${lib.makeBinPath [ openjdk21 ]}
186 '';
187
188 passthru = {
189 inherit releaseName distroPrefix;
190 inherit (ghidra-extensions.override { ghidra = finalAttrs.finalPackage; })
191 buildGhidraExtension
192 buildGhidraScripts
193 ;
194
195 withExtensions = callPackage ./with-extensions.nix { ghidra = finalAttrs.finalPackage; };
196 };
197
198 meta = with lib; {
199 changelog = "https://htmlpreview.github.io/?https://github.com/NationalSecurityAgency/ghidra/blob/Ghidra_${finalAttrs.version}_build/Ghidra/Configurations/Public_Release/src/global/docs/ChangeHistory.html";
200 description = "Software reverse engineering (SRE) suite of tools";
201 mainProgram = "ghidra";
202 homepage = "https://ghidra-sre.org/";
203 platforms = [
204 "x86_64-linux"
205 "aarch64-linux"
206 "x86_64-darwin"
207 "aarch64-darwin"
208 ];
209 sourceProvenance = with sourceTypes; [
210 fromSource
211 binaryBytecode # deps
212 ];
213 license = licenses.asl20;
214 maintainers = with maintainers; [
215 roblabla
216 vringar
217 ];
218 broken = stdenv.hostPlatform.isDarwin && stdenv.hostPlatform.isx86_64;
219 };
220})