Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 832987

Summary: Is it allowed to support multiples build systems from one ebuild ?
Product: Portage Development Reporter: Fab <netbox253>
Component: UnclassifiedAssignee: Portage team <dev-portage>
Status: RESOLVED INVALID    
Severity: normal    
Priority: Normal    
Version: unspecified   
Hardware: All   
OS: Linux   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=626054
Whiteboard:
Package list:
Runtime testing required: ---

Description Fab 2022-02-09 12:15:02 UTC
From one ebuild, is it allowed to do something like following :

> EAPI=8
> 
> : ${BUILDSYSTEM_ECLASS:=meson}
> #: ${BUILDSYSTEM_ECLASS:=autotools}
> 
> case ${BUILDSYSTEM_ECLASS} in
> 	"autotools") ;;
> 	*) BUILDSYSTEM_ECLASS="meson" ;;
> esac
> 
> inherit tmpfiles xdg-utils ${BUILDSYSTEM_ECLASS}

And in phases functions :
> src_prepare() {
> 	default
> 
> 	if [[ ${BUILDSYSTEM_ECLASS} == "autotools" ]] ; then
> 		eautoreconf
> 	fi
> }
> 
> src_configure() {
> 	if [[ ${BUILDSYSTEM_ECLASS} == "meson" ]] ; then
> 		local emesonargs
> 
> 		emesonargs=(
> 			$(meson_use dbus)
> 		)
> 
> 		meson_src_configure
> 	elif [[ ${BUILDSYSTEM_ECLASS} == "autotools" ]] ; then
> 		econf \
> 			$(use_enable dbus)
> 	fi
> }

When using the ebuild command like this :
> $ env BUILDSYSTEM_ECLASS=autotools ebuild foo-9999.ebuild compile
or
> $ env BUILDSYSTEM_ECLASS=meson ebuild foo-9999.ebuild compile
or
> $ ebuild foo-9999.ebuild compile

It seems to work fine. However, sometimes, but not always (and I don't understand why),
I'm getting some QA Notice :
> $ ebuild foo-9999.ebuild manifest compile
> Appending /home/user/dev/gentoo/overlays/user to PORTDIR_OVERLAY...
> >>> Creating Manifest for /home/user/dev/gentoo/overlays/user/app-misc/foo
>  * checking ebuild checksums ;-) ...   [ ok ]
>  * checking miscfile checksums ;-) ... [ ok ]
>  * QA Notice: ECLASS 'meson' inherited illegally in app-misc/foo-9999 pretend
>  * QA Notice: ECLASS 'multiprocessing' inherited illegally in app-misc/foo-9999 pretend
>  * QA Notice: ECLASS 'ninja-utils' inherited illegally in app-misc/foo-9999 pretend
>  * QA Notice: ECLASS 'python-utils-r1' inherited illegally in app-misc/foo-9999 pretend
>  * QA Notice: ECLASS 'meson' inherited illegally in app-misc/foo-9999 setup
>  * QA Notice: ECLASS 'multiprocessing' inherited illegally in app-misc/foo-9999 setup
>  * QA Notice: ECLASS 'ninja-utils' inherited illegally in app-misc/foo-9999 setup
>  * QA Notice: ECLASS 'python-utils-r1' inherited illegally in app-misc/foo-9999 setup
> >>> Unpacking source...

Why do I want to do this ? Because I'm the developer of the foo package, and I want to support
both build systems. It would be simpler for me to choose the build system with an environment
variable rather than keeping two differents ebuilds in sync. Is it allowed ? Is there any
other/cleaner/official way to do this ? I searched the portage tree and the devmanual, I found
nothing. Portage 3.0.30-r1 here.

Thank you.

Reproducible: Always
Comment 1 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2022-02-09 12:20:39 UTC
It is not allowed to do this. You should be inheriting each eclass that you need. You may not modify inherits via the environment: https://devmanual.gentoo.org/general-concepts/portage-cache/index.html.
Comment 2 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2022-02-09 12:21:29 UTC
What you may want to do is have a variable at the top you flip or something like that. But you can't do it via an environment variable.

You could maybe have a _pN where N is even == meson, N is odd == cmake or something, or just change a variable at the top of the ebuild when testing.
Comment 3 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2022-02-09 13:00:17 UTC
Well, strictly speaking there is no technical rule against supporting two build systems as long as their respective eclasses permit that.  However, the ebuild metadata must be immutable, i.e. environment variables must not cause things like inherits or dependencies to change.  This is necessary for caching to work correctly.

So technically you could inherit all the necessary eclasses and switch the phases appropriately but the ebuild would end up depending on both build systems, i.e. in both cases you'd have extraneous dependencies.  Now, you could get around that by replacing the envvar with USE flags or || blocks and detecting which build system is available and using that.

However, such an ebuild would not be accepted into ::gentoo as containing a lot of unnecessary complexity.  If both build systems are equivalent, settle on one and use it.  If they're not, use the one that's better (e.g. more functional).