Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 698912 - toolchain-funcs.eclass: tc-cpp-is-true: always returns false when building with clang
Summary: toolchain-funcs.eclass: tc-cpp-is-true: always returns false when building wi...
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Toolchain Maintainers
URL:
Whiteboard:
Keywords: PullRequest
Depends on:
Blocks:
 
Reported: 2019-10-30 10:25 UTC by Mattias Nissler
Modified: 2019-11-06 22:44 UTC (History)
1 user (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 Mattias Nissler 2019-10-30 10:25:38 UTC
tc-cpp-is-true doesn't work correctly when building with clang. This leads to problems when ebuilds get the wrong result, in my case I'm seeing a build failure in dev-python/m2crypto-0.31.0-r2 when cross-compiling for ARM with clang. That setup takes effort to reproduce though, so I'll spare you the details but provide an artificial repro:

# CC=/usr/lib/llvm/8/bin/clang bash -x -c '. eclass/toolchain-funcs.eclass; tc-cpp-is-true "defined(__FILE__)"; echo $?'
+ . eclass/toolchain-funcs.eclass
++ [[ -z '' ]]
++ _TOOLCHAIN_FUNCS_ECLASS=1
++ inherit multilib
eclass/toolchain-funcs.eclass: line 18: inherit: command not found
+ tc-cpp-is-true 'defined(__FILE__)'
+ local 'CONDITION=defined(__FILE__)'
+ shift
+++ tc-getTARGET_CPP
+++ [[ -n '' ]]
+++ tc-getCPP
+++ tc-getPROG CPP '/usr/lib/llvm/8/bin/clang -E'
+++ _tc-getPROG CHOST CPP '/usr/lib/llvm/8/bin/clang -E'
+++ local tuple=CHOST
+++ local v var vars=CPP
+++ prog=($3)
+++ local prog
+++ var=CPP
+++ for v in ${vars}
+++ [[ -n '' ]]
+++ local search=
+++ [[ -n '' ]]
+++ [[ -z '' ]]
+++ [[ -n '' ]]
+++ [[ -n '' ]]
+++ export 'CPP=/usr/lib/llvm/8/bin/clang -E'
+++ CPP='/usr/lib/llvm/8/bin/clang -E'
+++ echo '/usr/lib/llvm/8/bin/clang -E'
++ /usr/lib/llvm/8/bin/clang -E -P -
+ local 'RESULT=
true'
+ [[ 
true == true ]]
+ echo 1
1

Note the newline in the RESULT variable which ultimately leads to the wrong result. Here's the difference in behavior between gcc and clang:

# echo -e "#ifdef __FILE__\ntrue\n#endif" | gcc -E -P - 
true

# echo -e "#ifdef __FILE__\ntrue\n#endif" | /usr/lib/llvm/8/bin/clang -E -P - 

true

Reproducible: Always

Steps to Reproduce:
CC=/usr/lib/llvm/8/bin/clang bash -x -c '. eclass/toolchain-funcs.eclass; tc-cpp-is-true "defined(__FILE__)"; echo $?'
Actual Results:  
Last line of the output is 1.

Expected Results:  
Should print 0 in the last line since __FILE__ is always defined.
Comment 1 Mattias Nissler 2019-10-30 12:53:38 UTC
Proposed fix: https://github.com/gentoo/gentoo/pull/13497
Comment 2 Sergei Trofimovich (RETIRED) gentoo-dev 2019-10-30 19:50:16 UTC
Yeah, I agree it's a bug.

Reliance on whitespace has always been the problem of these macros.

It works even worse when you pass something like -ggdb3 as part of CC:
    $ echo -e "#ifdef __FILE__\ntrue\n#endif" | gcc -ggdb3 -E -P -
    ...
    #define __STDC_IEC_559_COMPLEX__ 1
    #define __STDC_ISO_10646__ 201706L
    true

Arguably it should almost never happen but in practice it's convenient sometimes. I wounder if it would be better to rely on exit code of preprocessor itself and inject the error there. Something like:

$ clang -ggdb3 -E -P - <<< $(echo -e "#ifdef __FILE1__\ntrue\n#else\n#error Nooooooo\n#endif") >/dev/null 2>&1 && echo ok
$ clang -ggdb3 -E -P - <<< $(echo -e "#ifdef __FILE__\ntrue\n#else\n#error Nooooooo\n#endif") >/dev/null 2>&1 && echo ok
ok
Comment 3 Sergei Trofimovich (RETIRED) gentoo-dev 2019-10-30 19:55:06 UTC
Also, we used to grep for ^true$ to avoid the case of -ggdb3:
    https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=f3f183dd42463b42d1aac27debb04c75c616dae7
Comment 4 Mattias Nissler 2019-11-04 10:14:14 UTC
Updated the fix to use preprocessor exit status as suggested on the pull request: https://github.com/gentoo/gentoo/commit/2ff07a14c230f2e225bc605e9d93e6031e169a34
Comment 5 Larry the Git Cow gentoo-dev 2019-11-06 22:44:40 UTC
The bug has been closed via the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8f02136721af40dd89a09101504750fb28f8142e

commit 8f02136721af40dd89a09101504750fb28f8142e
Author:     Sergei Trofimovich <slyfox@gentoo.org>
AuthorDate: 2019-11-06 22:40:18 +0000
Commit:     Sergei Trofimovich <slyfox@gentoo.org>
CommitDate: 2019-11-06 22:44:34 +0000

    eclass/tests/toolchain-funcs.sh add test for 'tc-cpp-is-true()'
    
    With patch from bug #698912 reverted we observe failures as:
     * Testing tc-cpp-is-true (gcc, defined) ...              [ ok ]
     * Testing tc-cpp-is-true (gcc, not defined) ...          [ ok ]
     * Testing tc-cpp-is-true (gcc, defined on -ggdb3) ...    [ !! ]
     * Testing tc-cpp-is-true (clang, defined) ...            [ !! ]
     * Testing tc-cpp-is-true (clang, not defined) ...        [ ok ]
     * Testing tc-cpp-is-true (clang, defined on -ggdb3) ...  [ !! ]
    
    Closes: https://bugs.gentoo.org/698912
    Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>

 eclass/tests/toolchain-funcs.sh | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

Additionally, it has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3ef6b33339da7bb04afd77e1bc5db011b02d658a

commit 3ef6b33339da7bb04afd77e1bc5db011b02d658a
Author:     Mattias Nissler <mnissler@chromium.org>
AuthorDate: 2019-11-04 10:11:20 +0000
Commit:     Sergei Trofimovich <slyfox@gentoo.org>
CommitDate: 2019-11-06 22:44:33 +0000

    toolchain-funcs.eclass: fix tc-cpp-is-true() to work with clang
    
    Clang's preprocessor likes to output a leading newline, which makes
    the comparison always fail. GCC generates additional output with certain
    flags (e.g. -ggdb3) as well. Hence, switch the test to trigger a
    preprocessor error when the condition is not true and examine the exit
    code.
    
    Bug: https://bugs.gentoo.org/698912
    
    Signed-off-by: Mattias Nissler <mnissler@chromium.org>
    Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>

 eclass/toolchain-funcs.eclass | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)