at master 17 kB view raw
1{ 2 stdenv, 3 lib, 4 src, 5 patches, 6 version, 7 qtCompatVersion, 8 9 coreutils, 10 bison, 11 flex, 12 gdb, 13 gperf, 14 lndir, 15 perl, 16 pkg-config, 17 python3, 18 which, 19 # darwin support 20 apple-sdk_14, 21 xcbuild, 22 23 dbus, 24 fontconfig, 25 freetype, 26 glib, 27 harfbuzz, 28 icu, 29 libdrm, 30 libX11, 31 libXcomposite, 32 libXcursor, 33 libXext, 34 libXi, 35 libXrender, 36 libjpeg, 37 libpng, 38 libxcb, 39 libxkbcommon, 40 libxml2, 41 libxslt, 42 openssl, 43 pcre2, 44 sqlite, 45 udev, 46 xcbutil, 47 xcbutilimage, 48 xcbutilkeysyms, 49 xcbutilrenderutil, 50 xcbutilwm, 51 zlib, 52 at-spi2-core, 53 54 # optional dependencies 55 cups ? null, 56 libpq ? null, 57 withGtk3 ? false, 58 dconf, 59 gtk3, 60 withQttranslation ? true, 61 qttranslations ? null, 62 withLibinput ? false, 63 libinput, 64 65 # options 66 libGLSupported ? !stdenv.hostPlatform.isDarwin, 67 libGL, 68 # qmake detection for libmysqlclient does not seem to work when cross compiling 69 mysqlSupport ? stdenv.hostPlatform == stdenv.buildPlatform, 70 libmysqlclient, 71 buildExamples ? false, 72 buildTests ? false, 73 debug ? false, 74 developerBuild ? false, 75 decryptSslTraffic ? false, 76 testers, 77 buildPackages, 78}: 79 80let 81 debugSymbols = debug || developerBuild; 82 qtPlatformCross = 83 plat: 84 with plat; 85 if isLinux then 86 "linux-generic-g++" 87 else 88 throw "Please add a qtPlatformCross entry for ${plat.config}"; 89 90 # Per https://doc.qt.io/qt-5/macos.html#supported-versions: build SDK = 13.x or 14.x. 91 darwinVersionInputs = [ 92 apple-sdk_14 93 ]; 94in 95 96stdenv.mkDerivation ( 97 finalAttrs: 98 ( 99 { 100 pname = "qtbase"; 101 inherit qtCompatVersion src version; 102 debug = debugSymbols; 103 104 propagatedBuildInputs = [ 105 libxml2 106 libxslt 107 openssl 108 sqlite 109 zlib 110 111 # Text rendering 112 freetype 113 harfbuzz 114 icu 115 116 # Image formats 117 libjpeg 118 libpng 119 pcre2 120 ] 121 ++ lib.optionals (!stdenv.hostPlatform.isDarwin) ( 122 [ 123 dbus 124 glib 125 udev 126 127 # Text rendering 128 fontconfig 129 130 libdrm 131 132 # X11 libs 133 libX11 134 libXcomposite 135 libXext 136 libXi 137 libXrender 138 libxcb 139 libxkbcommon 140 xcbutil 141 xcbutilimage 142 xcbutilkeysyms 143 xcbutilrenderutil 144 xcbutilwm 145 ] 146 ++ lib.optional libGLSupported libGL 147 ); 148 149 buildInputs = [ 150 python3 151 at-spi2-core 152 ] 153 ++ lib.optionals (!stdenv.hostPlatform.isDarwin) ( 154 lib.optional withLibinput libinput ++ lib.optional withGtk3 gtk3 155 ) 156 ++ lib.optional stdenv.hostPlatform.isDarwin darwinVersionInputs 157 ++ lib.optional developerBuild gdb 158 ++ lib.optional (cups != null) cups 159 ++ lib.optional (mysqlSupport) libmysqlclient 160 ++ lib.optional (libpq != null) libpq; 161 162 nativeBuildInputs = [ 163 bison 164 flex 165 gperf 166 lndir 167 perl 168 pkg-config 169 which 170 ] 171 ++ lib.optionals (mysqlSupport) [ libmysqlclient ] 172 ++ lib.optionals stdenv.hostPlatform.isDarwin [ xcbuild ]; 173 174 } 175 // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) { 176 # `qtbase` expects to find `cc` (with no prefix) in the 177 # `$PATH`, so the following is needed even if 178 # `stdenv.buildPlatform.canExecute stdenv.hostPlatform` 179 depsBuildBuild = [ buildPackages.stdenv.cc ]; 180 } 181 // { 182 183 propagatedNativeBuildInputs = [ lndir ]; 184 185 strictDeps = true; 186 187 # libQt5Core links calls CoreFoundation APIs that call into the system ICU. Binaries linked 188 # against it will crash during build unless they can access `/usr/share/icu/icudtXXl.dat`. 189 propagatedSandboxProfile = lib.optionalString stdenv.hostPlatform.isDarwin '' 190 (allow file-read* (subpath "/usr/share/icu")) 191 ''; 192 193 enableParallelBuilding = true; 194 195 outputs = [ 196 "bin" 197 "dev" 198 "out" 199 ]; 200 201 inherit patches; 202 203 fix_qt_builtin_paths = ../hooks/fix-qt-builtin-paths.sh; 204 fix_qt_module_paths = ../hooks/fix-qt-module-paths.sh; 205 preHook = '' 206 . "$fix_qt_builtin_paths" 207 . "$fix_qt_module_paths" 208 . ${../hooks/move-qt-dev-tools.sh} 209 . ${../hooks/fix-qmake-libtool.sh} 210 ''; 211 212 postPatch = '' 213 for prf in qml_plugin.prf qt_plugin.prf qt_docs.prf qml_module.prf create_cmake.prf; do 214 substituteInPlace "mkspecs/features/$prf" \ 215 --subst-var qtPluginPrefix \ 216 --subst-var qtQmlPrefix \ 217 --subst-var qtDocPrefix 218 done 219 220 substituteInPlace configure --replace /bin/pwd pwd 221 substituteInPlace src/corelib/global/global.pri --replace /bin/ls ${coreutils}/bin/ls 222 sed -e 's@/\(usr\|opt\)/@/var/empty/@g' -i mkspecs/*/*.conf 223 224 sed -i '/PATHS.*NO_DEFAULT_PATH/ d' src/corelib/Qt5Config.cmake.in 225 sed -i '/PATHS.*NO_DEFAULT_PATH/ d' src/corelib/Qt5CoreMacros.cmake 226 sed -i 's/NO_DEFAULT_PATH//' src/gui/Qt5GuiConfigExtras.cmake.in 227 sed -i '/PATHS.*NO_DEFAULT_PATH/ d' mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in 228 229 # https://bugs.gentoo.org/803470 230 sed -i 's/-lpthread/-pthread/' mkspecs/common/linux.conf src/corelib/configure.json 231 232 patchShebangs ./bin 233 '' 234 + ( 235 if stdenv.hostPlatform.isDarwin then 236 '' 237 for file in \ 238 configure \ 239 mkspecs/features/mac/asset_catalogs.prf \ 240 mkspecs/features/mac/default_pre.prf \ 241 mkspecs/features/mac/sdk.mk \ 242 mkspecs/features/mac/sdk.prf 243 do 244 substituteInPlace "$file" \ 245 --replace-quiet /usr/bin/xcode-select '${lib.getExe' xcbuild "xcode-select"}' \ 246 --replace-quiet /usr/bin/xcrun '${lib.getExe' xcbuild "xcrun"}' \ 247 --replace-quiet /usr/libexec/PlistBuddy '${lib.getExe' xcbuild "PlistBuddy"}' 248 done 249 250 substituteInPlace configure \ 251 --replace-fail /System/Library/Frameworks/Cocoa.framework "$SDKROOT/System/Library/Frameworks/Cocoa.framework" 252 253 substituteInPlace mkspecs/common/macx.conf \ 254 --replace-fail 'CONFIG += ' 'CONFIG += no_default_rpath ' \ 255 --replace-fail \ 256 'QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.13' \ 257 "QMAKE_MACOSX_DEPLOYMENT_TARGET = $MACOSX_DEPLOYMENT_TARGET" 258 '' 259 else 260 lib.optionalString libGLSupported '' 261 sed -i mkspecs/common/linux.conf \ 262 -e "/^QMAKE_INCDIR_OPENGL/ s|$|${lib.getDev libGL}/include|" \ 263 -e "/^QMAKE_LIBDIR_OPENGL/ s|$|${lib.getLib libGL}/lib|" 264 '' 265 + lib.optionalString (stdenv.hostPlatform.isx86_32 && stdenv.cc.isGNU) '' 266 sed -i mkspecs/common/gcc-base-unix.conf \ 267 -e "/^QMAKE_LFLAGS_SHLIB/ s/-shared/-shared -static-libgcc/" 268 '' 269 ); 270 271 qtPluginPrefix = "lib/qt-${qtCompatVersion}/plugins"; 272 qtQmlPrefix = "lib/qt-${qtCompatVersion}/qml"; 273 qtDocPrefix = "share/doc/qt-${qtCompatVersion}"; 274 275 setOutputFlags = false; 276 preConfigure = '' 277 export LD_LIBRARY_PATH="$PWD/lib:$PWD/plugins/platforms''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" 278 279 NIX_CFLAGS_COMPILE+=" -DNIXPKGS_QT_PLUGIN_PREFIX=\"$qtPluginPrefix\"" 280 281 # paralellize compilation of qtmake, which happens within ./configure 282 export MAKEFLAGS+=" -j$NIX_BUILD_CORES" 283 284 ./bin/syncqt.pl -version $version 285 '' 286 + lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) '' 287 # QT's configure script will refuse to use pkg-config unless these two environment variables are set 288 export PKG_CONFIG_SYSROOT_DIR=/ 289 export PKG_CONFIG_LIBDIR=${lib.getLib pkg-config}/lib 290 echo "QMAKE_LFLAGS=''${LDFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf 291 echo "QMAKE_CFLAGS=''${CFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf 292 echo "QMAKE_CXXFLAGS=''${CXXFLAGS}" >> mkspecs/devices/${qtPlatformCross stdenv.hostPlatform}/qmake.conf 293 ''; 294 295 postConfigure = '' 296 qmakeCacheInjectNixOutputs() { 297 local cache="$1/.qmake.stash" 298 echo "qmakeCacheInjectNixOutputs: $cache" 299 if ! [ -f "$cache" ]; then 300 echo >&2 "qmakeCacheInjectNixOutputs: WARNING: $cache does not exist" 301 fi 302 cat >>"$cache" <<EOF 303 NIX_OUTPUT_BIN = $bin 304 NIX_OUTPUT_DEV = $dev 305 NIX_OUTPUT_OUT = $out 306 NIX_OUTPUT_DOC = $dev/$qtDocPrefix 307 NIX_OUTPUT_QML = $bin/$qtQmlPrefix 308 NIX_OUTPUT_PLUGIN = $bin/$qtPluginPrefix 309 EOF 310 } 311 312 find . -name '.qmake.conf' | while read conf; do 313 qmakeCacheInjectNixOutputs "$(dirname $conf)" 314 done 315 ''; 316 317 env = { 318 NIX_CFLAGS_COMPILE = toString ( 319 [ 320 "-Wno-error=sign-compare" # freetype-2.5.4 changed signedness of some struct fields 321 ] 322 ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ 323 "-Wno-warn=free-nonheap-object" 324 "-Wno-free-nonheap-object" 325 "-w" 326 ] 327 ++ [ 328 ''-DNIXPKGS_QTCOMPOSE="${libX11.out}/share/X11/locale"'' 329 ''-DLIBRESOLV_SO="${stdenv.cc.libc.out}/lib/libresolv"'' 330 ''-DNIXPKGS_LIBXCURSOR="${libXcursor.out}/lib/libXcursor"'' 331 ] 332 ++ lib.optional libGLSupported ''-DNIXPKGS_MESA_GL="${libGL.out}/lib/libGL"'' 333 ++ lib.optional stdenv.hostPlatform.isLinux "-DUSE_X11" 334 ++ lib.optionals withGtk3 [ 335 ''-DNIXPKGS_QGTK3_XDG_DATA_DIRS="${gtk3}/share/gsettings-schemas/${gtk3.name}"'' 336 ''-DNIXPKGS_QGTK3_GIO_EXTRA_MODULES="${dconf.lib}/lib/gio/modules"'' 337 ] 338 ++ lib.optional decryptSslTraffic "-DQT_DECRYPT_SSL_TRAFFIC" 339 ); 340 } 341 // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) { 342 NIX_CFLAGS_COMPILE_FOR_BUILD = toString ([ 343 "-Wno-warn=free-nonheap-object" 344 "-Wno-free-nonheap-object" 345 "-w" 346 ]); 347 }; 348 349 prefixKey = "-prefix "; 350 351 # PostgreSQL autodetection fails sporadically because Qt omits the "-lpq" flag 352 # if dependency paths contain the string "pq", which can occur in the hash. 353 # To prevent these failures, we need to override PostgreSQL detection. 354 PSQL_LIBS = lib.optionalString (libpq != null) "-L${libpq}/lib -lpq"; 355 356 } 357 // lib.optionalAttrs (stdenv.buildPlatform != stdenv.hostPlatform) { 358 configurePlatforms = [ ]; 359 } 360 // { 361 # TODO Remove obsolete and useless flags once the build will be totally mastered 362 configureFlags = [ 363 "-plugindir $(out)/$(qtPluginPrefix)" 364 "-qmldir $(out)/$(qtQmlPrefix)" 365 "-docdir $(out)/$(qtDocPrefix)" 366 367 "-verbose" 368 "-confirm-license" 369 "-opensource" 370 371 "-release" 372 "-shared" 373 "-accessibility" 374 "-optimized-qmake" 375 # for separateDebugInfo 376 "-no-strip" 377 "-system-proxies" 378 "-pkg-config" 379 380 "-gui" 381 "-widgets" 382 "-opengl desktop" 383 "-icu" 384 "-L" 385 "${icu.out}/lib" 386 "-I" 387 "${icu.dev}/include" 388 "-pch" 389 ] 390 ++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ 391 "-device ${qtPlatformCross stdenv.hostPlatform}" 392 "-device-option CROSS_COMPILE=${stdenv.cc.targetPrefix}" 393 ] 394 ++ lib.optional debugSymbols "-debug" 395 ++ lib.optionals developerBuild [ 396 "-developer-build" 397 "-no-warnings-are-errors" 398 ] 399 ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [ 400 "-no-warnings-are-errors" 401 ] 402 ++ ( 403 if (!stdenv.hostPlatform.isx86_64) then 404 [ 405 "-no-sse2" 406 ] 407 else 408 [ 409 "-sse2" 410 "${lib.optionalString (!stdenv.hostPlatform.sse3Support) "-no"}-sse3" 411 "${lib.optionalString (!stdenv.hostPlatform.ssse3Support) "-no"}-ssse3" 412 "${lib.optionalString (!stdenv.hostPlatform.sse4_1Support) "-no"}-sse4.1" 413 "${lib.optionalString (!stdenv.hostPlatform.sse4_2Support) "-no"}-sse4.2" 414 "${lib.optionalString (!stdenv.hostPlatform.avxSupport) "-no"}-avx" 415 "${lib.optionalString (!stdenv.hostPlatform.avx2Support) "-no"}-avx2" 416 ] 417 ) 418 ++ [ 419 "-no-mips_dsp" 420 "-no-mips_dspr2" 421 ] 422 ++ [ 423 "-system-zlib" 424 "-L" 425 "${zlib.out}/lib" 426 "-I" 427 "${zlib.dev}/include" 428 "-system-libjpeg" 429 "-L" 430 "${libjpeg.out}/lib" 431 "-I" 432 "${libjpeg.dev}/include" 433 "-system-harfbuzz" 434 "-L" 435 "${harfbuzz.out}/lib" 436 "-I" 437 "${harfbuzz.dev}/include" 438 "-system-pcre" 439 "-openssl-linked" 440 "-L" 441 "${lib.getLib openssl}/lib" 442 "-I" 443 "${openssl.dev}/include" 444 "-system-sqlite" 445 ''-${if mysqlSupport then "plugin" else "no"}-sql-mysql'' 446 ''-${if libpq != null then "plugin" else "no"}-sql-psql'' 447 "-system-libpng" 448 449 "-make libs" 450 "-make tools" 451 ''-${lib.optionalString (!buildExamples) "no"}make examples'' 452 ''-${lib.optionalString (!buildTests) "no"}make tests'' 453 ] 454 ++ ( 455 if stdenv.hostPlatform.isDarwin then 456 [ 457 "-no-fontconfig" 458 "-no-framework" 459 "-no-rpath" 460 ] 461 else 462 [ 463 "-rpath" 464 ] 465 ++ [ 466 "-xcb" 467 "-qpa xcb" 468 "-L" 469 "${libX11.out}/lib" 470 "-I" 471 "${libX11.out}/include" 472 "-L" 473 "${libXext.out}/lib" 474 "-I" 475 "${libXext.out}/include" 476 "-L" 477 "${libXrender.out}/lib" 478 "-I" 479 "${libXrender.out}/include" 480 481 ''-${lib.optionalString (cups == null) "no-"}cups'' 482 "-dbus-linked" 483 "-glib" 484 ] 485 ++ lib.optional withGtk3 "-gtk" 486 ++ lib.optional withLibinput "-libinput" 487 ++ [ 488 "-inotify" 489 ] 490 ++ lib.optionals (cups != null) [ 491 "-L" 492 "${cups.lib}/lib" 493 "-I" 494 "${cups.dev}/include" 495 ] 496 ++ lib.optionals (mysqlSupport) [ 497 "-L" 498 "${libmysqlclient}/lib" 499 "-I" 500 "${libmysqlclient}/include" 501 ] 502 ++ lib.optional (withQttranslation && (qttranslations != null)) [ 503 # depends on x11 504 "-translationdir" 505 "${qttranslations}/translations" 506 ] 507 ); 508 509 # Move selected outputs. 510 postInstall = '' 511 moveToOutput "mkspecs" "$dev" 512 ''; 513 514 devTools = [ 515 "bin/fixqt4headers.pl" 516 "bin/moc" 517 "bin/qdbuscpp2xml" 518 "bin/qdbusxml2cpp" 519 "bin/qlalr" 520 "bin/qmake" 521 "bin/rcc" 522 "bin/syncqt.pl" 523 "bin/uic" 524 ]; 525 526 postFixup = '' 527 # Don't retain build-time dependencies like gdb. 528 sed '/QMAKE_DEFAULT_.*DIRS/ d' -i $dev/mkspecs/qconfig.pri 529 fixQtModulePaths "''${!outputDev}/mkspecs/modules" 530 fixQtBuiltinPaths "''${!outputDev}" '*.pr?' 531 532 # Move development tools to $dev 533 moveQtDevTools 534 moveToOutput bin "$dev" 535 536 # fixup .pc file (where to find 'moc' etc.) 537 sed -i "$dev/lib/pkgconfig/Qt5Core.pc" \ 538 -e "/^host_bins=/ c host_bins=$dev/bin" 539 ''; 540 541 dontStrip = debugSymbols; 542 543 setupHook = ../hooks/qtbase-setup-hook.sh; 544 545 passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; 546 547 meta = with lib; { 548 homepage = "https://www.qt.io/"; 549 description = "Cross-platform application framework for C++"; 550 license = with licenses; [ 551 fdl13Plus 552 gpl2Plus 553 lgpl21Plus 554 lgpl3Plus 555 ]; 556 maintainers = with maintainers; [ 557 qknight 558 ttuegel 559 periklis 560 bkchr 561 ]; 562 pkgConfigModules = [ 563 "Qt5Concurrent" 564 "Qt5Core" 565 "Qt5DBus" 566 "Qt5Gui" 567 "Qt5Network" 568 "Qt5OpenGL" 569 "Qt5OpenGLExtensions" 570 "Qt5PrintSupport" 571 #"Qt5Qml" 572 #"Qt5QmlModels" 573 #"Qt5Quick" 574 #"Qt5QuickTest" 575 #"Qt5QuickWidgets" 576 "Qt5Sql" 577 "Qt5Test" 578 "Qt5Widgets" 579 "Qt5Xml" 580 ]; 581 platforms = platforms.unix; 582 }; 583 584 } 585 ) 586)