1 # Copyright 1999-2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
8 # @BLURB: Support eclass for packages that use KDE Frameworks with ECM.
10 # This eclass is intended to streamline the creation of ebuilds for packages
11 # that use cmake and KDE Frameworks' extra-cmake-modules, thereby following
12 # some of their packaging conventions. It is primarily intended for the three
13 # upstream release groups (Frameworks, Plasma, Applications) but also for any
14 # other package that follows similar conventions.
16 # This eclass unconditionally inherits cmake.eclass and all its public
17 # variables and helper functions (not phase functions) may be considered as part
18 # of this eclass's API.
20 # This eclass's phase functions are not intended to be mixed and matched, so if
21 # any phase functions are overridden the version here should also be called.
23 # Porting from kde5.class
24 # - Convert all add_*_dep dependency functions to regular dependencies
25 # - Manually set LICENSE
27 # - Rename vars and function names as needed, see kde5.eclass PORTING comments
28 # - Instead of FRAMEWORKS_MINIMAL, define KFMIN in ebuilds and use it for deps
30 if [[ -z ${_ECM_ECLASS} ]]; then
33 # @ECLASS-VARIABLE: VIRTUALX_REQUIRED
35 # For proper description see virtualx.eclass manpage.
36 # Here we redefine default value to be manual, if your package needs virtualx
37 # for tests you should proceed with setting VIRTUALX_REQUIRED=test.
38 : ${VIRTUALX_REQUIRED:=manual}
40 # @ECLASS-VARIABLE: ECM_NONGUI
43 # By default, for all CATEGORIES except kde-frameworks, assume we are building
44 # a GUI application. Add dependency on kde-frameworks/breeze-icons or
45 # kde-frameworks/oxygen-icons and run the xdg.eclass routines for pkg_preinst,
46 # pkg_postinst and pkg_postrm. If set to "true", do nothing.
47 if [[ ${CATEGORY} = kde-frameworks ]] ; then
50 : ${ECM_NONGUI:=false}
52 inherit cmake flag-o-matic toolchain-funcs virtualx
54 if [[ ${ECM_NONGUI} = false ]] ; then
60 *) die "EAPI=${EAPI:-0} is not supported" ;;
63 if [[ -v KDE_GCC_MINIMAL ]]; then
64 EXPORT_FUNCTIONS pkg_pretend
67 EXPORT_FUNCTIONS pkg_setup src_prepare src_configure src_test pkg_preinst pkg_postinst pkg_postrm
69 # @ECLASS-VARIABLE: ECM_KDEINSTALLDIRS
71 # Assume the package is using KDEInstallDirs macro and switch
72 # KDE_INSTALL_USE_QT_SYS_PATHS to ON. If set to "false", do nothing.
73 : ${ECM_KDEINSTALLDIRS:=true}
75 # @ECLASS-VARIABLE: ECM_DEBUG
77 # Add "debug" to IUSE. If !debug, add -DNDEBUG (via cmake_src_configure)
78 # and -DQT_NO_DEBUG to CPPFLAGS. If set to "false", do nothing.
81 # @ECLASS-VARIABLE: ECM_DESIGNERPLUGIN
83 # If set to "true", add "designer" to IUSE to toggle build of designer plugins
84 # and add the necessary BDEPEND. If set to "false", do nothing.
85 : ${ECM_DESIGNERPLUGIN:=false}
87 # @ECLASS-VARIABLE: ECM_EXAMPLES
89 # By default unconditionally ignore a top-level examples subdirectory.
90 # If set to "true", add "examples" to IUSE to toggle adding that subdirectory.
91 : ${ECM_EXAMPLES:=false}
93 # @ECLASS-VARIABLE: ECM_HANDBOOK
95 # Will accept "true", "false", "optional", "forceoptional". If set to "false",
97 # Otherwise, add "+handbook" to IUSE, add the appropriate dependency, and let
98 # KF5DocTools generate and install the handbook from docbook file(s) found in
99 # ECM_HANDBOOK_DIR. However if !handbook, disable build of ECM_HANDBOOK_DIR
101 # If set to "optional", build with -DCMAKE_DISABLE_FIND_PACKAGE_KF5DocTools=ON
102 # when !handbook. In case package requires KF5KDELibs4Support, see next:
103 # If set to "forceoptional", remove a KF5DocTools dependency from the root
104 # CMakeLists.txt in addition to the above.
105 : ${ECM_HANDBOOK:=false}
107 # @ECLASS-VARIABLE: ECM_HANDBOOK_DIR
109 # Specifies the directory containing the docbook file(s) relative to ${S} to
110 # be processed by KF5DocTools (kdoctools_install).
111 : ${ECM_HANDBOOK_DIR:=doc}
113 # @ECLASS-VARIABLE: ECM_PO_DIRS
115 # Specifies directories of l10n files relative to ${S} to be processed by
116 # KF5I18n (ki18n_install). If IUSE nls exists and is disabled then disable
117 # build of these directories in CMakeLists.txt.
118 : ${ECM_PO_DIRS:="po poqm"}
120 # @ECLASS-VARIABLE: ECM_QTHELP
123 # Default value for all CATEGORIES except kde-frameworks is "false".
124 # If set to "true", add "doc" to IUSE, add the appropriate dependency, let
125 # -DBUILD_QCH=ON generate and install Qt compressed help files when USE=doc.
126 # If set to "false", do nothing.
127 if [[ ${CATEGORY} = kde-frameworks ]]; then
128 : ${ECM_QTHELP:=true}
130 : ${ECM_QTHELP:=false}
132 # @ECLASS-VARIABLE: ECM_TEST
135 # Will accept "true", "false", "optional", "forceoptional",
136 # "forceoptional-recursive".
137 # Default value is "false", except for CATEGORY=kde-frameworks where it is
138 # set to "true". If set to "false", do nothing.
139 # For any other value, add "test" to IUSE and DEPEND on dev-qt/qttest:5.
140 # If set to "optional", build with -DCMAKE_DISABLE_FIND_PACKAGE_Qt5Test=ON
142 # If set to "forceoptional", punt Qt5Test dependency and ignore "autotests",
143 # "test", "tests" subdirs from top-level CMakeLists.txt when USE=!test.
144 # If set to "forceoptional-recursive", punt Qt5Test dependencies and make
145 # autotest(s), unittest(s) and test(s) subdirs from *any* CMakeLists.txt in
146 # ${S} and below conditional on BUILD_TESTING when USE=!test. This is always
147 # meant as a short-term fix and creates ${T}/${P}-tests-optional.patch to
148 # refine and submit upstream.
149 if [[ ${CATEGORY} = kde-frameworks ]]; then
154 # @ECLASS-VARIABLE: KFMIN
157 # Minimum version of Frameworks to require. Default value for kde-frameworks
158 # is ${PV} and 5.64.0 baseline for everything else. This is not going to be
159 # changed unless we also bump EAPI, which usually implies (rev-)bumping.
160 # Version will later be used to differentiate between KF5/Qt5 and KF6/Qt6.
161 if [[ ${CATEGORY} = kde-frameworks ]]; then
162 : ${KFMIN:=$(ver_cut 1-2)}
166 # @ECLASS-VARIABLE: KFSLOT
169 # KDE Frameworks and Qt slot dependency, implied by KFMIN version.
172 case ${ECM_NONGUI} in
175 # gui applications need breeze or oxygen for basic iconset, bug #564838
176 if [[ -n ${_KDE5_ECLASS} ]] ; then
178 >=kde-frameworks/breeze-icons-${KFMIN}:${KFSLOT}
179 kde-frameworks/oxygen-icons:*
183 kde-frameworks/breeze-icons:*
184 kde-frameworks/oxygen-icons:*
189 eerror "Unknown value for \${ECM_NONGUI}"
190 die "Value ${ECM_NONGUI} is not supported"
200 eerror "Unknown value for \${ECM_DEBUG}"
201 die "Value ${ECM_DEBUG} is not supported"
205 case ${ECM_DESIGNERPLUGIN} in
208 if [[ -n ${_KDE5_ECLASS} ]] ; then
209 BDEPEND+=" designer? ( >=dev-qt/designer-5.12.3:${KFSLOT} )"
211 BDEPEND+=" designer? ( dev-qt/designer:${KFSLOT} )"
216 eerror "Unknown value for \${ECM_DESIGNERPLUGIN}"
217 die "Value ${ECM_DESIGNERPLUGIN} is not supported"
221 # @ECLASS-VARIABLE: KDE_DESIGNERPLUGIN
223 # If set to "false", do nothing.
224 # Otherwise, add "designer" to IUSE to toggle build of designer plugins
225 # and add the necessary BDEPEND.
226 # TODO: drop after KDE Applications 19.08.3 removal
227 : ${KDE_DESIGNERPLUGIN:=false}
228 case ${KDE_DESIGNERPLUGIN} in
232 designer? ( >=kde-frameworks/kdesignerplugin-${KFMIN}:${KFSLOT} )
237 eerror "Unknown value for \${KDE_DESIGNERPLUGIN}"
238 die "Value ${KDE_DESIGNERPLUGIN} is not supported"
242 case ${ECM_EXAMPLES} in
248 eerror "Unknown value for \${ECM_EXAMPLES}"
249 die "Value ${ECM_EXAMPLES} is not supported"
253 case ${ECM_HANDBOOK} in
254 true|optional|forceoptional)
256 BDEPEND+=" handbook? ( >=kde-frameworks/kdoctools-${KFMIN}:${KFSLOT} )"
260 eerror "Unknown value for \${ECM_HANDBOOK}"
261 die "Value ${ECM_HANDBOOK} is not supported"
265 case ${ECM_QTHELP} in
268 if [[ -n ${_KDE5_ECLASS} ]] ; then
269 COMMONDEPEND+=" doc? ( >=dev-qt/qt-docs-5.12.3:${KFSLOT} )"
270 BDEPEND+=" doc? ( >=dev-qt/qthelp-5.12.3:${KFSLOT} )"
272 COMMONDEPEND+=" doc? ( dev-qt/qt-docs:${KFSLOT} )"
273 BDEPEND+=" doc? ( dev-qt/qthelp:${KFSLOT} )"
275 BDEPEND+=" doc? ( >=app-doc/doxygen-1.8.13-r1 )"
279 eerror "Unknown value for \${ECM_QTHELP}"
280 die "Value ${ECM_QTHELP} is not supported"
285 true|optional|forceoptional|forceoptional-recursive)
287 if [[ -n ${_KDE5_ECLASS} ]] ; then
288 DEPEND+=" test? ( >=dev-qt/qttest-5.12.3:${KFSLOT} )"
290 DEPEND+=" test? ( dev-qt/qttest:${KFSLOT} )"
292 RESTRICT+=" !test? ( test )"
296 eerror "Unknown value for \${ECM_TEST}"
297 die "Value ${ECM_TEST} is not supported"
301 BDEPEND+=" >=kde-frameworks/extra-cmake-modules-${KFMIN}:${KFSLOT}"
302 RDEPEND+=" >=kde-frameworks/kf-env-4"
303 if [[ -n ${_KDE5_ECLASS} ]] ; then
304 COMMONDEPEND+=" >=dev-qt/qtcore-5.12.3:${KFSLOT}"
306 COMMONDEPEND+=" dev-qt/qtcore:${KFSLOT}"
309 DEPEND+=" ${COMMONDEPEND}"
310 RDEPEND+=" ${COMMONDEPEND}"
313 # @FUNCTION: _ecm_banned_var
316 # Banned kde5*.eclass variables are banned.
318 die "$1 is banned. use $2 instead."
321 if [[ -z ${_KDE5_ECLASS} ]] ; then
322 [[ -n ${KDE_DEBUG} ]] && _ecm_banned_var KDE_DEBUG ECM_DEBUG
323 [[ -n ${KDE_EXAMPLES} ]] && _ecm_banned_var KDE_EXAMPLES ECM_EXAMPLES
324 [[ -n ${KDE_HANDBOOK} ]] && _ecm_banned_var KDE_HANDBOOK ECM_HANDBOOK
325 [[ -n ${KDE_DOC_DIR} ]] && _ecm_banned_var KDE_DOC_DIR ECM_HANDBOOK_DIR
326 [[ -n ${KDE_PO_DIRS} ]] && _ecm_banned_var KDE_PO_DIRS ECM_PO_DIRS
327 [[ -n ${KDE_QTHELP} ]] && _ecm_banned_var KDE_QTHELP ECM_QTHELP
328 [[ -n ${KDE_TEST} ]] && _ecm_banned_var KDE_TEST ECM_TEST
331 # @ECLASS-VARIABLE: KDE_GCC_MINIMAL
334 # Minimum version of active GCC to require. This is checked in
335 # ecm_pkg_pretend and ecm_pkg_setup.
337 # @FUNCTION: _ecm_check_gcc_version
340 # Determine if the current GCC version is acceptable, otherwise die.
341 _ecm_check_gcc_version() {
342 if [[ ${MERGE_TYPE} != binary && -v KDE_GCC_MINIMAL ]] && tc-is-gcc; then
344 local version=$(gcc-version)
346 debug-print "GCC version check activated"
347 debug-print "Version detected: ${version}"
348 debug-print "Version required: ${KDE_GCC_MINIMAL}"
350 ver_test ${version} -lt ${KDE_GCC_MINIMAL} &&
351 die "Sorry, but gcc-${KDE_GCC_MINIMAL} or later is required for this package (found ${version})."
355 # @FUNCTION: _ecm_strip_handbook_translations
358 # If LINGUAS is defined, enable only the requested translations when required.
359 _ecm_strip_handbook_translations() {
360 if ! [[ -v LINGUAS ]]; then
365 for po in ${ECM_PO_DIRS}; do
366 if [[ -d ${po} ]] ; then
367 pushd ${po} > /dev/null || die
370 if [[ -e ${lang} ]] && ! has ${lang/.po/} ${LINGUAS} ; then
375 *) rm -r ${lang} || die ;;
377 if [[ -e CMakeLists.txt ]] ; then
378 cmake_comment_add_subdirectory ${lang}
379 sed -e "/add_subdirectory([[:space:]]*${lang}\/.*[[:space:]]*)/d" \
380 -i CMakeLists.txt || die
384 popd > /dev/null || die
389 # @FUNCTION: ecm_punt_bogus_dep
390 # @USAGE: <prefix> <dependency>
392 # Removes a specified dependency from a find_package call with multiple
394 ecm_punt_bogus_dep() {
398 if [[ ! -e "CMakeLists.txt" ]]; then
402 pcregrep -Mni "(?s)find_package\s*\(\s*${prefix}[^)]*?${dep}.*?\)" CMakeLists.txt > "${T}/bogus${dep}"
404 # pcregrep returns non-zero on no matches/error
405 if [[ $? -ne 0 ]] ; then
409 local length=$(wc -l "${T}/bogus${dep}" | cut -d " " -f 1)
410 local first=$(head -n 1 "${T}/bogus${dep}" | cut -d ":" -f 1)
411 local last=$(( length + first - 1))
413 sed -e "${first},${last}s/${dep}//" -i CMakeLists.txt || die
415 if [[ ${length} -eq 1 ]] ; then
416 sed -e "/find_package\s*(\s*${prefix}\(\s\+\(REQUIRED\|CONFIG\|COMPONENTS\|\${[A-Z0-9_]*}\)\)\+\s*)/Is/^/# removed by ecm.eclass - /" -i CMakeLists.txt || die
420 # @FUNCTION: ecm_pkg_pretend
422 # Checks if the active compiler meets the minimum version requirements.
423 # phase function is only exported if KDE_GCC_MINIMAL is defined.
425 debug-print-function ${FUNCNAME} "$@"
426 _ecm_check_gcc_version
429 # @FUNCTION: ecm_pkg_setup
431 # Checks if the active compiler meets the minimum version requirements.
433 debug-print-function ${FUNCNAME} "$@"
434 _ecm_check_gcc_version
437 # @FUNCTION: ecm_src_prepare
439 # Wrapper for cmake_src_prepare with lots of extra logic for magic
440 # handling of linguas, tests, handbook etc.
442 debug-print-function ${FUNCNAME} "$@"
446 # only build examples when required
447 if ! { in_iuse examples && use examples; } ; then
448 cmake_comment_add_subdirectory examples
451 # only enable handbook when required
452 if in_iuse handbook && ! use handbook ; then
453 cmake_comment_add_subdirectory ${ECM_HANDBOOK_DIR}
455 if [[ ${ECM_HANDBOOK} = forceoptional ]] ; then
456 ecm_punt_bogus_dep KF5 DocTools
457 sed -i -e "/kdoctools_install/ s/^/#DONT/" CMakeLists.txt || die
461 # drop translations when nls is not wanted
462 if in_iuse nls && ! use nls ; then
464 for po in ${ECM_PO_DIRS}; do
469 # don't change behaviour for kde5.eclass consumers
470 # for ported ebuilds, limit playing field of this to kde-*/ categories
471 if [[ -n ${_KDE5_ECLASS} ]] ; then
472 _ecm_strip_handbook_translations # TODO: kde5.eclass cleanup
473 elif [[ ${CATEGORY} = kde-* ]] ; then
474 # always install unconditionally for kconfigwidgets - if you use
475 # language X as system language, and there is a combobox with language
476 # names, the translated language name for language Y is taken from
477 # /usr/share/locale/Y/kf5_entry.desktop
478 [[ ${PN} != kconfigwidgets ]] && _ecm_strip_handbook_translations
481 # only build unit tests when required
482 if ! { in_iuse test && use test; } ; then
483 if [[ ${ECM_TEST} = forceoptional ]] ; then
484 ecm_punt_bogus_dep Qt5 Test
485 # if forceoptional, also cover non-kde categories
486 cmake_comment_add_subdirectory autotests test tests
487 elif [[ ${ECM_TEST} = forceoptional-recursive ]] ; then
488 ecm_punt_bogus_dep Qt5 Test
489 local f pf="${T}/${P}"-tests-optional.patch
490 touch ${pf} || die "Failed to touch patch file"
491 for f in $(find . -type f -name "CMakeLists.txt" -exec \
492 grep -l "^\s*add_subdirectory\s*\(\s*.*\(auto|unit\)\?tests\?\s*)\s*\)" {} \;); do
493 cp ${f} ${f}.old || die "Failed to prepare patch origfile"
494 pushd ${f%/*} > /dev/null || die
495 ecm_punt_bogus_dep Qt5 Test
496 sed -i CMakeLists.txt -e \
497 "/^#/! s/add_subdirectory\s*\(\s*.*\(auto|unit\)\?tests\?\s*)\s*\)/if(BUILD_TESTING)\n&\nendif()/" \
499 popd > /dev/null || die
500 diff -Naur ${f}.old ${f} 1>>${pf}
501 rm ${f}.old || die "Failed to clean up"
503 eqawarn "Build system was modified by ECM_TEST=forceoptional-recursive."
504 eqawarn "Unified diff file ready for pickup in:"
506 eqawarn "Push it upstream to make this message go away."
507 elif [[ ${CATEGORY} = kde-frameworks || ${CATEGORY} = kde-plasma || ${CATEGORY} = kde-apps ]] ; then
508 cmake_comment_add_subdirectory autotests test tests
512 # in frameworks, tests = manual tests so never build them
513 if [[ ${CATEGORY} = kde-frameworks ]] && [[ ${PN} != extra-cmake-modules ]]; then
514 cmake_comment_add_subdirectory tests
518 # @FUNCTION: ecm_src_configure
520 # Wrapper for cmake_src_configure with extra logic for magic handling of
521 # handbook, tests etc.
522 ecm_src_configure() {
523 debug-print-function ${FUNCNAME} "$@"
525 # we rely on cmake.eclass to append -DNDEBUG too
526 if in_iuse debug && ! use debug; then
527 append-cppflags -DQT_NO_DEBUG
532 if in_iuse test && ! use test ; then
533 cmakeargs+=( -DBUILD_TESTING=OFF )
535 if [[ ${ECM_TEST} = optional ]] ; then
536 cmakeargs+=( -DCMAKE_DISABLE_FIND_PACKAGE_Qt5Test=ON )
540 if [[ ${ECM_HANDBOOK} = optional ]] ; then
541 cmakeargs+=( -DCMAKE_DISABLE_FIND_PACKAGE_KF5DocTools=$(usex !handbook) )
544 if in_iuse designer && [[ ${ECM_DESIGNERPLUGIN} = true ]]; then
545 cmakeargs+=( -DBUILD_DESIGNERPLUGIN=$(usex designer) )
548 # TODO: drop after KDE Applications 19.08.3 removal
549 if in_iuse designer && [[ ${KDE_DESIGNERPLUGIN} != false ]] ; then
550 cmakeargs+=( $(cmake_use_find_package designer KF5DesignerPlugin) )
553 if [[ ${ECM_QTHELP} = true ]]; then
554 cmakeargs+=( -DBUILD_QCH=$(usex doc) )
557 if [[ ${ECM_KDEINSTALLDIRS} = true ]] ; then
559 # install mkspecs in the same directory as Qt stuff
560 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
561 # move handbook outside of doc dir, bug 667138
562 -DKDE_INSTALL_DOCBUNDLEDIR="${EPREFIX}/usr/share/help"
566 # allow the ebuild to override what we set here
567 mycmakeargs=("${cmakeargs[@]}" "${mycmakeargs[@]}")
572 # @FUNCTION: ecm_src_compile
574 # Wrapper for cmake_src_compile. Currently doesn't do anything extra, but
575 # is included as part of the API just in case it's needed in the future.
577 debug-print-function ${FUNCNAME} "$@"
579 cmake_src_compile "$@"
582 # @FUNCTION: ecm_src_test
584 # Wrapper for cmake_src_test with extra logic for magic handling of dbus
587 debug-print-function ${FUNCNAME} "$@"
590 if [[ -n "${VIRTUALDBUS_TEST}" ]]; then
591 export $(dbus-launch)
597 # When run as normal user during ebuild development with the ebuild command,
598 # tests tend to access the session DBUS. This however is not possible in a
599 # real emerge or on the tinderbox.
600 # make sure it does not happen, so bad tests can be recognized and disabled
601 unset DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID
603 if [[ ${VIRTUALX_REQUIRED} = always || ${VIRTUALX_REQUIRED} = test ]]; then
609 if [[ -n "${DBUS_SESSION_BUS_PID}" ]] ; then
610 kill ${DBUS_SESSION_BUS_PID}
614 # @FUNCTION: ecm_src_install
616 # Wrapper for cmake_src_install. Currently doesn't do anything extra, but
617 # is included as part of the API just in case it's needed in the future.
619 debug-print-function ${FUNCNAME} "$@"
624 # @FUNCTION: ecm_pkg_preinst
626 # Sets up environment variables required in ecm_pkg_postinst.
628 debug-print-function ${FUNCNAME} "$@"
630 case ${ECM_NONGUI} in
631 false) xdg_pkg_preinst ;;
636 # @FUNCTION: ecm_pkg_postinst
638 # Updates the various XDG caches (icon, desktop, mime) if necessary.
640 debug-print-function ${FUNCNAME} "$@"
642 case ${ECM_NONGUI} in
643 false) xdg_pkg_postinst ;;
647 if [[ -n ${_KDE_ORG_ECLASS} ]] && [[ -z ${I_KNOW_WHAT_I_AM_DOING} ]] && [[ ${KDE_BUILD_TYPE} = live ]]; then
648 einfo "WARNING! This is an experimental live ebuild of ${CATEGORY}/${PN}"
649 einfo "Use it at your own risk."
650 einfo "Do _NOT_ file bugs at bugs.gentoo.org because of this ebuild!"
654 # @FUNCTION: ecm_pkg_postrm
656 # Updates the various XDG caches (icon, desktop, mime) if necessary.
658 debug-print-function ${FUNCNAME} "$@"
660 case ${ECM_NONGUI} in
661 false) xdg_pkg_postrm ;;