1{
2 lib,
3 stdenv,
4 fetchurl,
5 replaceVars,
6 fetchDebianPatch,
7 fetchFromGitHub,
8 copyDesktopItems,
9 pkg-config,
10 wrapGAppsHook3,
11 unzip,
12 curl,
13 glib,
14 gtk3,
15 libidn2,
16 libssh2,
17 openssl,
18 wxGTK32,
19 makeDesktopItem,
20}:
21
22let
23 wxwidgets_3_3 = wxGTK32.overrideAttrs (
24 finalAttrs: previousAttrs: {
25 version = "3.3.0-unstable-2025-02-02";
26 src = fetchFromGitHub {
27 owner = "wxWidgets";
28 repo = "wxWidgets";
29 rev = "969c5a46b5c1da57836f721a4ce5df9feaa437f9";
30 fetchSubmodules = true;
31 hash = "sha256-ODPE896xc5RxdyfIzdPB5fsTeBm3O+asYJd99fuW6AY=";
32 };
33 patches = [
34 ./wxcolorhook.patch
35 ];
36 configureFlags = lib.subtractLists [
37 "--disable-compat28"
38 "--enable-unicode"
39 ] previousAttrs.configureFlags;
40 }
41 );
42in
43stdenv.mkDerivation (finalAttrs: {
44 pname = "freefilesync";
45 version = "14.3";
46
47 src = fetchurl {
48 url = "https://freefilesync.org/download/FreeFileSync_${finalAttrs.version}_Source.zip";
49 # The URL only redirects to the file on the second attempt
50 postFetch = ''
51 rm -f $out
52 tryDownload "$url"
53 '';
54 hash = "sha256-F8oIoG+SaHwhT7aA+iYp9/eWyGf6CiDIGm6Y2px0wlI=";
55 };
56
57 sourceRoot = ".";
58
59 patches = [
60 # Disable loading of the missing Animal.dat
61 ./skip-missing-Animal.dat.patch
62 # Fix build with GTK 3
63 (replaceVars ./Makefile.patch {
64 gtk3-dev = lib.getDev gtk3;
65 })
66 # Fix build with vanilla wxWidgets
67 (fetchDebianPatch {
68 pname = "freefilesync";
69 version = "13.7";
70 debianRevision = "1";
71 patch = "Disable_wxWidgets_uncaught_exception_handling.patch";
72 hash = "sha256-Fem7eDDKSqPFU/t12Jco8OmYC8FM9JgB4/QVy/ouvbI=";
73 })
74 ];
75
76 # https://freefilesync.org/forum/viewtopic.php?t=12163
77 postPatch = ''
78 substituteInPlace zen/socket.h zen/sys_error.h \
79 --replace-fail "#undef G_GNUC_UNUSED" ""
80 '';
81
82 nativeBuildInputs = [
83 copyDesktopItems
84 pkg-config
85 wrapGAppsHook3
86 unzip
87 ];
88
89 buildInputs = [
90 curl
91 glib
92 gtk3
93 libidn2
94 libssh2
95 openssl
96 wxwidgets_3_3
97 ];
98
99 env.NIX_CFLAGS_COMPILE = toString [
100 # Undef g_object_ref on GLib 2.56+
101 "-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_54"
102 "-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_54"
103 # Define libssh2 constants
104 "-DMAX_SFTP_READ_SIZE=30000"
105 "-DMAX_SFTP_OUTGOING_SIZE=30000"
106 ];
107
108 buildPhase = ''
109 runHook preBuild
110
111 chmod +w FreeFileSync/Build
112 cd FreeFileSync/Source
113 make -j$NIX_BUILD_CORES
114 cd RealTimeSync
115 make -j$NIX_BUILD_CORES
116 cd ../../..
117
118 runHook postBuild
119 '';
120
121 installPhase = ''
122 runHook preInstall
123
124 mkdir -p $out
125 cp -R FreeFileSync/Build/* $out
126 mv $out/{Bin,bin}
127
128 mkdir -p $out/share/pixmaps
129 unzip -j $out/Resources/Icons.zip '*Sync.png' -d $out/share/pixmaps
130
131 runHook postInstall
132 '';
133
134 desktopItems = [
135 (makeDesktopItem rec {
136 name = "FreeFileSync";
137 desktopName = name;
138 genericName = "Folder Comparison and Synchronization";
139 icon = name;
140 exec = name;
141 categories = [
142 "Utility"
143 "FileTools"
144 ];
145 })
146 (makeDesktopItem rec {
147 name = "RealTimeSync";
148 desktopName = name;
149 genericName = "Automated Synchronization";
150 icon = name;
151 exec = name;
152 categories = [
153 "Utility"
154 "FileTools"
155 ];
156 })
157 ];
158
159 meta = with lib; {
160 description = "Open Source File Synchronization & Backup Software";
161 homepage = "https://freefilesync.org";
162 license = [
163 licenses.gpl3Only
164 licenses.openssl
165 licenses.curl
166 licenses.bsd3
167 ];
168 maintainers = with maintainers; [ wegank ];
169 platforms = platforms.linux;
170 };
171})