biglybt: 3.5.0.0 -> 3.6.0.0
[NixPkgs.git] / pkgs / development / tools / analysis / retdec / default.nix
blob95e95bb34babc3abd1b4c00189067f8e4530b4e2
1 { stdenv
2 , fetchFromGitHub
3 , fetchpatch
4 , fetchzip
5 , writeText
6 , lib
7 , openssl
8 , cmake
9 , autoconf
10 , automake
11 , libtool
12 , pkg-config
13 , bison
14 , flex
15 , groff
16 , perl
17 , python3
18 , ncurses
19 , time
20 , upx
21 , gtest
22 , libffi
23 , libxml2
24 , zlib
25 , enableTests ? true
26 , buildDevTools ? true
27 , compileYaraPatterns ? true
30 let
31   # all dependencies that are normally fetched during build time (the subdirectories of `deps`)
32   # all of these need to be fetched through nix and applied via their <NAME>_URL cmake variable
33   capstone = fetchFromGitHub {
34     owner = "capstone-engine";
35     repo = "capstone";
36     rev = "5.0-rc2";
37     sha256 = "sha256-nB7FcgisBa8rRDS3k31BbkYB+tdqA6Qyj9hqCnFW+ME=";
38   };
39   llvm = fetchFromGitHub {
40     owner = "avast-tl";
41     repo = "llvm";
42     rev = "2a1f3d8a97241c6e91710be8f84cf3cf80c03390";
43     sha256 = "sha256-+v1T0VI9R92ed9ViqsfYZMJtPCjPHCr4FenoYdLuFOU=";
44   };
45   yaracpp = fetchFromGitHub {
46     owner = "VirusTotal";
47     repo = "yara";
48     rev = "v4.2.0-rc1";
49     sha256 = "sha256-WcN6ClYO2d+/MdG06RHx3kN0o0WVAY876dJiG7CwJ8w=";
50   };
51   yaramod = fetchFromGitHub {
52     owner = "avast";
53     repo = "yaramod";
54     rev = "aa06dd408c492a8f4488774caf2ee105ccc23ab5";
55     sha256 = "sha256-NVDRf2U5H92EN/Ks//uxNEaeKU+sT4VL4QyyYMO+zKk=";
56   };
57   keystone = fetchFromGitHub {
58     # only for tests
59     owner = "keystone-engine";
60     repo = "keystone";
61     rev = "d7ba8e378e5284e6384fc9ecd660ed5f6532e922";
62     sha256 = "1yzw3v8xvxh1rysh97y0i8y9svzbglx2zbsqjhrfx18vngh0x58f";
63   };
65   retdec-support-version = "2019-03-08";
66   retdec-support =
67     { rev = retdec-support-version; } // # for checking the version against the expected version
68     fetchzip {
69       url = "https://github.com/avast-tl/retdec-support/releases/download/${retdec-support-version}/retdec-support_${retdec-support-version}.tar.xz";
70       hash = "sha256-t1tx4MfLW/lwtbO5JQ1nrFBIOeMclq+0dENuXW+ahIM=";
71       stripRoot = false;
72     };
74   check-dep = name: dep:
75     ''
76       context="$(grep ${name}_URL --after-context 1 cmake/deps.cmake)"
77       expected="$(echo "$context" | grep --only-matching '".*"')"
78       have="${dep.rev}"
80       echo "checking ${name} dependency matches deps.cmake...";
81       if ! echo "$expected" | grep -q "$have"; then
82         printf '%s\n' "${name} version does not match!"  "  nix: $have, expected: $expected"
83         false
84       fi
85     '';
87   deps = {
88     CAPSTONE = capstone;
89     LLVM = llvm;
90     YARA = yaracpp;
91     YARAMOD = yaramod;
92     SUPPORT_PKG = retdec-support;
93   } // lib.optionalAttrs enableTests {
94     KEYSTONE = keystone;
95     # nixpkgs googletest is used
96     # GOOGLETEST = googletest;
97   };
99   # overwrite install-share.py to copy instead of download.
100   # we use this so the copy happens at the right time in the build,
101   # otherwise, the build process cleans the directory.
102   install-share =
103     writeText
104       "install-share.py"
105       ''
106         import os, sys, shutil, subprocess
108         install_path, arch_url, sha256hash_ref, version = sys.argv[1:]
109         support_dir = os.path.join(install_path, 'share', 'retdec', 'support')
111         assert os.path.isdir(arch_url), "nix install-share.py expects a path for support url"
113         os.makedirs(support_dir, exist_ok=True)
114         shutil.copytree(arch_url, support_dir, dirs_exist_ok=True)
115         subprocess.check_call(['chmod', '-R', 'u+w', support_dir])
116       '';
118 stdenv.mkDerivation (self: {
119   pname = "retdec";
121   # If you update this you will also need to adjust the versions of the updated dependencies.
122   # I've notified upstream about this problem here:
123   # https://github.com/avast-tl/retdec/issues/412
124   #
125   # The dependencies and their sources are listed in this file:
126   # https://github.com/avast/retdec/blob/master/cmake/deps.cmake
127   version = "5.0";
129   src = fetchFromGitHub {
130     owner = "avast";
131     repo = "retdec";
132     rev = "refs/tags/v${self.version}";
133     sha256 = "sha256-H4e+aSgdBBbG6X6DzHGiDEIASPwBVNVsfHyeBTQLAKI=";
134   };
136   patches = [
137     # gcc 13 compatibility: https://github.com/avast/retdec/pull/1153
138     (fetchpatch {
139       url = "https://github.com/avast/retdec/commit/dbaab2c3d17b1eae22c581e8ab6bfefadf4ef6ae.patch";
140       hash = "sha256-YqHYPGAGWT4x6C+CpsOSsOIZ+NPM2FBQtGQFs74OUIQ=";
141     })
142   ];
144   nativeBuildInputs = [
145     cmake
146     autoconf
147     automake
148     libtool
149     pkg-config
150     bison
151     flex
152     groff
153     perl
154     python3
155   ];
157   buildInputs = [
158     openssl
159     ncurses
160     libffi
161     libxml2
162     zlib
163   ] ++ lib.optional self.doInstallCheck gtest;
165   cmakeFlags = [
166     (lib.cmakeBool "RETDEC_TESTS" self.doInstallCheck) # build tests
167     (lib.cmakeBool "RETDEC_DEV_TOOLS" buildDevTools) # build tools e.g. capstone2llvmir, retdectool
168     (lib.cmakeBool "RETDEC_COMPILE_YARA" compileYaraPatterns) # build and install compiled patterns
169   ] ++ lib.mapAttrsToList (k: v: lib.cmakeFeature "${k}_URL" "${v}") deps;
171   preConfigure =
172     lib.concatStringsSep "\n" (lib.mapAttrsToList check-dep deps)
173     +
174     ''
175       cp -v ${install-share} ./support/install-share.py
177       # the CMakeLists assume CMAKE_INSTALL_BINDIR, etc are path components but in Nix, they are absolute.
178       # therefore, we need to remove the unnecessary CMAKE_INSTALL_PREFIX prepend.
179       substituteInPlace ./CMakeLists.txt \
180         --replace-warn "''$"{CMAKE_INSTALL_PREFIX}/"''$"{RETDEC_INSTALL_BIN_DIR} "''$"{CMAKE_INSTALL_FULL_BINDIR} \
181         --replace-warn "''$"{CMAKE_INSTALL_PREFIX}/"''$"{RETDEC_INSTALL_LIB_DIR} "''$"{CMAKE_INSTALL_FULL_LIBDIR} \
183       # --replace "''$"{CMAKE_INSTALL_PREFIX}/"''$"{RETDEC_INSTALL_SUPPORT_DIR} "''$"{RETDEC_INSTALL_SUPPORT_DIR}
184       # note! Nix does not set CMAKE_INSTALL_DATADIR to an absolute path, so this replacement would be incorrect
186       # similarly for yaramod. here, we fix the LIBDIR to lib64. for whatever reason, only "lib64" works.
187       substituteInPlace deps/yaramod/CMakeLists.txt \
188         --replace-fail "''$"{YARAMOD_INSTALL_DIR}/"''$"{CMAKE_INSTALL_LIBDIR} "''$"{YARAMOD_INSTALL_DIR}/lib64 \
189         --replace-fail CMAKE_ARGS 'CMAKE_ARGS -DCMAKE_INSTALL_LIBDIR=lib64'
191       # yara needs write permissions in the generated source directory.
192       echo ${lib.escapeShellArg ''
193         ExternalProject_Add_Step(
194           yara chmod WORKING_DIRECTORY ''${YARA_DIR}
195           DEPENDEES download COMMAND chmod -R u+w .
196         )
197       ''} >> deps/yara/CMakeLists.txt
199       # patch gtest to use the system package
200       gtest=deps/googletest/CMakeLists.txt
201       old="$(cat $gtest)"
202       (echo 'find_package(GTest REQUIRED)'; echo "$old") > $gtest
203       sed -i 's/ExternalProject_[^(]\+[(]/ set(IGNORED /g' $gtest
205       substituteInPlace $gtest \
206         --replace-fail '$'{GTEST_LIB} "GTest::gtest"\
207         --replace-fail '$'{GMOCK_LIB} "GTest::gmock"\
208         --replace-fail '$'{GTEST_MAIN_LIB} "GTest::gtest_main"\
209         --replace-fail '$'{GMOCK_MAIN_LIB} "GTest::gmock_main"
211       # without git history, there is no chance these tests will pass.
212       substituteInPlace tests/utils/version_tests.cpp \
213         --replace-quiet VersionTests DISABLED_VersionTests
215       substituteInPlace scripts/retdec-utils.py \
216         --replace-warn /usr/bin/time ${time} \
217         --replace-warn /usr/local/bin/gtime ${time}
218       substituteInPlace scripts/retdec-unpacker.py \
219         --replace-warn "'upx'" "'${upx}'"
220     '';
222   doInstallCheck = enableTests;
223   installCheckPhase = ''
224     ${python3.interpreter} "$out/bin/retdec-tests-runner.py"
226     rm -rf $out/bin/__pycache__
227   '';
229   meta = with lib; {
230     description = "A retargetable machine-code decompiler based on LLVM";
231     homepage = "https://retdec.com";
232     license = licenses.mit;
233     maintainers = with maintainers; [ dtzWill katrinafyi ];
234     platforms = [ "x86_64-linux" ];
235   };