From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 070A21392EF for ; Sat, 21 Jun 2014 10:31:39 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B63C5E0951; Sat, 21 Jun 2014 10:31:32 +0000 (UTC) Received: from mail-ve0-f172.google.com (mail-ve0-f172.google.com [209.85.128.172]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 82417E093E for ; Sat, 21 Jun 2014 10:31:31 +0000 (UTC) Received: by mail-ve0-f172.google.com with SMTP id jz11so4445142veb.17 for ; Sat, 21 Jun 2014 03:31:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=EOVOGxgW8DZwqqMyJqza18mQEpmPyxnTnWN/HIYDy4g=; b=eq21J4uE5i5nN3xJU6ayZw8/23yPYaT5XNl3DqJ0NsD2YWhyAL54On1mOvSFkhuTWo jy78AHT5noJcKRR1b9gCXgdNIBGnU7ahQTOMXYlNceU0+tO2lj7eAv1zV6cLVPXNKZdH RlpNMKD/8o2crKQYtZQCP5BtwlJwqtfO27G5OBUhjRVr5t8Ba9Ph9qUKHWyP13Y/4Hnn J28PA9VeO4VsGhB2SS1lVTh2hC8u5KZMNoVe03vb7spsbvOp737qchnqt4FLnWHLb6Jg 2m63JiANFlRwZVe4ooFSARk1TBZp6kRic43uMcUtk6jonS38YhSnDcv8be2akfVkDOnE 3dig== X-Gm-Message-State: ALoCoQkIfXHQXtnjes90uLShRRPOteD++KEA891y+cwW0vWkdeHxCXbWH3g9WshFJcBEz/3sodJe Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org MIME-Version: 1.0 X-Received: by 10.52.5.129 with SMTP id s1mr6901611vds.31.1403346690344; Sat, 21 Jun 2014 03:31:30 -0700 (PDT) Sender: gmt@be-evil.net Received: by 10.220.141.207 with HTTP; Sat, 21 Jun 2014 03:31:30 -0700 (PDT) X-Originating-IP: [75.147.143.254] In-Reply-To: <53A4954E.20002@gentoo.org> References: <539F5288.1000000@gentoo.org> <539F5AB5.7000006@gentoo.org> <539F6B3C.7030807@gentoo.org> <539F8000.5080804@gentoo.org> <539F9E41.9050505@gentoo.org> <539FA536.3010401@gentoo.org> <53A034F4.2000900@gentoo.org> <53A04DF6.6050407@gentoo.org> <1403017001.11300.1.camel@rook> <20140619212023.GC4582@rathaus.eclipse.co.uk> <53A4954E.20002@gentoo.org> Date: Sat, 21 Jun 2014 03:31:30 -0700 X-Google-Sender-Auth: Jw1chxwXhaKsA7K0d8wo1nZbwX4 Message-ID: Subject: Re: [gentoo-dev] Re: crossdev and multilib interference From: Greg Turner To: gentoo-dev@lists.gentoo.org Content-Type: multipart/alternative; boundary=20cf302efab0f99ecb04fc561c58 X-Archives-Salt: 2cb1d141-e560-40e6-b686-8d70c77adf9c X-Archives-Hash: e4efda6ba91487d5a4db8247710a67af --20cf302efab0f99ecb04fc561c58 Content-Type: text/plain; charset=UTF-8 On Fri, Jun 20, 2014 at 1:10 PM, Ian Stakenvicius wrote: > Thoughts [about wrapping gcc, so that non-native multilib-build ABI's can finally return to a world where [[ ${GCC} != *' '* ]] ]? TLDR: good idea, I'm strongly in favor of it. A wrapper would fix horrors like the following, which, last I checked, was sort-of required* on ABI_X86="*32*" DEFAULT_ABI="amd64" systems with crossdev i686-pc-linux-gnu targets in ${PATH}: --- /usr/portage/eclass/cmake-utils.eclass 2014-05-06 08:31:17.000000000 -0700 +++ /usr/local/portage/gogogmt/eclass/cmake-utils.eclass 2014-06-01 12:36:40.753904765 -0700 @@ -373,14 +373,115 @@ enable_cmake-utils_src_prepare() { } + +# retrieve a variable (i.e.: FOO) using i.e.: tc_getFOO, +# unless the variable is already defined to a nonempty value, +# in which case, it is returned unaltered +_cmake-utils_tc_get_if_needed() { + local v="$1" s + if [[ ${!v} ]] ; then + s="${!v}" + else + s=$(tc-get${v}) + fi + echo "${s}" +} + + +# trim the preceeding and trailing whitespace from a string, +# leaving inner spaces intact +_cmake-utils_trimmed() { + local s="$*" + while [[ ${s:0:1} =~ [[:space:]] ]] ; do + s="${s:1}" + done + while [[ ${s:$((${#s}-1))} =~ [[:space:]] ]] ; do + s="${s:0:$((${#s}-1))}" + done + echo "${s}" +} + +# given a string, retrieve the first word (consisting of non-space characters) +# after trimming any leading whitespace. +_cmake-utils_first_word_of() { + local s=$(_cmake-utils_trimmed "$*") + echo "${s%% *}" +} + +# given a string, retrieve the rest of the string after the first word, +# with any whitespace trimmed, retaining any whitespace between words +# (except whitespace that was between the first and second word) +_cmake-utils_subsequent_words_of() { + local s=$(_cmake-utils_trimmed "$*") + if [[ ${s} ]] ; then + s="${s#$(_cmake-utils_first_word_of "${s}")}" + echo "$(_cmake-utils_trimmed "${s}")" + else + echo "" + fi +} + +# given a variable-name, retrieve it with _cmake-utils_tc_get_if_needed +# and then from that retreive the first word +_cmake-utils_get_first_word() { + local s=$(_cmake-utils_tc_get_if_needed "$1") + echo "$(_cmake-utils_first_word_of "${s}")" +} + +# given a command-containing variable as the first argument, +# uses _cmake-utils_tc_get_if_needed to retrieve the var, and then +# returns type -P of the first word of it, ignoring rest. +_cmake-utils_get_first_word_executable() { + local w=$(_cmake-utils_get_first_word "$1") + if [[ ${w} ]] ; then + echo "$(type -P "${w}")" + else + echo "" + fi +} + +# fetches any additional bits of a variable not included in +# _cmake-utils_get_first_word. takes the variable name as an input. +# May return an empty string. +_cmake-utils_get_subsequent_words() { + local s=$(_cmake-utils_tc_get_if_needed "$1") + echo "$(_cmake-utils_subsequent_words_of "${s}")" } # @VARIABLE: mycmakeargs @@ -433,17 +534,46 @@ enable_cmake-utils_src_configure() { # Prepare Gentoo override rules (set valid compiler, append CPPFLAGS etc.) local build_rules=${BUILD_DIR}/gentoo_rules.cmake + + local _CMAKE_C_COMPILER=$(_cmake-utils_get_first_word_executable CC) + local _CCORPHANS=$(_cmake-utils_get_subsequent_words CC) + local _CMAKE_C_COMPILER_ARG1_COMMAND= + local _CMAKE_CXX_COMPILER=$(_cmake-utils_get_first_word_executable CXX) + local _CXXORPHANS=$(_cmake-utils_get_subsequent_words CXX) + local _CMAKE_CXX_COMPILER_ARG1_COMMAND= + + # This seems fairly rediculous to me, but if C{,XX}ORPHANS is nonempty, then, in order to prevent + # duplication of the first argument, we must handle the first word specially + if [[ ${_CCORPHANS} ]] ; then + _CMAKE_C_COMPILER_ARG1_COMMAND="SET (CMAKE_C_COMPILER_ARG1 $(_cmake-utils_first_word_of "${_CCORPHANS}") CACHE STRING \"C compiler first argument\" FORCE)" + _CCORPHANS=$(_cmake-utils_subsequent_words_of "${_CCORPHANS}") + fi + if [[ ${_CXXORPHANS} ]] ; then + _CMAKE_CXX_COMPILER_ARG1_COMMAND="SET (CMAKE_CXX_COMPILER_ARG1 $(_cmake-utils_first_word_of "${_CXXORPHANS}") CACHE STRING \"C++ compiler first argument\" FORCE)" + _CXXORPHANS=$(_cmake-utils_subsequent_words_of "${_CXXORPHANS}") + fi + cat > "${build_rules}" <<- _EOF_ - SET (CMAKE_AR $(type -P $(tc-getAR)) CACHE FILEPATH "Archive manager" FORCE) - SET (CMAKE_ASM_COMPILE_OBJECT " ${CFLAGS} -o -c " CACHE STRING "ASM compile command" FORCE) - SET (CMAKE_C_COMPILER $(type -P $(tc-getCC)) CACHE FILEPATH "C compiler" FORCE) - SET (CMAKE_C_COMPILE_OBJECT " ${CPPFLAGS} -o -c " CACHE STRING "C compile command" FORCE) - SET (CMAKE_CXX_COMPILER $(type -P $(tc-getCXX)) CACHE FILEPATH "C++ compiler" FORCE) - SET (CMAKE_CXX_COMPILE_OBJECT " ${CPPFLAGS} -o -c " CACHE STRING "C++ compile command" FORCE) - SET (CMAKE_RANLIB $(type -P $(tc-getRANLIB)) CACHE FILEPATH "Archive index generator" FORCE) - SET (PKG_CONFIG_EXECUTABLE $(type -P $(tc-getPKG_CONFIG)) CACHE FILEPATH "pkg-config executable" FORCE) + SET (CMAKE_C_COMPILER "${_CMAKE_C_COMPILER}" CACHE FILEPATH "C compiler" FORCE) + ${_CMAKE_C_COMPILER_ARG1_COMMAND} + SET (CMAKE_CXX_COMPILER "${_CMAKE_CXX_COMPILER}" CACHE FILEPATH "C++ compiler" FORCE) + ${_CMAKE_CXX_COMPILER_ARG1_COMMAND} + SET (CMAKE_AR "$(_cmake-utils_get_first_word_executable AR)" CACHE FILEPATH "Archive manager" FORCE) + SET (CMAKE_RANLIB "$(_cmake-utils_get_first_word_executable RANLIB)" CACHE FILEPATH "Archive index generator" FORCE) + SET (CMAKE_ASM_COMPILE_OBJECT " ${_CCORPHANS}${_CCORPHANS:+ } ${CFLAGS}${CFLAGS:+ } -o -c " CACHE STRING "ASM compile command" FORCE) + SET (CMAKE_C_COMPILE_OBJECT " ${_CCORPHANS}${_CCORPHANS:+ } ${CFLAGS}${CFLAGS:+ } -o -c " CACHE STRING "C compile command" FORCE) + SET (CMAKE_CXX_COMPILE_OBJECT " ${_CXXORPHANS}${_CXXORPHANS:+ } ${CXXFLAGS}${CXXFLAGS:+ } -o -c " CACHE STRING "C++ compile command" FORCE) + SET (CMAKE_C_LINK_EXECUTABLE " ${_CCORPHANS}${_CCORPHANS:+ } ${LDFLAGS}${LDFLAGS:+ } -o " CACHE STRING "C link command for executables" FORCE) + SET (CMAKE_C_CREATE_SHARED_LIBRARY " ${_CCORPHANS}${_CCORPHANS:+ } ${LDFLAGS}${LDFLAGS:+ } -o " CACHE STRING "C shared library link command" FORCE) + SET (CMAKE_C_CREATE_SHARED_MODULE "\${CMAKE_C_CREATE_SHARED_LIBRARY}" CACHE STRING "C shared module link command" FORCE) + SET (CMAKE_CXX_LINK_EXECUTABLE " ${_CXXORPHANS}${_CXXORPHANS:+ } ${LDFLAGS}${LDFLAGS:+ } -o " CACHE STRING "C++ link command for executables" FORCE) + SET (CMAKE_CXX_CREATE_SHARED_LIBRARY " ${_CXXORPHANS}${_CXXORPHANS:+ } ${LDFLAGS}${LDFLAGS:+ } -o " CACHE STRING "C++ shared library link command" FORCE) + SET (CMAKE_CXX_CREATE_SHARED_MODULE "\${CMAKE_CXX_CREATE_SHARED_LIBRARY}" CACHE STRING "C++ shared module link command" FORCE) + SET (PKG_CONFIG_EXECUTABLE "$(_cmake-utils_get_first_word_executable PKG_CONFIG)" CACHE FILEPATH "pkg-config executable" FORCE) _EOF_ has "${EAPI:-0}" 0 1 2 && ! use prefix && EPREFIX= Perhaps a straw-man argument, since, the above code could be made more beautiful, and then it would not be so ugly :P But, it's not just that cmake can't properly handle a C{C,XX} variables with spaces in them**. There are a bunch of similar places where we had to patch Makefiles and autotools to wedge GCC="foo bar" support in. Without hyperbole, I can honestly say, it's a lame and inelegant hack to put an /argument/ into GCC. -m${foo} is a CFLAG, not a compiler. "Everyone" knows GCC is a variable that names an executable -- but in multilib-build, for some god-awful reason, we've made it into some other thing, a hybrid-psuedo-thing that really only makes sense in a shell script, and even then, only in an improperly coded shell script :). Even if that rubicon was already crossed by ccache, distcc, etc, there is a reason none of them /require/ it. It's just asking for trouble. We'll just keep wasting time fixing subtle bugs like the above, because of it until we break down and fix it. I'd lay pretty long odds that five years from now we are still clinging to it, should we decide to stick with the status quo for now. So why not bite the bullet and save ourselves the hassle? -gmt * perhaps today the problem is mitigated, due to the same gcc-${pseudo-CHOST} executables now existing for upstream multilib-build pseudo-targets -- but, I'll bet, not solved. Usually trouble only crops up for larger framework builds with lots of sub-dirs, like qt or mysql-server, and manifests as incorrect attempts to link native libraries in -- which the compiler might or might not manage to save you from at the last moment... also note that patch is mocked up for easy reading -- it won't apply. See my overlay for the real code. Finally, sorry for the HTML -- I'm writing from the gmail ajax which obstinately refuses to allow plain-text inline patches. ** IIRC, it would be more precise to say something like "cmake's in-built hacks for the CC='exectutable argument' circumstance are subtly incompatible with our means of injecting the portage compiler values into cmake (or so things used to be; I suspect the problem still lurks to some extent), and that this ultimately manifests as confusing, intermittent build failures and correctly issued QA warnings in larger multilib-build-based ebuilds (or will in the near future; I actually wouldn't know as I run with the above patches :P), esp. in cases where a ${CC}-${CHOST} or ${CXX}-${CHOST} executables are to be found in ${PATH}." But if any unlucky person is still reading, they can see fully why I didn't bother to say all that :P --20cf302efab0f99ecb04fc561c58 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

On Fri, Jun 20, 2014 at 1:10 PM, Ian Stakenvicius <= axs@gentoo.org> wrote:
> Tho= ughts [about wrapping gcc, so that non-native multilib-build ABI's can = finally return to a world where [[ ${GCC} !=3D *' '* ]] ]?

TLDR: good idea, I'm strongly in favor of it.

A w= rapper would fix horrors like the following, which, last I checked, was sor= t-of required* on ABI_X86=3D"*32*" DEFAULT_ABI=3D"amd64"= ; systems with crossdev i686-pc-linux-gnu targets in ${PATH}:

--- /usr/port= age/eclass/cmake-utils.eclass =C2=A0 =C2=A0 =C2=A02014-05-06 08:31:17.00000= 0000 -0700
+++ /usr/local/portage/gogogmt/e= class/cmake-utils.eclass =C2=A0 =C2=A0 =C2=A0 =C2=A02014-06-01 12:36:40.753= 904765 -0700
@@ -373= ,14 +373,115 @@ enable_cmake-utils_src_prepare() {
=C2=A0}
+
+# retrieve a variable (i.e.: FOO) using i.e.: tc_getFOO,
+# unless the variable is alread= y defined to a nonempty value, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0
+# in which case, it is returned= unaltered =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0
+_cmake-utils_tc_get_if_needed()= { =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0
+ =C2=A0 =C2=A0 =C2=A0 local v= =3D"$1" s =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0
+ =C2=A0 =C2=A0 =C2=A0 if [[ ${!= v} ]] ; then=C2=A0
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 s=3D"${!v}"=C2= =A0
+ =C2=A0 =C2=A0 = =C2=A0 else =C2=A0 =C2=A0=C2=A0
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 s=3D$(tc-get${v})=C2=A0
+ =C2=A0 =C2=A0 =C2=A0 fi =C2=A0 =C2=A0
+ =C2=A0 =C2=A0 =C2=A0 echo &q= uot;${s}" =C2=A0=C2=A0
+} =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0= =C2=A0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0
+# trim the preceeding and trail= ing whitespace from a string,
+# leaving inner spaces intact
+_cmake-utils_trimmed() {
+ =C2=A0 =C2=A0 =C2=A0 local s= =3D"$*"
+ = =C2=A0 =C2=A0 =C2=A0 while [[ ${s:0:1} =3D~ [[:space:]] ]] ; do
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 s=3D"${s:1}"
+ =C2=A0 =C2=A0 =C2=A0 done
+ =C2=A0 =C2=A0 =C2=A0 w= hile [[ ${s:$((${#s}-1))} =3D~ [[:space:]] ]] ; do
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 s=3D"${s:0:$((${#s}-1))}"
+ =C2=A0 =C2=A0 =C2=A0 done
+ =C2=A0 =C2=A0 =C2=A0 e= cho "${s}"
+}
+
+# given a string, retrieve the = first word (consisting of non-space characters)
+# after trimming any leading whitespace.
+_cmake-utils_first_word_of() {<= /font>
+ =C2=A0 =C2=A0 =C2= =A0 local s=3D$(_cmake-utils_trimmed "$*")
+ =C2=A0 =C2=A0 =C2=A0 echo "${s%% *}= "
+}
+
+# given a string, retrieve the rest of the string after the firs= t word,
+# with any whitespace trimmed, = retaining any whitespace between words
+# (except whitespace that was between the first and sec= ond word)
+_cmake-utils_subsequent_words_o= f() {
+ =C2=A0 =C2= =A0 =C2=A0 local s=3D$(_cmake-utils_trimmed "$*")
+ =C2=A0 =C2=A0 =C2=A0 if [[ ${s} ]= ] ; then
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 s=3D"${s#$(_cmake-utils_first_word_of "${s}&= quot;)}"
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 echo "$(_cmake-utils_tri= mmed "${s}")"
+ =C2=A0 =C2=A0 =C2=A0 else
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 echo ""
+ =C2=A0 =C2=A0 =C2=A0 fi
+}
+
+# given a variable-name, retrieve it with _cmake-utils_tc_get_if_needed=
+# and then from that retreive t= he first word
+_cmak= e-utils_get_first_word() {
+ =C2=A0 =C2=A0 =C2=A0 local s=3D$(_cmake-utils_tc_get_if_needed &qu= ot;$1")
+ =C2=A0 =C2=A0 =C2=A0 echo &quo= t;$(_cmake-utils_first_word_of "${s}")"
+}
+
+# given a command-containing va= riable as the first argument,
+# uses _cmake-utils_tc_get_if_needed to retrieve the var, and th= en
+# returns type -P of the first = word of it, ignoring rest.
+_cmake-utils_get_first_word_executable() {
+ =C2=A0 =C2=A0 =C2=A0 local w=3D$(_cmake-ut= ils_get_first_word "$1")
+ =C2=A0 =C2=A0 =C2=A0 if [[ ${w= } ]] ; then
+ =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 echo "$(type -P "${w}&= quot;)"
+ =C2= =A0 =C2=A0 =C2=A0 else
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 echo ""
+ =C2=A0 =C2=A0 =C2=A0 fi
+}
+
+# fetches any additional bits o= f a variable not included in
+# _cmake-utils_get_first_word. =C2=A0takes the variable name as a= n input.
+# May return an empty string.
+_cmake-utils_get_sub= sequent_words() {
+ = =C2=A0 =C2=A0 =C2=A0 local s=3D$(_cmake-utils_tc_get_if_needed "$1&quo= t;)
+ =C2=A0 =C2=A0 =C2=A0 echo &quo= t;$(_cmake-utils_subsequent_words_of "${s}")"
=C2=A0}
=C2=A0
=C2=A0# @VARIABLE: mycmakeargs
@@ -433,17= +534,46 @@ enable_cmake-utils_src_configure() {
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 # Pr= epare Gentoo override rules (set valid compiler, append CPPFLAGS etc.)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 local build_rules=3D${BUILD_DIR}/gentoo_rules.cmake
+
+ =C2=A0 =C2=A0 =C2=A0 local _CMAKE_C_COMPILER=3D$= (_cmake-utils_get_first_word_executable CC)
+ =C2=A0 =C2=A0 =C2=A0 local _CCORPHANS=3D$(_cmake-= utils_get_subsequent_words CC)
+ =C2=A0 =C2=A0 =C2=A0 local _CM= AKE_C_COMPILER_ARG1_COMMAND=3D
+ =C2=A0 =C2=A0 =C2=A0 local _CMAKE_CXX_COMPILER=3D$(_cmake-util= s_get_first_word_executable CXX)
+ =C2=A0 =C2=A0 =C2=A0 local _CX= XORPHANS=3D$(_cmake-utils_get_subsequent_words CXX)
+ =C2=A0 =C2=A0 =C2=A0 local _CMAKE_CXX_COM= PILER_ARG1_COMMAND=3D
+
+ =C2=A0 =C2=A0 =C2=A0 # This seems fairly redicul= ous to me, but if C{,XX}ORPHANS is nonempty, then, in order to prevent
+ =C2=A0 =C2=A0 =C2=A0 #= duplication of the first argument, we must handle the first word specially=
+ =C2=A0 =C2=A0 =C2=A0 if [[ ${_= CCORPHANS} ]] ; then
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 _CMAKE_C_COMPILER_ARG1_= COMMAND=3D"SET (CMAKE_C_COMPILER_ARG1 $(_cmake-utils_first_word_of &qu= ot;${_CCORPHANS}") CACHE STRING \"C compiler first argument\"= ; FORCE)"
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 _CCORPHANS=3D$(_cmake-utils_subsequent_words_of "= ${_CCORPHANS}")
+ =C2=A0 =C2=A0 =C2=A0 fi
+ =C2=A0 =C2=A0 =C2=A0 if [[ ${_CXXORPHANS} ]] ; then
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 _CMAKE_CXX_COMPILER_ARG1_COMMAND=3D"SET (CMAKE_CX= X_COMPILER_ARG1 $(_cmake-utils_first_word_of "${_CXXORPHANS}") CA= CHE STRING \"C++ compiler first argument\" FORCE)"
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 _CXXORPHANS=3D$(_cmake-utils_subsequent_words_of "= ;${_CXXORPHANS}")
+ =C2=A0 =C2=A0 =C2=A0 fi
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 cat = > "${build_rules}" <<- _EOF_
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 SET (CMAKE_AR $(type -P $(tc-getAR)) CACHE FILEPATH "Archive manag= er" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_ASM_COMPILE_OBJECT "<CMAKE_C_COMPIL= ER> <DEFINES> ${CFLAGS} <FLAGS> -o <OBJECT> -c <SOU= RCE>" CACHE STRING "ASM compile command" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_COMPILER $(type -P $(tc-getCC)) CACHE FIL= EPATH "C compiler" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SET (CMA= KE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> ${CPPFLA= GS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING &q= uot;C compile command" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_COMPILER $(type -P $(tc-getCXX)) CACHE = FILEPATH "C++ compiler" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SET= (CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES>= ${CPPFLAGS} <FLAGS> -o <OBJECT> -c <SOURCE>" CACHE = STRING "C++ compile command" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_RANLIB $(type -P $(tc-getRANLIB)) CACHE FIL= EPATH "Archive index generator" FORCE)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 SET (PKG_CONFIG_EXECUTABLE $(type -P $(tc-getPKG_CONFIG)) CACHE FILE= PATH "pkg-config executable" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_COMPILER "${_CMAKE_C_COMPILER}"= CACHE FILEPATH "C compiler" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 ${_CMAKE_C_COMPILER_ARG1_COMMAND}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_COMPILER "${_CMAKE_CXX_COMPILER}&q= uot; CACHE FILEPATH "C++ compiler" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 ${_CMAKE_CXX_COMPILER_ARG1_COMMAND}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_AR "$(_cmake-utils_get_first_word_exec= utable AR)" CACHE FILEPATH "Archive manager" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_RANLIB "$(_cmake-utils_get_first_w= ord_executable RANLIB)" CACHE FILEPATH "Archive index generator&q= uot; FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_ASM_COMPILE_OBJECT "<CMAKE_C_COMPIL= ER> ${_CCORPHANS}${_CCORPHANS:+ }<DEFINES> ${CFLAGS}${CFLAGS:+ }&l= t;FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "AS= M compile command" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER= > ${_CCORPHANS}${_CCORPHANS:+ }<DEFINES> ${CFLAGS}${CFLAGS:+ }<= FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING "C co= mpile command" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMP= ILER> ${_CXXORPHANS}${_CXXORPHANS:+ }<DEFINES> ${CXXFLAGS}${CXXFLA= GS:+ }<FLAGS> -o <OBJECT> -c <SOURCE>" CACHE STRING = "C++ compile command" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILE= R> ${_CCORPHANS}${_CCORPHANS:+ }<FLAGS> ${LDFLAGS}${LDFLAGS:+ }<= ;CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET>= ; <LINK_LIBRARIES>" CACHE STRING "C link command for execut= ables" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_C= OMPILER> ${_CCORPHANS}${_CCORPHANS:+ }<CMAKE_SHARED_LIBRARY_C_FLAGS&g= t; <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${LDFLAGS}${LDFLAGS:+ = }<CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAM= E_C_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LIN= K_LIBRARIES>" CACHE STRING "C shared library link command"= ; FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_C_CREATE_SHARED_MODULE "\${CMAKE_C_CRE= ATE_SHARED_LIBRARY}" CACHE STRING "C shared module link command&q= uot; FORCE)
+ =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_LINK_EXECUTABLE &= quot;<CMAKE_CXX_COMPILER> ${_CXXORPHANS}${_CXXORPHANS:+ }<FLAGS>= ; ${LDFLAGS}${LDFLAGS:+ }<CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> &l= t;OBJECTS> -o <TARGET> <LINK_LIBRARIES>" CACHE STRING &= quot;C++ link command for executables" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_C= XX_COMPILER> ${_CXXORPHANS}${_CXXORPHANS:+ }<CMAKE_SHARED_LIBRARY_CXX= _FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${LDFLAGS}${LD= FLAGS:+ }<CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIB= RARY_SONAME_CXX_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS= > <LINK_LIBRARIES>" CACHE STRING "C++ shared library lin= k command" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 SET (CMAKE_CXX_CREATE_SHARED_MODULE "\${CMAKE_CXX= _CREATE_SHARED_LIBRARY}" CACHE STRING "C++ shared module link com= mand" FORCE)
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 SET (PKG_CONFIG_EXECUTABLE "$(_cmake-utils_get_first_wor= d_executable PKG_CONFIG)" CACHE FILEPATH "pkg-config executable&q= uot; FORCE)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 _EOF_
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 has "${EAPI:= -0}" 0 1 2 && ! use prefix && EPREFIX=3D
<= /div>

Perhaps a straw-man argument, since, the above co= de could be made more beautiful, and then it would not be so ugly :P
<= div>
But, it's not just that cmake can't properly han= dle a C{C,XX} variables with spaces in them**. There are a bunch of similar= places where we had to patch Makefiles and autotools to wedge GCC=3D"= foo bar" support in.

Without hyperbole, I can honestly say, it's a lame = and inelegant hack to put an /argument/ into GCC. =C2=A0-m${foo} is a CFLAG= , not a compiler. =C2=A0"Everyone" knows GCC is a variable that n= ames an executable -- but in multilib-build, for some god-awful reason, we&= #39;ve made it into some other thing, a hybrid-psuedo-thing that really onl= y makes sense in a shell script, and even then, only in an improperly coded= shell script :).

Even if that rubicon was already crossed by ccache, dis= tcc, etc, there is a reason none of them /require/ it. =C2=A0It's just = asking for trouble. =C2=A0We'll just keep wasting time fixing subtle bu= gs like the above, because of it until we break down and fix it. =C2=A0I= 9;d lay pretty long odds that five years from now we are still clinging to = it, should we decide to stick with the status quo for now. =C2=A0So why not= bite the bullet and save ourselves the hassle?

-gmt

* perhap= s today the problem is mitigated, due to the same gcc-${pseudo-CHOST} execu= tables now existing for upstream multilib-build pseudo-targets -- but, I= 9;ll bet, not solved. =C2=A0Usually trouble only crops up for larger framew= ork builds with lots of sub-dirs, like qt or mysql-server, and manifests as= incorrect attempts to link native libraries in -- which the compiler might= or might not manage to save you from at the last moment... =C2=A0also note= that patch is mocked up for easy reading -- it won't apply. =C2=A0See = my overlay for the real code. =C2=A0Finally, sorry for the HTML -- =C2=A0I&= #39;m writing from the gmail ajax which obstinately refuses to allow plain-= text inline patches.

** IIRC, it would be more precise to say somethin= g like "cmake's in-built hacks for the CC=3D'exectutable argum= ent' circumstance are subtly incompatible with our means of injecting t= he portage compiler values into cmake (or so things used to be; I suspect t= he problem still lurks to some extent), and that this ultimately manifests = as confusing, intermittent build failures and correctly issued QA warnings = in larger multilib-build-based ebuilds (or will in the near future; I actua= lly wouldn't know as I run with the above patches :P), esp. in cases wh= ere a ${CC}-${CHOST} or ${CXX}-${CHOST} executables are to be found in ${PA= TH}." =C2=A0But if any unlucky person is still reading, they can see f= ully why I didn't bother to say all that :P
--20cf302efab0f99ecb04fc561c58--