Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 947668 - multilib-build.eclass header wrapper breaks cmake checks which parse headers using regex
Summary: multilib-build.eclass header wrapper breaks cmake checks which parse headers ...
Status: UNCONFIRMED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Michał Górny
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-01-07 12:38 UTC by Philippe Michaud-Boudreault
Modified: 2025-02-22 17:23 UTC (History)
4 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Philippe Michaud-Boudreault 2025-01-07 12:38:37 UTC
Hello Gentoo people,

The problem I have run accross is that Gentoo installs a bunch of wrappers in /usr/include/ to redirect to header files, in order to offer more convenient multilib support.

What I mean by this is the following, as an example, /usr/include/db.h contains this on my system:

```
/* This file is auto-generated by multilib-build.eclass
 * as a multilib-friendly wrapper. For the original content,
 * please see the files that are #included below.
 */

#if defined(__x86_64__) /* amd64 */
#	if defined(__ILP32__) /* x32 ABI */
#		error "abi_x86_x32 not supported by the package."
#	else /* 64-bit ABI */
#		include <x86_64-pc-linux-gnu/db6.0/db.h>
#	endif
#elif defined(__i386__) /* plain x86 */
#	error "abi_x86_32 not supported by the package."
#elif defined(__mips__)
#	if(_MIPS_SIM == _ABIN32) /* n32 */
#		error "abi_mips_n32 not supported by the package."
#	elif(_MIPS_SIM == _ABI64) /* n64 */
#		error "abi_mips_n64 not supported by the package."
#	elif(_MIPS_SIM == _ABIO32) /* o32 */
#		error "abi_mips_o32 not supported by the package."
#	endif
#elif defined(__sparc__)
#	if defined(__arch64__)
#		error "abi_sparc_64 not supported by the package."
#	else
#		error "abi_sparc_32 not supported by the package."
#	endif
#elif defined(__s390__)
#	if defined(__s390x__)
#		error "abi_s390_64 not supported by the package."
#	else
#		error "abi_s390_32 not supported by the package."
#	endif
#elif defined(__powerpc__) || defined(__ppc__)
#	if defined(__powerpc64__) || defined(__ppc64__)
#		error "abi_ppc_64 not supported by the package."
#	else
#		error "abi_ppc_32 not supported by the package."
#	endif
#elif defined(SWIG) /* https://sourceforge.net/p/swig/bugs/799/ */
#	include <x86_64-pc-linux-gnu/db6.0/db.h>
#else
#	error "No ABI matched, please report a bug to bugs.gentoo.org"
#endif
```

Now this is all fine, but CMake depends on being able to regexp version strings in the header file, which means Gentoo just broke all software that check for packages using Find* scripts.

For an example of software that fails to build, see BCH:  https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node.git

I don't know how to resolve this, I've given it some thought but no idea just yet. I don't think leaving the behaviour like it is is acceptable, this is breaking a lot of things and other distributions don't do this.

-- Phil
Comment 1 Mike Gilbert gentoo-dev 2025-01-07 17:20:12 UTC
> Now this is all fine, but CMake depends on being able to regexp version strings in the header file, which means Gentoo just broke all software that check for packages using Find* scripts.

It's not cmake's fault, but rather the fault of poorly written cmake modules.

Example of a broken cmake check:

https://gitlab.com/bitcoin-cash-node/bitcoin-cash-node/-/blob/v28.0.1/cmake/modules/FindBerkeleyDB.cmake?ref_type=tags#L92-132

My advice would be "don't do that". Instead, provide build options or use pkg-config to discover the information.
Comment 2 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2025-01-07 18:47:47 UTC
(In reply to Philippe Michaud-Boudreault from comment #0)
> 
> Now this is all fine, but CMake depends on being able to regexp version
> strings in the header file, which means Gentoo just broke all software that
> check for packages using Find* scripts.

wrt "just broke", I'll note that this isn't a recent change at all.

Anyway, floppym is correct.
Comment 3 Eli Schwartz gentoo-dev 2025-01-07 18:57:11 UTC
CMake loves regex. Regex is terrible.

Previously, in the CMake core installation: https://gitlab.kitware.com/cmake/cmake/-/issues/25200


Meson for example has https://mesonbuild.com/Reference-manual_returned_compiler.html#compilerget_define, which you can use to perform a preprocessor check on the value of a define -- this correctly handles multilib wrappers. You can then utilize the string value of the version directly, and simply split it on "." instead of something fragile like a regular expression which is prone to e.g. erroneous results if the upstream software decides to change how many version components they use (as happened with zlib)
Comment 4 Mike Gilbert gentoo-dev 2025-01-07 19:02:57 UTC
Note that I have assigned this to the eclass maintainer in case there is some magic solution I haven't thought of.

I suspect this will be closed as CANTFIX or INVALID.
Comment 5 Philippe Michaud-Boudreault 2025-01-07 20:15:19 UTC
I agree about CMake being suboptimal on the best of days, however there is just a lot of it out there... Sure, the cmake module is wrong, but it can't even be fixed the way the multilib wrapper is done :\

sys-libs/db doesn't ship a pkg-config file.

Eli's comment is helpful though.
I'll see if I can petition @CMake about adding functionality similar to meson's compiler.get_define(). But then the problem is cross-compiles break, right?
sigh.
Comment 6 Mike Gilbert gentoo-dev 2025-01-07 21:46:14 UTC
(In reply to Philippe Michaud-Boudreault from comment #5)
> But then the problem is cross-compiles break, right?

Cross-compiles work fine. meson invokes the compiler to pre-process a dummy source file, and then parses the resulting output.
Comment 7 Eli Schwartz gentoo-dev 2025-01-07 21:47:00 UTC
(In reply to Philippe Michaud-Boudreault from comment #5)
> Eli's comment is helpful though.
> I'll see if I can petition @CMake about adding functionality similar to
> meson's compiler.get_define(). But then the problem is cross-compiles break,
> right?
> sigh.


Nope. meson's get_define is fully cross-safe since it only runs a cross preprocessor (so, ${CROSS_COMPILER} -E is all you need) in order to print out the preprocessed values. It's the same underlying "compiler checks" infrastructure that drives tests for "compiles" and "links" and "runs".

Checking if a binary compiles-and-runs can't be done during a cross compilation if you don't have the ability to exec() a cross-compiled binary, and there's a special error status for that. You can also define a meson "exe_wrapper" property to e.g. qemu-user which will make those work.

But again, none of that is necessary to check a define. get_define() is very much cross-friendly.
Comment 8 Eli Schwartz gentoo-dev 2025-01-07 21:47:58 UTC
With cmake, you can compile a binary that printf's the value of the db.h version macro. That's not very cross friendly as you have to be able to run the resulting binary. But it does work today with cmake, I believe.