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
> 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.
(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.
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)
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.
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.
(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.
(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.
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.