1{
2 stdenv,
3 lib,
4 src,
5 version,
6 bison,
7 flex,
8 gperf,
9 lndir,
10 perl,
11 pkg-config,
12 which,
13 cmake,
14 ninja,
15 libproxy,
16 xorg,
17 zstd,
18 double-conversion,
19 util-linux,
20 systemd,
21 systemdSupport ? stdenv.hostPlatform.isLinux,
22 libb2,
23 md4c,
24 mtdev,
25 lksctp-tools,
26 libselinux,
27 libsepol,
28 vulkan-headers,
29 vulkan-loader,
30 libthai,
31 libdrm,
32 libdatrie,
33 lttng-ust,
34 libepoxy,
35 dbus,
36 fontconfig,
37 freetype,
38 glib,
39 harfbuzz,
40 icu,
41 libX11,
42 libXcomposite,
43 libXext,
44 libXi,
45 libXrender,
46 libjpeg,
47 libpng,
48 libxcb,
49 libxkbcommon,
50 libxml2,
51 libxslt,
52 openssl,
53 pcre2,
54 sqlite,
55 udev,
56 xcbutil,
57 xcbutilimage,
58 xcbutilkeysyms,
59 xcbutilrenderutil,
60 xcbutilwm,
61 zlib,
62 at-spi2-core,
63 unixODBC,
64 unixODBCDrivers,
65 libGL,
66 # darwin
67 moltenvk,
68 moveBuildTree,
69 darwinVersionInputs,
70 xcbuild,
71 # mingw
72 pkgsBuildBuild,
73 # optional dependencies
74 cups,
75 libmysqlclient,
76 libpq,
77 withGtk3 ? false,
78 gtk3,
79 withLibinput ? false,
80 libinput,
81 # options
82 qttranslations ? null,
83}:
84
85let
86 isCrossBuild = !stdenv.buildPlatform.canExecute stdenv.hostPlatform;
87in
88stdenv.mkDerivation rec {
89 pname = "qtbase";
90
91 inherit src version;
92
93 propagatedBuildInputs = [
94 libxml2
95 libxslt
96 openssl
97 sqlite
98 zlib
99 libGL
100 vulkan-headers
101 vulkan-loader
102 # Text rendering
103 harfbuzz
104 icu
105 # Image formats
106 libjpeg
107 libpng
108 pcre2
109 zstd
110 libb2
111 md4c
112 double-conversion
113 ]
114 ++ lib.optionals (!stdenv.hostPlatform.isMinGW) [
115 libproxy
116 dbus
117 glib
118 # unixODBC drivers
119 unixODBC
120 unixODBCDrivers.psql
121 unixODBCDrivers.sqlite
122 unixODBCDrivers.mariadb
123 ]
124 ++ lib.optionals systemdSupport [
125 systemd
126 ]
127 ++ lib.optionals stdenv.hostPlatform.isLinux [
128 util-linux
129 mtdev
130 lksctp-tools
131 libselinux
132 libsepol
133 lttng-ust
134 libthai
135 libdrm
136 libdatrie
137 udev
138 # Text rendering
139 fontconfig
140 freetype
141 # X11 libs
142 libX11
143 libXcomposite
144 libXext
145 libXi
146 libXrender
147 libxcb
148 libxkbcommon
149 xcbutil
150 xcbutilimage
151 xcbutilkeysyms
152 xcbutilrenderutil
153 xcbutilwm
154 xorg.libXdmcp
155 xorg.libXtst
156 xorg.xcbutilcursor
157 libepoxy
158 ]
159 ++ lib.optional (cups != null && lib.meta.availableOn stdenv.hostPlatform cups) cups;
160
161 buildInputs =
162 lib.optionals (lib.meta.availableOn stdenv.hostPlatform at-spi2-core) [
163 at-spi2-core
164 ]
165 ++ lib.optionals stdenv.hostPlatform.isDarwin (darwinVersionInputs ++ [ moltenvk ])
166 ++ lib.optional withGtk3 gtk3
167 ++ lib.optional withLibinput libinput
168 ++ lib.optional (libmysqlclient != null && !stdenv.hostPlatform.isMinGW) libmysqlclient
169 ++ lib.optional (libpq != null && lib.meta.availableOn stdenv.hostPlatform libpq) libpq;
170
171 nativeBuildInputs = [
172 bison
173 flex
174 gperf
175 lndir
176 perl
177 pkg-config
178 which
179 cmake
180 ninja
181 ]
182 ++ lib.optionals stdenv.hostPlatform.isDarwin [ moveBuildTree ];
183
184 propagatedNativeBuildInputs = [
185 lndir
186 ]
187 # I’m not sure if this is necessary, but the macOS mkspecs stuff
188 # tries to call `xcrun xcodebuild`, so better safe than sorry.
189 ++ lib.optionals stdenv.hostPlatform.isDarwin [ xcbuild ];
190
191 strictDeps = true;
192
193 enableParallelBuilding = true;
194
195 patches = [
196 # look for Qt plugins in directories on PATH
197 ./derive-plugin-load-path-from-PATH.patch
198
199 # allow translations to be found outside of install prefix, as is the case in our split builds
200 ./allow-translations-outside-prefix.patch
201
202 # always link to libraries by name in qmake-generated build scripts
203 ./qmake-always-use-libname.patch
204 # always explicitly list includedir in qmake-generated pkg-config files
205 ./qmake-fix-includedir.patch
206
207 # don't generate SBOM files by default, they don't work with our split installs anyway
208 ./no-sbom.patch
209
210 # use cmake from PATH in qt-cmake wrapper, to avoid qtbase runtime-depending on cmake
211 ./use-cmake-from-path.patch
212
213 # macdeployqt fixes
214 # get qmlimportscanner location from environment variable
215 ./find-qmlimportscanner.patch
216 # pass QML2_IMPORT_PATH from environment to qmlimportscanner
217 ./qmlimportscanner-import-path.patch
218 # don't pass qtbase's QML directory to qmlimportscanner if it's empty
219 ./skip-missing-qml-directory.patch
220 ];
221
222 postPatch = lib.optionalString stdenv.hostPlatform.isDarwin ''
223 # TODO: Verify that this catches all the occurrences?
224 for file in \
225 cmake/QtPublicAppleHelpers.cmake \
226 mkspecs/features/mac/asset_catalogs.prf \
227 mkspecs/features/mac/default_pre.prf \
228 mkspecs/features/mac/sdk.mk \
229 mkspecs/features/mac/sdk.prf \
230 mkspecs/features/permissions.prf \
231 src/corelib/Qt6CoreMacros.cmake
232 do
233 substituteInPlace "$file" \
234 --replace-quiet /usr/bin/xcrun '${lib.getExe' xcbuild "xcrun"}' \
235 --replace-quiet /usr/bin/xcode-select '${lib.getExe' xcbuild "xcode-select"}' \
236 --replace-quiet /usr/libexec/PlistBuddy '${lib.getExe' xcbuild "PlistBuddy"}'
237 done
238
239 substituteInPlace mkspecs/common/macx.conf \
240 --replace-fail 'CONFIG += ' 'CONFIG += no_default_rpath '
241 '';
242
243 fix_qt_builtin_paths = ../../hooks/fix-qt-builtin-paths.sh;
244 fix_qt_module_paths = ../../hooks/fix-qt-module-paths.sh;
245 preHook = ''
246 . "$fix_qt_builtin_paths"
247 . "$fix_qt_module_paths"
248 '';
249
250 qtPluginPrefix = "lib/qt-6/plugins";
251 qtQmlPrefix = "lib/qt-6/qml";
252
253 cmakeFlags = [
254 "-DQT_EMBED_TOOLCHAIN_COMPILER=OFF"
255 "-DINSTALL_PLUGINSDIR=${qtPluginPrefix}"
256 "-DINSTALL_QMLDIR=${qtQmlPrefix}"
257 "-DQT_FEATURE_libproxy=ON"
258 "-DQT_FEATURE_system_sqlite=ON"
259 "-DQT_FEATURE_openssl_linked=ON"
260 "-DQT_FEATURE_vulkan=ON"
261 # don't leak OS version into the final output
262 # https://bugreports.qt.io/browse/QTBUG-136060
263 "-DCMAKE_SYSTEM_VERSION="
264 ]
265 ++ lib.optionals (!stdenv.hostPlatform.isDarwin) [
266 "-DQT_FEATURE_sctp=ON"
267 "-DQT_FEATURE_journald=${if systemdSupport then "ON" else "OFF"}"
268 ]
269 ++ lib.optionals stdenv.hostPlatform.isDarwin [
270 "-DQT_FEATURE_rpath=OFF"
271 "-DQT_NO_XCODE_MIN_VERSION_CHECK=ON"
272 # This is only used for the min version check, which we disabled above.
273 # When this variable is not set, cmake tries to execute xcodebuild
274 # to query the version.
275 "-DQT_INTERNAL_XCODE_VERSION=0.1"
276 ]
277 ++ lib.optionals isCrossBuild [
278 "-DQT_HOST_PATH=${pkgsBuildBuild.qt6.qtbase}"
279 "-DQt6HostInfo_DIR=${pkgsBuildBuild.qt6.qtbase}/lib/cmake/Qt6HostInfo"
280 ]
281 ++ lib.optional (
282 qttranslations != null && !isCrossBuild
283 ) "-DINSTALL_TRANSLATIONSDIR=${qttranslations}/translations";
284
285 env.NIX_CFLAGS_COMPILE = "-DNIXPKGS_QT_PLUGIN_PREFIX=\"${qtPluginPrefix}\"";
286
287 outputs = [
288 "out"
289 "dev"
290 ];
291 separateDebugInfo = true;
292
293 moveToDev = false;
294
295 postFixup = ''
296 moveToOutput "mkspecs/modules" "$dev"
297 fixQtModulePaths "$dev/mkspecs/modules"
298 fixQtBuiltinPaths "$out" '*.pr?'
299 ''
300 + lib.optionalString stdenv.hostPlatform.isLinux ''
301 # FIXME: not sure why this isn't added automatically?
302 patchelf --add-rpath "${libmysqlclient}/lib/mariadb" $out/${qtPluginPrefix}/sqldrivers/libqsqlmysql.so
303 patchelf --add-rpath "${vulkan-loader}/lib" --add-needed "libvulkan.so" $out/lib/libQt6Gui.so
304 '';
305
306 dontWrapQtApps = true;
307
308 setupHook = ../../hooks/qtbase-setup-hook.sh;
309
310 meta = with lib; {
311 homepage = "https://www.qt.io/";
312 description = "Cross-platform application framework for C++";
313 license = with licenses; [
314 fdl13Plus
315 gpl2Plus
316 lgpl21Plus
317 lgpl3Plus
318 ];
319 maintainers = with maintainers; [
320 nickcao
321 LunNova
322 ];
323 platforms = platforms.unix ++ platforms.windows;
324 };
325}