sys-process/glances: 3.1.4.1-r1 amd64 stable, bug #720368
[gentoo.git] / eclass / qt5-build.eclass
1 # Copyright 1999-2020 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: qt5-build.eclass
5 # @MAINTAINER:
6 # qt@gentoo.org
7 # @AUTHOR:
8 # Davide Pesavento <pesa@gentoo.org>
9 # @SUPPORTED_EAPIS: 7
10 # @BLURB: Eclass for Qt5 split ebuilds.
11 # @DESCRIPTION:
12 # This eclass contains various functions that are used when building Qt5.
13 # Requires EAPI 7.
14
15 if [[ ${CATEGORY} != dev-qt ]]; then
16         die "qt5-build.eclass is only to be used for building Qt 5"
17 fi
18
19 case ${EAPI} in
20         7)      : ;;
21         *)      die "qt5-build.eclass: unsupported EAPI=${EAPI:-0}" ;;
22 esac
23
24 # @ECLASS-VARIABLE: QT5_MODULE
25 # @PRE_INHERIT
26 # @DESCRIPTION:
27 # The upstream name of the module this package belongs to. Used for
28 # SRC_URI and EGIT_REPO_URI. Must be set before inheriting the eclass.
29 : ${QT5_MODULE:=${PN}}
30
31 # @ECLASS-VARIABLE: QT5_TARGET_SUBDIRS
32 # @DEFAULT_UNSET
33 # @DESCRIPTION:
34 # Array variable containing the source directories that should be built.
35 # All paths must be relative to ${S}.
36
37 # @ECLASS-VARIABLE: QT5_GENTOO_CONFIG
38 # @DEFAULT_UNSET
39 # @DESCRIPTION:
40 # Array of <useflag:feature:macro> triplets that are evaluated in src_install
41 # to generate the per-package list of enabled QT_CONFIG features and macro
42 # definitions, which are then merged together with all other Qt5 packages
43 # installed on the system to obtain the global qconfig.{h,pri} files.
44
45 # @ECLASS-VARIABLE: QT5_GENTOO_PRIVATE_CONFIG
46 # @DEFAULT_UNSET
47 # @DESCRIPTION:
48 # Array of <useflag:feature> pairs that are evaluated in src_install
49 # to generate the per-package list of enabled QT.global_private features,
50 # which are then merged together with all other Qt5 packages installed on the
51 # system to obtain the global qmodule.pri file.
52
53 # @ECLASS-VARIABLE: VIRTUALX_REQUIRED
54 # @DESCRIPTION:
55 # For proper description see virtualx.eclass man page.
56 # Here we redefine default value to be manual, if your package needs virtualx
57 # for tests you should proceed with setting VIRTUALX_REQUIRED=test.
58 : ${VIRTUALX_REQUIRED:=manual}
59
60 inherit estack flag-o-matic toolchain-funcs virtualx
61
62 HOMEPAGE="https://www.qt.io/"
63 LICENSE="|| ( GPL-2 GPL-3 LGPL-3 ) FDL-1.3"
64 SLOT=5/$(ver_cut 1-2)
65
66 QT5_MINOR_VERSION=$(ver_cut 2)
67 readonly QT5_MINOR_VERSION
68
69 case ${PV} in
70         5.9999)
71                 # git dev branch
72                 QT5_BUILD_TYPE="live"
73                 EGIT_BRANCH="dev"
74                 ;;
75         5.?.9999|5.??.9999|5.???.9999)
76                 # git stable branch
77                 QT5_BUILD_TYPE="live"
78                 EGIT_BRANCH=${PV%.9999}
79                 ;;
80         *_alpha*|*_beta*|*_rc*)
81                 # development release
82                 QT5_BUILD_TYPE="release"
83                 MY_P=${QT5_MODULE}-everywhere-src-${PV/_/-}
84                 SRC_URI="https://download.qt.io/development_releases/qt/${PV%.*}/${PV/_/-}/submodules/${MY_P}.tar.xz"
85                 S=${WORKDIR}/${MY_P}
86                 ;;
87         *)
88                 # official stable release
89                 QT5_BUILD_TYPE="release"
90                 MY_P=${QT5_MODULE}-everywhere-src-${PV}
91                 SRC_URI="https://download.qt.io/official_releases/qt/${PV%.*}/${PV}/submodules/${MY_P}.tar.xz"
92                 S=${WORKDIR}/${MY_P}
93                 ;;
94 esac
95 readonly QT5_BUILD_TYPE
96
97 EGIT_REPO_URI=(
98         "https://code.qt.io/qt/${QT5_MODULE}.git"
99         "https://github.com/qt/${QT5_MODULE}.git"
100 )
101 [[ ${QT5_BUILD_TYPE} == live ]] && inherit git-r3
102
103 # @ECLASS-VARIABLE: QT5_BUILD_DIR
104 # @OUTPUT_VARIABLE
105 # @DESCRIPTION:
106 # Build directory for out-of-source builds.
107 : ${QT5_BUILD_DIR:=${S}_build}
108
109 IUSE="debug test"
110
111 [[ ${QT5_BUILD_TYPE} == release ]] && RESTRICT+=" test" # bug 457182
112
113 BDEPEND="
114         dev-lang/perl
115         virtual/pkgconfig
116 "
117 if [[ ${PN} != qttest ]]; then
118         DEPEND+=" test? ( ~dev-qt/qttest-${PV} )"
119 fi
120 RDEPEND="
121         dev-qt/qtchooser
122 "
123
124
125 ######  Phase functions  ######
126
127 EXPORT_FUNCTIONS src_unpack src_prepare src_configure src_compile src_install src_test pkg_postinst pkg_postrm
128
129 # @FUNCTION: qt5-build_src_unpack
130 # @DESCRIPTION:
131 # Unpacks the sources.
132 qt5-build_src_unpack() {
133         # bug 307861
134         if [[ ${PN} == qtwebengine ]]; then
135                 eshopts_push -s extglob
136                 if is-flagq '-g?(gdb)?([1-9])'; then
137                         ewarn
138                         ewarn "You have enabled debug info (probably have -g or -ggdb in your CFLAGS/CXXFLAGS)."
139                         ewarn "You may experience really long compilation times and/or increased memory usage."
140                         ewarn "If compilation fails, please try removing -g/-ggdb before reporting a bug."
141                         ewarn
142                 fi
143                 eshopts_pop
144         fi
145
146         case ${QT5_BUILD_TYPE} in
147                 live)    git-r3_src_unpack ;&
148                 release) default ;;
149         esac
150 }
151
152 # @FUNCTION: qt5-build_src_prepare
153 # @DESCRIPTION:
154 # Prepares the environment and patches the sources if necessary.
155 qt5-build_src_prepare() {
156         qt5_prepare_env
157
158         if [[ ${QT5_MODULE} == qtbase ]]; then
159                 qt5_symlink_tools_to_build_dir
160
161                 # Avoid unnecessary qmake recompilations
162                 sed -i -e "/Creating qmake/i if [ '!' -e \"\$outpath/bin/qmake\" ]; then" \
163                         -e '/echo "Done."/a fi' configure || die "sed failed (skip qmake bootstrap)"
164
165                 # Respect CC, CXX, *FLAGS, MAKEOPTS and EXTRA_EMAKE when bootstrapping qmake
166                 sed -i -e "/outpath\/qmake\".*\"\$MAKE\")/ s|)| \
167                         ${MAKEOPTS} ${EXTRA_EMAKE} 'CC=$(tc-getCC)' 'CXX=$(tc-getCXX)' \
168                         'QMAKE_CFLAGS=${CFLAGS}' 'QMAKE_CXXFLAGS=${CXXFLAGS}' 'QMAKE_LFLAGS=${LDFLAGS}'&|" \
169                         -e 's/\(setBootstrapVariable\s\+\|EXTRA_C\(XX\)\?FLAGS=.*\)QMAKE_C\(XX\)\?FLAGS_\(DEBUG\|RELEASE\).*/:/' \
170                         configure || die "sed failed (respect env for qmake build)"
171                 sed -i -e '/^CPPFLAGS\s*=/ s/-g //' \
172                         qmake/Makefile.unix || die "sed failed (CPPFLAGS for qmake build)"
173
174                 # Respect CXX in bsymbolic_functions, fvisibility, precomp, and a few other tests
175                 sed -i -e "/^QMAKE_CONF_COMPILER=/ s:=.*:=\"$(tc-getCXX)\":" \
176                         configure || die "sed failed (QMAKE_CONF_COMPILER)"
177
178                 # Respect build variables in configure tests (bug #639494)
179                 sed -i -e "s|\"\$outpath/bin/qmake\" \"\$relpathMangled\" -- \"\$@\"|& $(qt5_qmake_args) |" configure || die
180         fi
181
182         default
183 }
184
185 # @FUNCTION: qt5-build_src_configure
186 # @DESCRIPTION:
187 # Runs qmake in the target directories. For packages
188 # in qtbase, ./configure is also run before qmake.
189 qt5-build_src_configure() {
190         if [[ ${QT5_MODULE} == qtbase ]]; then
191                 qt5_base_configure
192         fi
193         if [[ ${QT5_MINOR_VERSION} -ge 15 ]] && [[ ${QT5_MODULE} == qttools ]] && [[ -z ${QT5_TARGET_SUBDIRS[@]} ]]; then
194                 qt5_tools_configure
195         fi
196
197         qt5_foreach_target_subdir qt5_qmake
198 }
199
200 # @FUNCTION: qt5-build_src_compile
201 # @DESCRIPTION:
202 # Runs emake in the target directories.
203 qt5-build_src_compile() {
204         qt5_foreach_target_subdir emake
205 }
206
207 # @FUNCTION: qt5-build_src_test
208 # @DESCRIPTION:
209 # Runs tests in the target directories.
210 qt5-build_src_test() {
211         # disable broken cmake tests (bug 474004)
212         local myqmakeargs=("${myqmakeargs[@]}" -after SUBDIRS-=cmake SUBDIRS-=installed_cmake)
213
214         qt5_foreach_target_subdir qt5_qmake
215         qt5_foreach_target_subdir emake
216
217         # create a custom testrunner script that correctly sets
218         # LD_LIBRARY_PATH before executing the given test
219         local testrunner=${QT5_BUILD_DIR}/gentoo-testrunner
220         cat > "${testrunner}" <<-_EOF_ || die
221         #!/bin/sh
222         export LD_LIBRARY_PATH="${QT5_BUILD_DIR}/lib:${QT5_LIBDIR}"
223         "\$@"
224         _EOF_
225         chmod +x "${testrunner}"
226
227         set -- qt5_foreach_target_subdir emake TESTRUNNER="'${testrunner}'" check
228         if [[ ${VIRTUALX_REQUIRED} == test ]]; then
229                 virtx "$@"
230         else
231                 "$@"
232         fi
233 }
234
235 # @FUNCTION: qt5-build_src_install
236 # @DESCRIPTION:
237 # Runs emake install in the target directories.
238 qt5-build_src_install() {
239         qt5_foreach_target_subdir emake INSTALL_ROOT="${D}" install
240
241         if [[ ${PN} == qtcore ]]; then
242                 pushd "${QT5_BUILD_DIR}" >/dev/null || die
243
244                 set -- emake INSTALL_ROOT="${D}" \
245                         sub-qmake-qmake-aux-pro-install_subtargets \
246                         install_{syncqt,mkspecs}
247
248                 einfo "Running $*"
249                 "$@"
250
251                 popd >/dev/null || die
252
253                 # install an empty Gentoo/gentoo-qconfig.h in ${D}
254                 # so that it's placed under package manager control
255                 > "${T}"/gentoo-qconfig.h
256                 (
257                         insinto "${QT5_HEADERDIR#${EPREFIX}}"/Gentoo
258                         doins "${T}"/gentoo-qconfig.h
259                 )
260
261                 # include gentoo-qconfig.h at the beginning of QtCore/qconfig.h
262                 sed -i -e '1i #include <Gentoo/gentoo-qconfig.h>\n' \
263                         "${D}${QT5_HEADERDIR}"/QtCore/qconfig.h \
264                         || die "sed failed (qconfig.h)"
265
266                 # install qtchooser configuration file
267                 cat > "${T}/qt5-${CHOST}.conf" <<-_EOF_ || die
268                         ${QT5_BINDIR}
269                         ${QT5_LIBDIR}
270                 _EOF_
271
272                 (
273                         insinto /etc/xdg/qtchooser
274                         doins "${T}/qt5-${CHOST}.conf"
275                 )
276
277                 # convenience symlinks
278                 dosym qt5-"${CHOST}".conf /etc/xdg/qtchooser/5.conf
279                 dosym qt5-"${CHOST}".conf /etc/xdg/qtchooser/qt5.conf
280                 # TODO bug 522646: write an eselect module to manage default.conf
281                 dosym qt5.conf /etc/xdg/qtchooser/default.conf
282         fi
283
284         qt5_install_module_config
285
286         # prune libtool files
287         find "${D}" -name '*.la' -type f -delete || die
288 }
289
290 # @FUNCTION: qt5-build_pkg_postinst
291 # @DESCRIPTION:
292 # Regenerate configuration after installation or upgrade/downgrade.
293 qt5-build_pkg_postinst() {
294         qt5_regenerate_global_configs
295 }
296
297 # @FUNCTION: qt5-build_pkg_postrm
298 # @DESCRIPTION:
299 # Regenerate configuration when a module is completely removed.
300 qt5-build_pkg_postrm() {
301         if [[ -z ${REPLACED_BY_VERSION} && ${PN} != qtcore ]]; then
302                 qt5_regenerate_global_configs
303         fi
304 }
305
306
307 ######  Public helpers  ######
308
309 # @FUNCTION: qt_use
310 # @USAGE: <flag> [feature] [enableval]
311 # @DESCRIPTION:
312 # <flag> is the name of a flag in IUSE.
313 #
314 # Outputs "-${enableval}-${feature}" if <flag> is enabled, "-no-${feature}"
315 # otherwise. If [feature] is not specified, <flag> is used in its place.
316 # If [enableval] is not specified, the "-${enableval}" prefix is omitted.
317 qt_use() {
318         [[ $# -ge 1 ]] || die "${FUNCNAME}() requires at least one argument"
319
320         usex "$1" "${3:+-$3}-${2:-$1}" "-no-${2:-$1}"
321 }
322
323 # @FUNCTION: qt_use_compile_test
324 # @USAGE: <flag> [config]
325 # @DESCRIPTION:
326 # <flag> is the name of a flag in IUSE.
327 # [config] is the argument of qtCompileTest, defaults to <flag>.
328 #
329 # This function is useful to disable optional dependencies that are checked
330 # at qmake-time using the qtCompileTest() function. If <flag> is disabled,
331 # the compile test is skipped and the dependency is assumed to be unavailable,
332 # i.e. the corresponding feature will be disabled. Note that all invocations
333 # of this function must happen before calling qt5-build_src_configure.
334 qt_use_compile_test() {
335         [[ $# -ge 1 ]] || die "${FUNCNAME}() requires at least one argument"
336
337         if ! use "$1"; then
338                 mkdir -p "${QT5_BUILD_DIR}" || die
339                 echo "CONFIG += done_config_${2:-$1}" >> "${QT5_BUILD_DIR}"/.qmake.cache || die
340         fi
341 }
342
343 # @FUNCTION: qt_use_disable_config
344 # @USAGE: <flag> <config> <files...>
345 # @DESCRIPTION:
346 # <flag> is the name of a flag in IUSE.
347 # <config> is the (lowercase) name of a Qt5 config entry.
348 # <files...> is a list of one or more qmake project files.
349 #
350 # This function patches <files> to treat <config> as disabled
351 # when <flag> is disabled, otherwise it does nothing.
352 # This can be useful to avoid an automagic dependency when the config entry
353 # is enabled on the system but the corresponding USE flag is disabled.
354 qt_use_disable_config() {
355         [[ $# -ge 3 ]] || die "${FUNCNAME}() requires at least three arguments"
356
357         local flag=$1
358         local config=$2
359         shift 2
360
361         if ! use "${flag}"; then
362                 echo "$@" | xargs sed -i -e "s/qtConfig(${config})/false/g" || die
363         fi
364 }
365
366 # @FUNCTION: qt_use_disable_mod
367 # @USAGE: <flag> <module> <files...>
368 # @DESCRIPTION:
369 # <flag> is the name of a flag in IUSE.
370 # <module> is the (lowercase) name of a Qt5 module.
371 # <files...> is a list of one or more qmake project files.
372 #
373 # This function patches <files> to treat <module> as not installed
374 # when <flag> is disabled, otherwise it does nothing.
375 # This can be useful to avoid an automagic dependency when the module
376 # is present on the system but the corresponding USE flag is disabled.
377 qt_use_disable_mod() {
378         [[ $# -ge 3 ]] || die "${FUNCNAME}() requires at least three arguments"
379
380         local flag=$1
381         local module=$2
382         shift 2
383
384         if ! use "${flag}"; then
385                 echo "$@" | xargs sed -i -e "s/qtHaveModule(${module})/false/g" || die
386         fi
387 }
388
389
390 ######  Internal functions  ######
391
392 # @FUNCTION: qt5_prepare_env
393 # @INTERNAL
394 # @DESCRIPTION:
395 # Prepares the environment for building Qt.
396 qt5_prepare_env() {
397         # setup installation directories
398         # note: keep paths in sync with qmake-utils.eclass
399         QT5_PREFIX=${EPREFIX}/usr
400         QT5_HEADERDIR=${QT5_PREFIX}/include/qt5
401         QT5_LIBDIR=${QT5_PREFIX}/$(get_libdir)
402         QT5_ARCHDATADIR=${QT5_PREFIX}/$(get_libdir)/qt5
403         QT5_BINDIR=${QT5_ARCHDATADIR}/bin
404         QT5_PLUGINDIR=${QT5_ARCHDATADIR}/plugins
405         QT5_LIBEXECDIR=${QT5_ARCHDATADIR}/libexec
406         QT5_IMPORTDIR=${QT5_ARCHDATADIR}/imports
407         QT5_QMLDIR=${QT5_ARCHDATADIR}/qml
408         QT5_DATADIR=${QT5_PREFIX}/share/qt5
409         QT5_DOCDIR=${QT5_PREFIX}/share/qt5-doc
410         QT5_TRANSLATIONDIR=${QT5_DATADIR}/translations
411         QT5_EXAMPLESDIR=${QT5_DATADIR}/examples
412         QT5_TESTSDIR=${QT5_DATADIR}/tests
413         QT5_SYSCONFDIR=${EPREFIX}/etc/xdg
414         readonly QT5_PREFIX QT5_HEADERDIR QT5_LIBDIR QT5_ARCHDATADIR \
415                 QT5_BINDIR QT5_PLUGINDIR QT5_LIBEXECDIR QT5_IMPORTDIR \
416                 QT5_QMLDIR QT5_DATADIR QT5_DOCDIR QT5_TRANSLATIONDIR \
417                 QT5_EXAMPLESDIR QT5_TESTSDIR QT5_SYSCONFDIR
418
419         if [[ ${QT5_MODULE} == qtbase ]]; then
420                 # see mkspecs/features/qt_config.prf
421                 export QMAKEMODULES="${QT5_BUILD_DIR}/mkspecs/modules:${S}/mkspecs/modules:${QT5_ARCHDATADIR}/mkspecs/modules"
422         fi
423 }
424
425 # @FUNCTION: qt5_foreach_target_subdir
426 # @INTERNAL
427 # @DESCRIPTION:
428 # Executes the command given as argument from inside each directory
429 # listed in QT5_TARGET_SUBDIRS. Handles autotests subdirs automatically.
430 qt5_foreach_target_subdir() {
431         [[ -z ${QT5_TARGET_SUBDIRS[@]} ]] && QT5_TARGET_SUBDIRS=("")
432
433         local subdir=
434         for subdir in "${QT5_TARGET_SUBDIRS[@]}"; do
435                 if [[ ${EBUILD_PHASE} == test ]]; then
436                         subdir=tests/auto${subdir#src}
437                         [[ -d ${S}/${subdir} ]] || continue
438                 fi
439
440                 local msg="Running $* ${subdir:+in ${subdir}}"
441                 einfo "${msg}"
442
443                 mkdir -p "${QT5_BUILD_DIR}/${subdir}" || die -n || return $?
444                 pushd "${QT5_BUILD_DIR}/${subdir}" >/dev/null || die -n || return $?
445
446                 "$@" || die -n "${msg} failed" || return $?
447
448                 popd >/dev/null || die -n || return $?
449         done
450 }
451
452 # @FUNCTION: qt5_symlink_tools_to_build_dir
453 # @INTERNAL
454 # @DESCRIPTION:
455 # Symlinks qmake and a few other tools to QT5_BUILD_DIR,
456 # so that they can be used when building other modules.
457 qt5_symlink_tools_to_build_dir() {
458         local tool= tools=()
459         if [[ ${PN} != qtcore ]]; then
460                 tools+=(qmake moc rcc qlalr)
461                 [[ ${PN} != qtdbus ]] && tools+=(qdbuscpp2xml qdbusxml2cpp)
462                 [[ ${PN} != qtwidgets ]] && tools+=(uic)
463         fi
464
465         mkdir -p "${QT5_BUILD_DIR}"/bin || die
466         pushd "${QT5_BUILD_DIR}"/bin >/dev/null || die
467
468         for tool in "${tools[@]}"; do
469                 [[ -e ${QT5_BINDIR}/${tool} ]] || continue
470                 ln -s "${QT5_BINDIR}/${tool}" . || die "failed to symlink ${tool}"
471         done
472
473         popd >/dev/null || die
474 }
475
476 # @FUNCTION: qt5_base_configure
477 # @INTERNAL
478 # @DESCRIPTION:
479 # Runs ./configure for modules belonging to qtbase.
480 qt5_base_configure() {
481         # setup toolchain variables used by configure
482         tc-export AR CC CXX OBJDUMP RANLIB STRIP
483         export LD="$(tc-getCXX)"
484
485         # bug 633838
486         unset QMAKESPEC XQMAKESPEC QMAKEPATH QMAKEFEATURES
487
488         # configure arguments
489         local conf=(
490                 # installation paths
491                 -prefix "${QT5_PREFIX}"
492                 -bindir "${QT5_BINDIR}"
493                 -headerdir "${QT5_HEADERDIR}"
494                 -libdir "${QT5_LIBDIR}"
495                 -archdatadir "${QT5_ARCHDATADIR}"
496                 -plugindir "${QT5_PLUGINDIR}"
497                 -libexecdir "${QT5_LIBEXECDIR}"
498                 -importdir "${QT5_IMPORTDIR}"
499                 -qmldir "${QT5_QMLDIR}"
500                 -datadir "${QT5_DATADIR}"
501                 -docdir "${QT5_DOCDIR}"
502                 -translationdir "${QT5_TRANSLATIONDIR}"
503                 -sysconfdir "${QT5_SYSCONFDIR}"
504                 -examplesdir "${QT5_EXAMPLESDIR}"
505                 -testsdir "${QT5_TESTSDIR}"
506
507                 # force appropriate compiler
508                 $(if use kernel_FreeBSD; then
509                         if tc-is-gcc; then
510                                 echo -platform freebsd-g++
511                         elif tc-is-clang; then
512                                 echo -platform freebsd-clang
513                         fi
514                 fi)
515                 $(if use kernel_linux; then
516                         if tc-is-gcc; then
517                                 echo -platform linux-g++
518                         elif tc-is-clang; then
519                                 echo -platform linux-clang
520                         fi
521                 fi)
522
523                 # configure in release mode by default,
524                 # override via the CONFIG qmake variable
525                 -release
526                 -no-separate-debug-info
527
528                 # no need to forcefully build host tools in optimized mode,
529                 # just follow the overall debug/release build type
530                 -no-optimized-tools
531
532                 # licensing stuff
533                 -opensource -confirm-license
534
535                 # autodetect the highest supported version of the C++ standard
536                 #-c++std <c++11|c++14|c++1z>
537
538                 # build shared libraries
539                 -shared
540
541                 # disabling accessibility is not recommended by upstream, as
542                 # it will break QStyle and may break other internal parts of Qt
543                 -accessibility
544
545                 # disable all SQL drivers by default, override in qtsql
546                 -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc
547                 -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 -no-sql-tds
548
549                 # MIPS DSP instruction set extensions
550                 $(is-flagq -mno-dsp   && echo -no-mips_dsp)
551                 $(is-flagq -mno-dspr2 && echo -no-mips_dspr2)
552
553                 # use pkg-config to detect include and library paths
554                 -pkg-config
555
556                 # prefer system libraries (only common hard deps here)
557                 -system-zlib
558                 -system-pcre
559                 -system-doubleconversion
560
561                 # disable everything to prevent automagic deps (part 1)
562                 -no-mtdev
563                 -no-journald -no-syslog
564                 -no-libpng -no-libjpeg
565                 -no-freetype -no-harfbuzz
566                 -no-openssl -no-libproxy
567                 -no-feature-gssapi
568                 -no-xcb-xlib
569
570                 # bug 672340
571                 -no-xkbcommon
572                 $([[ ${QT5_MINOR_VERSION} -lt 15 ]] && echo -no-xcb-xinput)
573                 $([[ ${QT5_MINOR_VERSION} -ge 15 ]] && echo -no-bundled-xcb-xinput)
574
575                 # cannot use -no-gif because there is no way to override it later
576                 #-no-gif
577
578                 # always enable glib event loop support
579                 -glib
580
581                 # disable everything to prevent automagic deps (part 2)
582                 -no-gtk
583
584                 # exclude examples and tests from default build
585                 -nomake examples
586                 -nomake tests
587                 -no-compile-examples
588
589                 # disable rpath on non-prefix (bugs 380415 and 417169)
590                 $(usex prefix '' -no-rpath)
591
592                 # print verbose information about each configure test
593                 -verbose
594
595                 # disable everything to prevent automagic deps (part 3)
596                 -no-cups -no-evdev -no-tslib -no-icu -no-fontconfig -no-dbus
597
598                 # let portage handle stripping
599                 -no-strip
600
601                 # precompiled headers can cause problems on hardened, so turn them off
602                 -no-pch
603
604                 # link-time code generation is not something we want to enable by default
605                 -no-ltcg
606
607                 # reduced relocations cause major breakage on at least arm and ppc, so
608                 # don't specify anything and let the configure figure out if they are
609                 # supported; see also https://bugreports.qt.io/browse/QTBUG-36129
610                 #-reduce-relocations
611
612                 # use the system linker (gold will be selected automagically otherwise)
613                 $(tc-ld-is-gold && echo -use-gold-linker || echo -no-use-gold-linker)
614
615                 # disable all platform plugins by default, override in qtgui
616                 -no-xcb -no-eglfs -no-kms -no-gbm -no-directfb -no-linuxfb
617
618                 # disable undocumented X11-related flags, override in qtgui
619                 # (not shown in ./configure -help output)
620                 $([[ ${QT5_MINOR_VERSION} -lt 15 ]] && echo -no-xkb)
621
622                 # always enable session management support: it doesn't need extra deps
623                 # at configure time and turning it off is dangerous, see bug 518262
624                 -sm
625
626                 # typedef qreal to double (warning: changing this flag breaks the ABI)
627                 -qreal double
628
629                 # disable OpenGL and EGL support by default, override in qtgui,
630                 # qtopengl, qtprintsupport and qtwidgets
631                 -no-opengl -no-egl
632
633                 # disable libinput-based generic plugin by default, override in qtgui
634                 -no-libinput
635
636                 # respect system proxies by default: it's the most natural
637                 # setting, and it'll become the new upstream default in 5.8
638                 -system-proxies
639
640                 # do not build with -Werror
641                 -no-warnings-are-errors
642
643                 # enable in respective modules to avoid poisoning QT.global_private.enabled_features
644                 -no-gui -no-widgets
645
646                 # QTBUG-76521, default will change to zstd in Qt6
647                 -no-zstd
648
649                 # module-specific options
650                 "${myconf[@]}"
651         )
652
653         pushd "${QT5_BUILD_DIR}" >/dev/null || die
654
655         einfo "Configuring with: ${conf[@]}"
656         "${S}"/configure "${conf[@]}" || die "configure failed"
657
658         # a forwarding header is no longer created since 5.8, causing the system
659         # config to always be used. bug 599636
660         # ${S}/include does not exist in live sources
661         local basedir="${S}/"
662         [[ ${QT5_BUILD_TYPE} == live ]] && basedir=""
663         cp src/corelib/global/qconfig.h "${basedir}"include/QtCore/ || die
664
665         popd >/dev/null || die
666
667 }
668
669 # @FUNCTION: qt5_tools_configure
670 # @INTERNAL
671 # @DESCRIPTION:
672 # Disables modules other than ${PN} belonging to qttools.
673 qt5_tools_configure() {
674         # configure arguments
675         local qmakeargs=(
676                 --
677                 # not packaged in Gentoo
678                 -no-feature-distancefieldgenerator
679                 -no-feature-kmap2qmap
680                 -no-feature-macdeployqt
681                 -no-feature-makeqpf
682                 -no-feature-qev
683                 -no-feature-qtattributionsscanner
684                 -no-feature-windeployqt
685                 -no-feature-winrtrunner
686         )
687
688         local i
689         for i in assistant designer linguist pixeltool qdbus qdoc qtdiag qtpaths qtplugininfo; do
690                 [[ ${PN} == ${i} ]] || qmakeargs+=( -no-feature-${i} )
691         done
692
693         # allow the ebuild to override what we set here
694         myqmakeargs=( "${qmakeargs[@]}" "${myqmakeargs[@]}" )
695 }
696
697 # @FUNCTION: qt5_qmake_args
698 # @INTERNAL
699 # @DESCRIPTION:
700 # Helper function to get the various toolchain-related variables.
701 qt5_qmake_args() {
702         echo \
703                 QMAKE_AR=\"$(tc-getAR)\" \
704                 QMAKE_CC=\"$(tc-getCC)\" \
705                 QMAKE_LINK_C=\"$(tc-getCC)\" \
706                 QMAKE_LINK_C_SHLIB=\"$(tc-getCC)\" \
707                 QMAKE_CXX=\"$(tc-getCXX)\" \
708                 QMAKE_LINK=\"$(tc-getCXX)\" \
709                 QMAKE_LINK_SHLIB=\"$(tc-getCXX)\" \
710                 QMAKE_OBJCOPY=\"$(tc-getOBJCOPY)\" \
711                 QMAKE_RANLIB= \
712                 QMAKE_STRIP=\"$(tc-getSTRIP)\" \
713                 QMAKE_CFLAGS=\"${CFLAGS}\" \
714                 QMAKE_CFLAGS_RELEASE= \
715                 QMAKE_CFLAGS_DEBUG= \
716                 QMAKE_CXXFLAGS=\"${CXXFLAGS}\" \
717                 QMAKE_CXXFLAGS_RELEASE= \
718                 QMAKE_CXXFLAGS_DEBUG= \
719                 QMAKE_LFLAGS=\"${LDFLAGS}\" \
720                 QMAKE_LFLAGS_RELEASE= \
721                 QMAKE_LFLAGS_DEBUG=
722 }
723
724 # @FUNCTION: qt5_qmake
725 # @INTERNAL
726 # @DESCRIPTION:
727 # Helper function that runs qmake in the current target subdir.
728 # Intended to be called by qt5_foreach_target_subdir().
729 qt5_qmake() {
730         local projectdir=${PWD/#${QT5_BUILD_DIR}/${S}}
731         local qmakepath=
732         if [[ ${QT5_MODULE} == qtbase ]]; then
733                 qmakepath=${QT5_BUILD_DIR}/bin
734         else
735                 qmakepath=${QT5_BINDIR}
736         fi
737
738         "${qmakepath}"/qmake \
739                 "${projectdir}" \
740                 CONFIG+=$(usex debug debug release) \
741                 CONFIG-=$(usex debug release debug) \
742                 QMAKE_AR="$(tc-getAR) cqs" \
743                 QMAKE_CC="$(tc-getCC)" \
744                 QMAKE_LINK_C="$(tc-getCC)" \
745                 QMAKE_LINK_C_SHLIB="$(tc-getCC)" \
746                 QMAKE_CXX="$(tc-getCXX)" \
747                 QMAKE_LINK="$(tc-getCXX)" \
748                 QMAKE_LINK_SHLIB="$(tc-getCXX)" \
749                 QMAKE_OBJCOPY="$(tc-getOBJCOPY)" \
750                 QMAKE_RANLIB= \
751                 QMAKE_STRIP="$(tc-getSTRIP)" \
752                 QMAKE_CFLAGS="${CFLAGS}" \
753                 QMAKE_CFLAGS_RELEASE= \
754                 QMAKE_CFLAGS_DEBUG= \
755                 QMAKE_CXXFLAGS="${CXXFLAGS}" \
756                 QMAKE_CXXFLAGS_RELEASE= \
757                 QMAKE_CXXFLAGS_DEBUG= \
758                 QMAKE_LFLAGS="${LDFLAGS}" \
759                 QMAKE_LFLAGS_RELEASE= \
760                 QMAKE_LFLAGS_DEBUG= \
761                 "${myqmakeargs[@]}" \
762                 || die "qmake failed (${projectdir#${S}/})"
763 }
764
765 # @FUNCTION: qt5_install_module_config
766 # @INTERNAL
767 # @DESCRIPTION:
768 # Creates and installs gentoo-specific ${PN}-qconfig.{h,pri} and
769 # ${PN}-qmodule.pri files.
770 qt5_install_module_config() {
771         local x qconfig_add= qconfig_remove= qprivateconfig_add= qprivateconfig_remove=
772
773         > "${T}"/${PN}-qconfig.h
774         > "${T}"/${PN}-qconfig.pri
775         > "${T}"/${PN}-qmodule.pri
776
777         # generate qconfig_{add,remove} and ${PN}-qconfig.h
778         for x in "${QT5_GENTOO_CONFIG[@]}"; do
779                 local flag=${x%%:*}
780                 x=${x#${flag}:}
781                 local feature=${x%%:*}
782                 x=${x#${feature}:}
783                 local macro=${x}
784                 macro=$(tr 'a-z-' 'A-Z_' <<< "${macro}")
785
786                 if [[ -z ${flag} ]] || { [[ ${flag} != '!' ]] && use ${flag}; }; then
787                         [[ -n ${feature} ]] && qconfig_add+=" ${feature}"
788                         [[ -n ${macro} ]] && echo "#define QT_${macro}" >> "${T}"/${PN}-qconfig.h
789                 else
790                         [[ -n ${feature} ]] && qconfig_remove+=" ${feature}"
791                         [[ -n ${macro} ]] && echo "#define QT_NO_${macro}" >> "${T}"/${PN}-qconfig.h
792                 fi
793         done
794
795         # install ${PN}-qconfig.h
796         [[ -s ${T}/${PN}-qconfig.h ]] && (
797                 insinto "${QT5_HEADERDIR#${EPREFIX}}"/Gentoo
798                 doins "${T}"/${PN}-qconfig.h
799         )
800
801         # generate and install ${PN}-qconfig.pri
802         [[ -n ${qconfig_add} ]] && echo "QCONFIG_ADD=${qconfig_add}" >> "${T}"/${PN}-qconfig.pri
803         [[ -n ${qconfig_remove} ]] && echo "QCONFIG_REMOVE=${qconfig_remove}" >> "${T}"/${PN}-qconfig.pri
804         [[ -s ${T}/${PN}-qconfig.pri ]] && (
805                 insinto "${QT5_ARCHDATADIR#${EPREFIX}}"/mkspecs/gentoo
806                 doins "${T}"/${PN}-qconfig.pri
807         )
808
809         # generate qprivateconfig
810         for x in "${QT5_GENTOO_PRIVATE_CONFIG[@]}"; do
811                 local flag=${x%%:*}
812                 x=${x#${flag}:}
813                 local feature=${x%%:*}
814                 x=${x#${feature}:}
815
816                 if [[ -z ${flag} ]] || { [[ ${flag} != '!' ]] && use ${flag}; }; then
817                         [[ -n ${feature} ]] && qprivateconfig_add+=" ${feature}"
818                 else
819                         [[ -n ${feature} ]] && qprivateconfig_remove+=" ${feature}"
820                 fi
821         done
822
823         # generate and install ${PN}-qmodule.pri
824         [[ -n ${qprivateconfig_add} ]] && echo "QT.global_private.enabled_features = ${qprivateconfig_add}" >> "${T}"/${PN}-qmodule.pri
825         [[ -n ${qprivateconfig_remove} ]] && echo "QT.global_private.disabled_features = ${qprivateconfig_remove}" >> "${T}"/${PN}-qmodule.pri
826         [[ -s ${T}/${PN}-qmodule.pri ]] && (
827                 insinto "${QT5_ARCHDATADIR#${EPREFIX}}"/mkspecs/gentoo
828                 doins "${T}"/${PN}-qmodule.pri
829         )
830
831         # install the original {qconfig,qmodule}.pri from qtcore
832         [[ ${PN} == qtcore ]] && (
833                 insinto "${QT5_ARCHDATADIR#${EPREFIX}}"/mkspecs/gentoo
834                 newins "${D}${QT5_ARCHDATADIR}"/mkspecs/qconfig.pri qconfig-qtcore.pri
835                 newins "${D}${QT5_ARCHDATADIR}"/mkspecs/qmodule.pri qmodule-qtcore.pri
836         )
837 }
838
839 # @FUNCTION: qt5_regenerate_global_configs
840 # @INTERNAL
841 # @DESCRIPTION:
842 # Generates Gentoo-specific qconfig.{h,pri} and qmodule.pri according to the
843 # build configuration.
844 # Don't call die here because dying in pkg_post{inst,rm} only makes things worse.
845 qt5_regenerate_global_configs() {
846         einfo "Regenerating gentoo-qconfig.h"
847
848         find "${ROOT}${QT5_HEADERDIR}"/Gentoo \
849                 -name '*-qconfig.h' -a \! -name 'gentoo-qconfig.h' -type f \
850                 -execdir cat '{}' + | sort -u > "${T}"/gentoo-qconfig.h
851
852         [[ -s ${T}/gentoo-qconfig.h ]] || ewarn "Generated gentoo-qconfig.h is empty"
853         cp "${T}"/gentoo-qconfig.h "${ROOT}${QT5_HEADERDIR}"/Gentoo/gentoo-qconfig.h \
854                 || eerror "Failed to install new gentoo-qconfig.h"
855
856         einfo "Updating QT_CONFIG in qconfig.pri"
857
858         local qconfig_pri=${ROOT}${QT5_ARCHDATADIR}/mkspecs/qconfig.pri
859         local qconfig_pri_orig=${ROOT}${QT5_ARCHDATADIR}/mkspecs/gentoo/qconfig-qtcore.pri
860         if [[ -f ${qconfig_pri} ]]; then
861                 local x qconfig_add= qconfig_remove=
862                 local qt_config new_qt_config=
863                 if [[ -f ${qconfig_pri_orig} ]]; then
864                         qt_config=$(sed -n 's/^QT_CONFIG\s*+=\s*//p' "${qconfig_pri_orig}")
865                 else
866                         qt_config=$(sed -n 's/^QT_CONFIG\s*+=\s*//p' "${qconfig_pri}")
867                 fi
868
869                 # generate list of QT_CONFIG entries from the existing list,
870                 # appending QCONFIG_ADD and excluding QCONFIG_REMOVE
871                 eshopts_push -s nullglob
872                 for x in "${ROOT}${QT5_ARCHDATADIR}"/mkspecs/gentoo/*-qconfig.pri; do
873                         qconfig_add+=" $(sed -n 's/^QCONFIG_ADD=\s*//p' "${x}")"
874                         qconfig_remove+=" $(sed -n 's/^QCONFIG_REMOVE=\s*//p' "${x}")"
875                 done
876                 eshopts_pop
877                 for x in ${qt_config} ${qconfig_add}; do
878                         if ! has "${x}" ${new_qt_config} ${qconfig_remove}; then
879                                 new_qt_config+=" ${x}"
880                         fi
881                 done
882
883                 # now replace the existing QT_CONFIG with the generated list
884                 sed -i -e "s/^QT_CONFIG\s*+=.*/QT_CONFIG +=${new_qt_config}/" \
885                         "${qconfig_pri}" || eerror "Failed to sed QT_CONFIG in ${qconfig_pri}"
886         else
887                 ewarn "${qconfig_pri} does not exist or is not a regular file"
888         fi
889
890         einfo "Updating QT.global_private in qmodule.pri"
891
892         local qmodule_pri=${ROOT}${QT5_ARCHDATADIR}/mkspecs/qmodule.pri
893         local qmodule_pri_orig=${ROOT}${QT5_ARCHDATADIR}/mkspecs/gentoo/qmodule-qtcore.pri
894         if [[ -f ${qmodule_pri} && -f ${qmodule_pri_orig} ]]; then
895                 local x
896                 local qprivateconfig_enabled= qprivateconfig_disabled=
897                 local qprivateconfig_orig_enabled= qprivateconfig_orig_disabled=
898                 local new_qprivateconfig_enabled= new_qprivateconfig_disabled=
899
900                 # generate lists of QT.global_private.{dis,en}abled_features
901                 qprivateconfig_orig_enabled="$(sed -n 's/^QT.global_private.enabled_features\s=\s*//p' "${qmodule_pri_orig}")"
902                 qprivateconfig_orig_disabled="$(sed -n 's/^QT.global_private.disabled_features\s=\s*//p' "${qmodule_pri_orig}")"
903                 eshopts_push -s nullglob
904                 for x in "${ROOT}${QT5_ARCHDATADIR}"/mkspecs/gentoo/*-qmodule.pri; do
905                         qprivateconfig_enabled+=" $(sed -n 's/^QT.global_private.enabled_features\s=\s*//p' "${x}")"
906                         qprivateconfig_disabled+=" $(sed -n 's/^QT.global_private.disabled_features\s=\s*//p' "${x}")"
907                 done
908                 eshopts_pop
909
910                 # anything enabled is enabled, but anything disabled is
911                 # only disabled if it isn't enabled somewhere else.
912                 # this is because we need to forcibly disable some stuff
913                 # in qtcore to support split qtbase.
914                 new_qprivateconfig_enabled=${qprivateconfig_enabled}
915                 for x in ${qprivateconfig_disabled}; do
916                         if ! has "${x}" ${qprivateconfig_enabled}; then
917                                 new_qprivateconfig_disabled+=" ${x}"
918                         fi
919                 done
920
921                 # check all items from the original qtcore qmodule.pri,
922                 # and add them to the appropriate list if not overridden
923                 # elsewhere
924                 for x in ${qprivateconfig_orig_enabled}; do
925                         if ! has "${x}" ${new_qprivateconfig_enabled} ${new_qprivateconfig_disabled}; then
926                                 new_qprivateconfig_enabled+=" ${x}"
927                         fi
928                 done
929                 for x in ${qprivateconfig_orig_disabled}; do
930                         if ! has "${x}" ${new_qprivateconfig_enabled} ${new_qprivateconfig_disabled}; then
931                                 new_qprivateconfig_disabled+=" ${x}"
932                         fi
933                 done
934
935                 # now replace the existing QT.global_private.{dis,en}abled_features
936                 # with the generated list
937                 sed \
938                         -e "s/^QT.global_private.enabled_features\s*=.*/QT.global_private.enabled_features =${new_qprivateconfig_enabled}/" \
939                         -e "s/^QT.global_private.disabled_features\s*=.*/QT.global_private.disabled_features =${new_qprivateconfig_disabled}/" \
940                         -i "${qmodule_pri}" || eerror "Failed to sed QT.global_private.enabled_features in ${qmodule_pri}"
941         else
942                 ewarn "${qmodule_pri} or ${qmodule_pri_orig} does not exist or is not a regular file"
943         fi
944 }