1 # Copyright 1999-2020 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 -DQT_NO_DEBUG to CPPFLAGS. If set to
78 # "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
177 kde-frameworks/breeze-icons:*
178 kde-frameworks/oxygen-icons:*
182 eerror "Unknown value for \${ECM_NONGUI}"
183 die "Value ${ECM_NONGUI} is not supported"
193 eerror "Unknown value for \${ECM_DEBUG}"
194 die "Value ${ECM_DEBUG} is not supported"
198 case ${ECM_DESIGNERPLUGIN} in
201 BDEPEND+=" designer? ( dev-qt/designer:${KFSLOT} )"
205 eerror "Unknown value for \${ECM_DESIGNERPLUGIN}"
206 die "Value ${ECM_DESIGNERPLUGIN} is not supported"
210 case ${ECM_EXAMPLES} in
216 eerror "Unknown value for \${ECM_EXAMPLES}"
217 die "Value ${ECM_EXAMPLES} is not supported"
221 case ${ECM_HANDBOOK} in
222 true|optional|forceoptional)
224 BDEPEND+=" handbook? ( >=kde-frameworks/kdoctools-${KFMIN}:${KFSLOT} )"
228 eerror "Unknown value for \${ECM_HANDBOOK}"
229 die "Value ${ECM_HANDBOOK} is not supported"
233 case ${ECM_QTHELP} in
236 COMMONDEPEND+=" doc? ( dev-qt/qt-docs:${KFSLOT} )"
238 >=app-doc/doxygen-1.8.13-r1
239 dev-qt/qthelp:${KFSLOT}
244 eerror "Unknown value for \${ECM_QTHELP}"
245 die "Value ${ECM_QTHELP} is not supported"
250 true|optional|forceoptional|forceoptional-recursive)
252 DEPEND+=" test? ( dev-qt/qttest:${KFSLOT} )"
253 RESTRICT+=" !test? ( test )"
257 eerror "Unknown value for \${ECM_TEST}"
258 die "Value ${ECM_TEST} is not supported"
262 BDEPEND+=" >=kde-frameworks/extra-cmake-modules-${KFMIN}:${KFSLOT}"
263 RDEPEND+=" >=kde-frameworks/kf-env-4"
264 COMMONDEPEND+=" dev-qt/qtcore:${KFSLOT}"
266 DEPEND+=" ${COMMONDEPEND}"
267 RDEPEND+=" ${COMMONDEPEND}"
270 # @FUNCTION: _ecm_banned_var
273 # Banned kde5*.eclass variables are banned.
275 die "$1 is banned. use $2 instead."
278 if [[ -z ${_KDE5_ECLASS} ]] ; then
279 [[ -n ${KDE_DEBUG} ]] && _ecm_banned_var KDE_DEBUG ECM_DEBUG
280 [[ -n ${KDE_EXAMPLES} ]] && _ecm_banned_var KDE_EXAMPLES ECM_EXAMPLES
281 [[ -n ${KDE_HANDBOOK} ]] && _ecm_banned_var KDE_HANDBOOK ECM_HANDBOOK
282 [[ -n ${KDE_DOC_DIR} ]] && _ecm_banned_var KDE_DOC_DIR ECM_HANDBOOK_DIR
283 [[ -n ${KDE_PO_DIRS} ]] && _ecm_banned_var KDE_PO_DIRS ECM_PO_DIRS
284 [[ -n ${KDE_QTHELP} ]] && _ecm_banned_var KDE_QTHELP ECM_QTHELP
285 [[ -n ${KDE_TEST} ]] && _ecm_banned_var KDE_TEST ECM_TEST
288 # @ECLASS-VARIABLE: KDE_GCC_MINIMAL
291 # Minimum version of active GCC to require. This is checked in
292 # ecm_pkg_pretend and ecm_pkg_setup.
294 # @FUNCTION: _ecm_check_gcc_version
297 # Determine if the current GCC version is acceptable, otherwise die.
298 _ecm_check_gcc_version() {
299 if [[ ${MERGE_TYPE} != binary && -v KDE_GCC_MINIMAL ]] && tc-is-gcc; then
301 local version=$(gcc-version)
303 debug-print "GCC version check activated"
304 debug-print "Version detected: ${version}"
305 debug-print "Version required: ${KDE_GCC_MINIMAL}"
307 ver_test ${version} -lt ${KDE_GCC_MINIMAL} &&
308 die "Sorry, but gcc-${KDE_GCC_MINIMAL} or later is required for this package (found ${version})."
312 # @FUNCTION: _ecm_strip_handbook_translations
315 # If LINGUAS is defined, enable only the requested translations when required.
316 _ecm_strip_handbook_translations() {
317 if ! [[ -v LINGUAS ]]; then
322 for po in ${ECM_PO_DIRS}; do
323 if [[ -d ${po} ]] ; then
324 pushd ${po} > /dev/null || die
327 if [[ -e ${lang} ]] && ! has ${lang/.po/} ${LINGUAS} ; then
332 *) rm -r ${lang} || die ;;
334 if [[ -e CMakeLists.txt ]] ; then
335 cmake_comment_add_subdirectory ${lang}
336 sed -e "/add_subdirectory([[:space:]]*${lang}\/.*[[:space:]]*)/d" \
337 -i CMakeLists.txt || die
341 popd > /dev/null || die
346 # @FUNCTION: ecm_punt_bogus_dep
347 # @USAGE: <prefix> <dependency>
349 # Removes a specified dependency from a find_package call with multiple
351 ecm_punt_bogus_dep() {
355 if [[ ! -e "CMakeLists.txt" ]]; then
359 pcregrep -Mni "(?s)find_package\s*\(\s*${prefix}[^)]*?${dep}.*?\)" CMakeLists.txt > "${T}/bogus${dep}"
361 # pcregrep returns non-zero on no matches/error
362 if [[ $? -ne 0 ]] ; then
366 local length=$(wc -l "${T}/bogus${dep}" | cut -d " " -f 1)
367 local first=$(head -n 1 "${T}/bogus${dep}" | cut -d ":" -f 1)
368 local last=$(( length + first - 1))
370 sed -e "${first},${last}s/${dep}//" -i CMakeLists.txt || die
372 if [[ ${length} -eq 1 ]] ; then
373 sed -e "/find_package\s*(\s*${prefix}\(\s\+\(REQUIRED\|CONFIG\|COMPONENTS\|\${[A-Z0-9_]*}\)\)\+\s*)/Is/^/# removed by ecm.eclass - /" -i CMakeLists.txt || die
377 # @FUNCTION: ecm_pkg_pretend
379 # Checks if the active compiler meets the minimum version requirements.
380 # phase function is only exported if KDE_GCC_MINIMAL is defined.
382 debug-print-function ${FUNCNAME} "$@"
383 _ecm_check_gcc_version
386 # @FUNCTION: ecm_pkg_setup
388 # Checks if the active compiler meets the minimum version requirements.
390 debug-print-function ${FUNCNAME} "$@"
391 _ecm_check_gcc_version
394 # @FUNCTION: ecm_src_prepare
396 # Wrapper for cmake_src_prepare with lots of extra logic for magic
397 # handling of linguas, tests, handbook etc.
399 debug-print-function ${FUNCNAME} "$@"
403 # only build examples when required
404 if ! { in_iuse examples && use examples; } ; then
405 cmake_comment_add_subdirectory examples
408 # only enable handbook when required
409 if in_iuse handbook && ! use handbook ; then
410 cmake_comment_add_subdirectory ${ECM_HANDBOOK_DIR}
412 if [[ ${ECM_HANDBOOK} = forceoptional ]] ; then
413 ecm_punt_bogus_dep KF5 DocTools
414 sed -i -e "/kdoctools_install/ s/^/#DONT/" CMakeLists.txt || die
418 # drop translations when nls is not wanted
419 if in_iuse nls && ! use nls ; then
421 for po in ${ECM_PO_DIRS}; do
426 # limit playing field of locale stripping to kde-*/ categories
427 if [[ ${CATEGORY} = kde-* ]] ; then
428 # always install unconditionally for kconfigwidgets - if you use
429 # language X as system language, and there is a combobox with language
430 # names, the translated language name for language Y is taken from
431 # /usr/share/locale/Y/kf5_entry.desktop
432 [[ ${PN} != kconfigwidgets ]] && _ecm_strip_handbook_translations
435 # only build unit tests when required
436 if ! { in_iuse test && use test; } ; then
437 if [[ ${ECM_TEST} = forceoptional ]] ; then
438 ecm_punt_bogus_dep Qt5 Test
439 # if forceoptional, also cover non-kde categories
440 cmake_comment_add_subdirectory autotests test tests
441 elif [[ ${ECM_TEST} = forceoptional-recursive ]] ; then
442 ecm_punt_bogus_dep Qt5 Test
443 local f pf="${T}/${P}"-tests-optional.patch
444 touch ${pf} || die "Failed to touch patch file"
445 for f in $(find . -type f -name "CMakeLists.txt" -exec \
446 grep -l "^\s*add_subdirectory\s*\(\s*.*\(auto|unit\)\?tests\?\s*)\s*\)" {} \;); do
447 cp ${f} ${f}.old || die "Failed to prepare patch origfile"
448 pushd ${f%/*} > /dev/null || die
449 ecm_punt_bogus_dep Qt5 Test
450 sed -i CMakeLists.txt -e \
451 "/^#/! s/add_subdirectory\s*\(\s*.*\(auto|unit\)\?tests\?\s*)\s*\)/if(BUILD_TESTING)\n&\nendif()/" \
453 popd > /dev/null || die
454 diff -Naur ${f}.old ${f} 1>>${pf}
455 rm ${f}.old || die "Failed to clean up"
457 eqawarn "Build system was modified by ECM_TEST=forceoptional-recursive."
458 eqawarn "Unified diff file ready for pickup in:"
460 eqawarn "Push it upstream to make this message go away."
461 elif [[ ${CATEGORY} = kde-frameworks || ${CATEGORY} = kde-plasma || ${CATEGORY} = kde-apps ]] ; then
462 cmake_comment_add_subdirectory autotests test tests
466 # in frameworks, tests = manual tests so never build them
467 if [[ ${CATEGORY} = kde-frameworks ]] && [[ ${PN} != extra-cmake-modules ]]; then
468 cmake_comment_add_subdirectory tests
472 # @FUNCTION: ecm_src_configure
474 # Wrapper for cmake_src_configure with extra logic for magic handling of
475 # handbook, tests etc.
476 ecm_src_configure() {
477 debug-print-function ${FUNCNAME} "$@"
479 if in_iuse debug && ! use debug; then
480 append-cppflags -DQT_NO_DEBUG
485 if in_iuse test && ! use test ; then
486 cmakeargs+=( -DBUILD_TESTING=OFF )
488 if [[ ${ECM_TEST} = optional ]] ; then
489 cmakeargs+=( -DCMAKE_DISABLE_FIND_PACKAGE_Qt5Test=ON )
493 if [[ ${ECM_HANDBOOK} = optional ]] ; then
494 cmakeargs+=( -DCMAKE_DISABLE_FIND_PACKAGE_KF5DocTools=$(usex !handbook) )
497 if in_iuse designer && [[ ${ECM_DESIGNERPLUGIN} = true ]]; then
498 cmakeargs+=( -DBUILD_DESIGNERPLUGIN=$(usex designer) )
501 if [[ ${ECM_QTHELP} = true ]]; then
502 cmakeargs+=( -DBUILD_QCH=$(usex doc) )
505 if [[ ${ECM_KDEINSTALLDIRS} = true ]] ; then
507 # install mkspecs in the same directory as Qt stuff
508 -DKDE_INSTALL_USE_QT_SYS_PATHS=ON
509 # move handbook outside of doc dir, bug 667138
510 -DKDE_INSTALL_DOCBUNDLEDIR="${EPREFIX}/usr/share/help"
514 # allow the ebuild to override what we set here
515 mycmakeargs=("${cmakeargs[@]}" "${mycmakeargs[@]}")
520 # @FUNCTION: ecm_src_compile
522 # Wrapper for cmake_src_compile. Currently doesn't do anything extra, but
523 # is included as part of the API just in case it's needed in the future.
525 debug-print-function ${FUNCNAME} "$@"
527 cmake_src_compile "$@"
530 # @FUNCTION: ecm_src_test
532 # Wrapper for cmake_src_test with extra logic for magic handling of dbus
535 debug-print-function ${FUNCNAME} "$@"
538 if [[ -n "${VIRTUALDBUS_TEST}" ]]; then
539 export $(dbus-launch)
545 # When run as normal user during ebuild development with the ebuild command,
546 # tests tend to access the session DBUS. This however is not possible in a
547 # real emerge or on the tinderbox.
548 # make sure it does not happen, so bad tests can be recognized and disabled
549 unset DBUS_SESSION_BUS_ADDRESS DBUS_SESSION_BUS_PID
551 if [[ ${VIRTUALX_REQUIRED} = always || ${VIRTUALX_REQUIRED} = test ]]; then
557 if [[ -n "${DBUS_SESSION_BUS_PID}" ]] ; then
558 kill ${DBUS_SESSION_BUS_PID}
562 # @FUNCTION: ecm_src_install
564 # Wrapper for cmake_src_install. Currently doesn't do anything extra, but
565 # is included as part of the API just in case it's needed in the future.
567 debug-print-function ${FUNCNAME} "$@"
572 # @FUNCTION: ecm_pkg_preinst
574 # Sets up environment variables required in ecm_pkg_postinst.
576 debug-print-function ${FUNCNAME} "$@"
578 case ${ECM_NONGUI} in
579 false) xdg_pkg_preinst ;;
584 # @FUNCTION: ecm_pkg_postinst
586 # Updates the various XDG caches (icon, desktop, mime) if necessary.
588 debug-print-function ${FUNCNAME} "$@"
590 case ${ECM_NONGUI} in
591 false) xdg_pkg_postinst ;;
595 if [[ -n ${_KDE_ORG_ECLASS} ]] && [[ -z ${I_KNOW_WHAT_I_AM_DOING} ]] && [[ ${KDE_BUILD_TYPE} = live ]]; then
596 einfo "WARNING! This is an experimental live ebuild of ${CATEGORY}/${PN}"
597 einfo "Use it at your own risk."
598 einfo "Do _NOT_ file bugs at bugs.gentoo.org because of this ebuild!"
602 # @FUNCTION: ecm_pkg_postrm
604 # Updates the various XDG caches (icon, desktop, mime) if necessary.
606 debug-print-function ${FUNCNAME} "$@"
608 case ${ECM_NONGUI} in
609 false) xdg_pkg_postrm ;;