Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / development / libraries / qt-5 / modules / qtbase.nix
blob67e9bd5440d118b473cb78150b9f0b72501a7598
1 { stdenv, lib
2 , src, patches, version, qtCompatVersion
4 , coreutils, bison, flex, gdb, gperf, lndir, perl, pkg-config, python3
5 , which
6   # darwin support
7 , libiconv, libobjc, xcbuild, AGL, AppKit, ApplicationServices, AVFoundation, Carbon, Cocoa, CoreAudio, CoreBluetooth
8 , CoreLocation, CoreServices, DiskArbitration, Foundation, OpenGL, MetalKit, IOKit
10 , dbus, fontconfig, freetype, glib, harfbuzz, icu, libdrm, libX11, libXcomposite
11 , libXcursor, libXext, libXi, libXrender, libinput, libjpeg, libpng , libxcb
12 , libxkbcommon, libxml2, libxslt, openssl, pcre2, sqlite, udev, xcbutil
13 , xcbutilimage, xcbutilkeysyms, xcbutilrenderutil, xcbutilwm , zlib, at-spi2-core
15   # optional dependencies
16 , cups ? null, postgresql ? null
17 , withGtk3 ? false, dconf, gtk3
18 , qttranslations ? null
20   # options
21 , libGLSupported ? !stdenv.isDarwin
22 , libGL
23   # qmake detection for libmysqlclient does not seem to work when cross compiling
24 , mysqlSupport ? stdenv.hostPlatform == stdenv.buildPlatform
25 , libmysqlclient
26 , buildExamples ? false
27 , buildTests ? false
28 , debug ? false
29 , developerBuild ? false
30 , decryptSslTraffic ? false
31 , testers
32 , buildPackages
35 let
36   debugSymbols = debug || developerBuild;
37   qtPlatformCross = plat: with plat;
38     if isLinux
39     then "linux-generic-g++"
40     else throw "Please add a qtPlatformCross entry for ${plat.config}";
43 stdenv.mkDerivation (finalAttrs: ({
44   pname = "qtbase";
45   inherit qtCompatVersion src version;
46   debug = debugSymbols;
48   propagatedBuildInputs = [
49     libxml2 libxslt openssl sqlite zlib
51     # Text rendering
52     harfbuzz icu
54     # Image formats
55     libjpeg libpng
56     pcre2
57   ] ++ (
58     if stdenv.isDarwin then [
59       # TODO: move to buildInputs, this should not be propagated.
60       AGL AppKit ApplicationServices AVFoundation Carbon Cocoa CoreAudio CoreBluetooth
61       CoreLocation CoreServices DiskArbitration Foundation OpenGL
62       libobjc libiconv MetalKit IOKit
63     ] else [
64       dbus glib udev
66       # Text rendering
67       fontconfig freetype
69       libdrm
71       # X11 libs
72       libX11 libXcomposite libXext libXi libXrender libxcb libxkbcommon xcbutil
73       xcbutilimage xcbutilkeysyms xcbutilrenderutil xcbutilwm
74     ] ++ lib.optional libGLSupported libGL
75   );
77   buildInputs = [ python3 at-spi2-core ]
78     ++ lib.optionals (!stdenv.isDarwin)
79     (
80       [ libinput ]
81       ++ lib.optional withGtk3 gtk3
82     )
83     ++ lib.optional developerBuild gdb
84     ++ lib.optional (cups != null) cups
85     ++ lib.optional (mysqlSupport) libmysqlclient
86     ++ lib.optional (postgresql != null) postgresql;
88   nativeBuildInputs = [ bison flex gperf lndir perl pkg-config which ]
89     ++ lib.optionals stdenv.isDarwin [ xcbuild ];
91   } // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) {
92     # `qtbase` expects to find `cc` (with no prefix) in the
93     # `$PATH`, so the following is needed even if
94     # `stdenv.buildPlatform.canExecute stdenv.hostPlatform`
95     depsBuildBuild = [ buildPackages.stdenv.cc ];
96   } // {
98   propagatedNativeBuildInputs = [ lndir ];
100   # libQt5Core links calls CoreFoundation APIs that call into the system ICU. Binaries linked
101   # against it will crash during build unless they can access `/usr/share/icu/icudtXXl.dat`.
102   propagatedSandboxProfile = lib.optionalString stdenv.isDarwin ''
103     (allow file-read* (subpath "/usr/share/icu"))
104   '';
106   enableParallelBuilding = true;
108   outputs = [ "bin" "dev" "out" ];
110   inherit patches;
112   fix_qt_builtin_paths = ../hooks/fix-qt-builtin-paths.sh;
113   fix_qt_module_paths = ../hooks/fix-qt-module-paths.sh;
114   preHook = ''
115     . "$fix_qt_builtin_paths"
116     . "$fix_qt_module_paths"
117     . ${../hooks/move-qt-dev-tools.sh}
118     . ${../hooks/fix-qmake-libtool.sh}
119   '';
121   postPatch = ''
122     for prf in qml_plugin.prf qt_plugin.prf qt_docs.prf qml_module.prf create_cmake.prf; do
123         substituteInPlace "mkspecs/features/$prf" \
124             --subst-var qtPluginPrefix \
125             --subst-var qtQmlPrefix \
126             --subst-var qtDocPrefix
127     done
129     substituteInPlace configure --replace /bin/pwd pwd
130     substituteInPlace src/corelib/global/global.pri --replace /bin/ls ${coreutils}/bin/ls
131     sed -e 's@/\(usr\|opt\)/@/var/empty/@g' -i mkspecs/*/*.conf
133     sed -i '/PATHS.*NO_DEFAULT_PATH/ d' src/corelib/Qt5Config.cmake.in
134     sed -i '/PATHS.*NO_DEFAULT_PATH/ d' src/corelib/Qt5CoreMacros.cmake
135     sed -i 's/NO_DEFAULT_PATH//' src/gui/Qt5GuiConfigExtras.cmake.in
136     sed -i '/PATHS.*NO_DEFAULT_PATH/ d' mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
138     # https://bugs.gentoo.org/803470
139     sed -i 's/-lpthread/-pthread/' mkspecs/common/linux.conf src/corelib/configure.json
141     patchShebangs ./bin
142   '' + (
143     if stdenv.isDarwin then ''
144         sed -i \
145             -e 's|/usr/bin/xcode-select|xcode-select|' \
146             -e 's|/usr/bin/xcrun|xcrun|' \
147             -e 's|/usr/bin/xcodebuild|xcodebuild|' \
148             -e 's|QMAKE_CONF_COMPILER=`getXQMakeConf QMAKE_CXX`|QMAKE_CXX="clang++"\nQMAKE_CONF_COMPILER="clang++"|' \
149             ./configure
150             substituteInPlace ./mkspecs/common/mac.conf \
151                 --replace "/System/Library/Frameworks/OpenGL.framework/" "${OpenGL}/Library/Frameworks/OpenGL.framework/" \
152                 --replace "/System/Library/Frameworks/AGL.framework/" "${AGL}/Library/Frameworks/AGL.framework/"
153     '' else lib.optionalString libGLSupported ''
154       sed -i mkspecs/common/linux.conf \
155           -e "/^QMAKE_INCDIR_OPENGL/ s|$|${libGL.dev or libGL}/include|" \
156           -e "/^QMAKE_LIBDIR_OPENGL/ s|$|${libGL.out}/lib|"
157     '' + lib.optionalString (stdenv.hostPlatform.isx86_32 && stdenv.cc.isGNU) ''
158       sed -i mkspecs/common/gcc-base-unix.conf \
159           -e "/^QMAKE_LFLAGS_SHLIB/ s/-shared/-shared -static-libgcc/"
160     ''
161   );
163   qtPluginPrefix = "lib/qt-${qtCompatVersion}/plugins";
164   qtQmlPrefix = "lib/qt-${qtCompatVersion}/qml";
165   qtDocPrefix = "share/doc/qt-${qtCompatVersion}";
167   setOutputFlags = false;
168   preConfigure = ''
169     export LD_LIBRARY_PATH="$PWD/lib:$PWD/plugins/platforms''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH"
171     NIX_CFLAGS_COMPILE+=" -DNIXPKGS_QT_PLUGIN_PREFIX=\"$qtPluginPrefix\""
173     # paralellize compilation of qtmake, which happens within ./configure
174     export MAKEFLAGS+=" -j$NIX_BUILD_CORES"
176     ./bin/syncqt.pl -version $version
177   '' + lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
178     # QT's configure script will refuse to use pkg-config unless these two environment variables are set
179     export PKG_CONFIG_SYSROOT_DIR=/
180     export PKG_CONFIG_LIBDIR=${lib.getLib pkg-config}/lib
181     echo "QMAKE_LFLAGS=''${LDFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf
182     echo "QMAKE_CFLAGS=''${CFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf
183     echo "QMAKE_CXXFLAGS=''${CXXFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf
184   '';
186   postConfigure = ''
187     qmakeCacheInjectNixOutputs() {
188         local cache="$1/.qmake.stash"
189         echo "qmakeCacheInjectNixOutputs: $cache"
190         if ! [ -f "$cache" ]; then
191             echo >&2 "qmakeCacheInjectNixOutputs: WARNING: $cache does not exist"
192         fi
193         cat >>"$cache" <<EOF
194     NIX_OUTPUT_BIN = $bin
195     NIX_OUTPUT_DEV = $dev
196     NIX_OUTPUT_OUT = $out
197     NIX_OUTPUT_DOC = $dev/$qtDocPrefix
198     NIX_OUTPUT_QML = $bin/$qtQmlPrefix
199     NIX_OUTPUT_PLUGIN = $bin/$qtPluginPrefix
200     EOF
201     }
203     find . -name '.qmake.conf' | while read conf; do
204         qmakeCacheInjectNixOutputs "$(dirname $conf)"
205     done
206   '';
208   env = {
209     NIX_CFLAGS_COMPILE = toString ([
210       "-Wno-error=sign-compare" # freetype-2.5.4 changed signedness of some struct fields
211     ] ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
212       "-Wno-warn=free-nonheap-object"
213       "-Wno-free-nonheap-object"
214       "-w"
215     ] ++ [
216       ''-DNIXPKGS_QTCOMPOSE="${libX11.out}/share/X11/locale"''
217       ''-DLIBRESOLV_SO="${stdenv.cc.libc.out}/lib/libresolv"''
218       ''-DNIXPKGS_LIBXCURSOR="${libXcursor.out}/lib/libXcursor"''
219     ] ++ lib.optional libGLSupported ''-DNIXPKGS_MESA_GL="${libGL.out}/lib/libGL"''
220     ++ lib.optional stdenv.isLinux "-DUSE_X11"
221     ++ lib.optionals (stdenv.hostPlatform.system == "x86_64-darwin") [
222       # ignore "is only available on macOS 10.12.2 or newer" in obj-c code
223       "-Wno-error=unguarded-availability"
224     ]
225     ++ lib.optionals withGtk3 [
226       ''-DNIXPKGS_QGTK3_XDG_DATA_DIRS="${gtk3}/share/gsettings-schemas/${gtk3.name}"''
227       ''-DNIXPKGS_QGTK3_GIO_EXTRA_MODULES="${dconf.lib}/lib/gio/modules"''
228     ] ++ lib.optional decryptSslTraffic "-DQT_DECRYPT_SSL_TRAFFIC");
229   } // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) {
230     NIX_CFLAGS_COMPILE_FOR_BUILD = toString ([
231       "-Wno-warn=free-nonheap-object"
232       "-Wno-free-nonheap-object"
233       "-w"
234     ]);
235   };
237   prefixKey = "-prefix ";
239   # PostgreSQL autodetection fails sporadically because Qt omits the "-lpq" flag
240   # if dependency paths contain the string "pq", which can occur in the hash.
241   # To prevent these failures, we need to override PostgreSQL detection.
242   PSQL_LIBS = lib.optionalString (postgresql != null) "-L${postgresql.lib}/lib -lpq";
244   } // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) {
245   configurePlatforms = [ ];
246   } // {
247   # TODO Remove obsolete and useless flags once the build will be totally mastered
248   configureFlags = [
249     "-plugindir $(out)/$(qtPluginPrefix)"
250     "-qmldir $(out)/$(qtQmlPrefix)"
251     "-docdir $(out)/$(qtDocPrefix)"
253     "-verbose"
254     "-confirm-license"
255     "-opensource"
257     "-release"
258     "-shared"
259     "-accessibility"
260     "-optimized-qmake"
261     # for separateDebugInfo
262     "-no-strip"
263     "-system-proxies"
264     "-pkg-config"
266     "-gui"
267     "-widgets"
268     "-opengl desktop"
269     "-icu"
270     "-L" "${icu.out}/lib"
271     "-I" "${icu.dev}/include"
272     "-pch"
273   ] ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [
274     "-device ${qtPlatformCross stdenv.hostPlatform}"
275     "-device-option CROSS_COMPILE=${stdenv.cc.targetPrefix}"
276   ]
277   ++ lib.optional debugSymbols "-debug"
278   ++ lib.optionals developerBuild [
279     "-developer-build"
280     "-no-warnings-are-errors"
281   ] ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
282     "-no-warnings-are-errors"
283   ] ++ (if (!stdenv.hostPlatform.isx86_64) then [
284     "-no-sse2"
285   ] else [
286     "-sse2"
287     "${lib.optionalString (!stdenv.hostPlatform.sse3Support)   "-no"}-sse3"
288     "${lib.optionalString (!stdenv.hostPlatform.ssse3Support)  "-no"}-ssse3"
289     "${lib.optionalString (!stdenv.hostPlatform.sse4_1Support) "-no"}-sse4.1"
290     "${lib.optionalString (!stdenv.hostPlatform.sse4_2Support) "-no"}-sse4.2"
291     "${lib.optionalString (!stdenv.hostPlatform.avxSupport)    "-no"}-avx"
292     "${lib.optionalString (!stdenv.hostPlatform.avx2Support)   "-no"}-avx2"
293     ]
294   ) ++ [
295     "-no-mips_dsp"
296     "-no-mips_dspr2"
297   ] ++ [
298     "-system-zlib"
299     "-L" "${zlib.out}/lib"
300     "-I" "${zlib.dev}/include"
301     "-system-libjpeg"
302     "-L" "${libjpeg.out}/lib"
303     "-I" "${libjpeg.dev}/include"
304     "-system-harfbuzz"
305     "-L" "${harfbuzz.out}/lib"
306     "-I" "${harfbuzz.dev}/include"
307     "-system-pcre"
308     "-openssl-linked"
309     "-L" "${lib.getLib openssl}/lib"
310     "-I" "${openssl.dev}/include"
311     "-system-sqlite"
312     ''-${if mysqlSupport then "plugin" else "no"}-sql-mysql''
313     ''-${if postgresql != null then "plugin" else "no"}-sql-psql''
315     "-make libs"
316     "-make tools"
317     ''-${lib.optionalString (!buildExamples) "no"}make examples''
318     ''-${lib.optionalString (!buildTests) "no"}make tests''
319   ]
320     ++ (
321       if stdenv.isDarwin then [
322       "-no-fontconfig"
323       "-qt-freetype"
324       "-qt-libpng"
325       "-no-framework"
326     ] else [
327       "-rpath"
328     ] ++ [
329       "-xcb"
330       "-qpa xcb"
331       "-L" "${libX11.out}/lib"
332       "-I" "${libX11.out}/include"
333       "-L" "${libXext.out}/lib"
334       "-I" "${libXext.out}/include"
335       "-L" "${libXrender.out}/lib"
336       "-I" "${libXrender.out}/include"
338       "-libinput"
340       ''-${lib.optionalString (cups == null) "no-"}cups''
341       "-dbus-linked"
342       "-glib"
343     ] ++ [
344       "-system-libpng"
345     ] ++ lib.optional withGtk3 "-gtk"
346       ++ [
347         "-inotify"
348     ] ++ lib.optionals (cups != null) [
349       "-L" "${cups.lib}/lib"
350       "-I" "${cups.dev}/include"
351     ] ++ lib.optionals (mysqlSupport) [
352       "-L" "${libmysqlclient}/lib"
353       "-I" "${libmysqlclient}/include"
354     ] ++ lib.optional (qttranslations != null) [
355       "-translationdir" "${qttranslations}/translations"
356     ]
357   );
359   # Move selected outputs.
360   postInstall = ''
361     moveToOutput "mkspecs" "$dev"
362   '';
364   devTools = [
365     "bin/fixqt4headers.pl"
366     "bin/moc"
367     "bin/qdbuscpp2xml"
368     "bin/qdbusxml2cpp"
369     "bin/qlalr"
370     "bin/qmake"
371     "bin/rcc"
372     "bin/syncqt.pl"
373     "bin/uic"
374   ];
376   postFixup = ''
377     # Don't retain build-time dependencies like gdb.
378     sed '/QMAKE_DEFAULT_.*DIRS/ d' -i $dev/mkspecs/qconfig.pri
379     fixQtModulePaths "''${!outputDev}/mkspecs/modules"
380     fixQtBuiltinPaths "''${!outputDev}" '*.pr?'
382     # Move development tools to $dev
383     moveQtDevTools
384     moveToOutput bin "$dev"
386     # fixup .pc file (where to find 'moc' etc.)
387     sed -i "$dev/lib/pkgconfig/Qt5Core.pc" \
388       -e "/^host_bins=/ c host_bins=$dev/bin"
389   '';
391   dontStrip = debugSymbols;
393   setupHook = ../hooks/qtbase-setup-hook.sh;
395   passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage;
397   meta = with lib; {
398     homepage = "https://www.qt.io/";
399     description = "A cross-platform application framework for C++";
400     license = with licenses; [ fdl13Plus gpl2Plus lgpl21Plus lgpl3Plus ];
401     maintainers = with maintainers; [ qknight ttuegel periklis bkchr ];
402     pkgConfigModules = [
403       "Qt5Concurrent"
404       "Qt5Core"
405       "Qt5DBus"
406       "Qt5Gui"
407       "Qt5Network"
408       "Qt5OpenGL"
409       "Qt5OpenGLExtensions"
410       "Qt5PrintSupport"
411       #"Qt5Qml"
412       #"Qt5QmlModels"
413       #"Qt5Quick"
414       #"Qt5QuickTest"
415       #"Qt5QuickWidgets"
416       "Qt5Sql"
417       "Qt5Test"
418       "Qt5Widgets"
419       "Qt5Xml"
420     ];
421     platforms = platforms.unix;
422   };