flag-o-matic.eclass: add LDFLAGS testing against linker
authorSergei Trofimovich <slyfox@gentoo.org>
Mon, 23 Dec 2019 11:41:20 +0000 (11:41 +0000)
committerSergei Trofimovich <slyfox@gentoo.org>
Tue, 24 Dec 2019 11:01:01 +0000 (11:01 +0000)
Before the change we tested only compiler driver (gcc flag parser)
for LDFLAGS.

This does not cover cases when we would really like to filter out
unsupported linker flags like -Wl,--hash-style=gnu passed to non-ELF
targets.

The change adds test-flag-CCLD() helper to perform all of assembly,
compilation and linking steps. Helper is used to filter LDFLAGS variable
in strip-unsupported-flags().

Closes: https://bugs.gentoo.org/333763
Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org>
eclass/flag-o-matic.eclass
eclass/tests/flag-o-matic.sh

index f882b09d6219ed2cd104ce781ed67f1b7d1608e8..0aec22c83f2c02b245a9faaa5daec3ddc7a2719e 100644 (file)
@@ -441,29 +441,63 @@ test-flag-PROG() {
        # 'type' needs a binary name
        type -p ${comp[0]} >/dev/null || return 1
 
+       # Set up test file.
+       local in_src in_ext cmdline_extra=()
+       case "${lang}" in
+               # compiler/assembler only
+               c)
+                       in_ext='.c'
+                       in_src='int main(void) { return 0; }'
+                       cmdline_extra+=(-xc -c)
+                       ;;
+               c++)
+                       in_ext='.cc'
+                       in_src='int main(void) { return 0; }'
+                       cmdline_extra+=(-xc++ -c)
+                       ;;
+               f77)
+                       in_ext='.f'
+                       # fixed source form
+                       in_src='      end'
+                       cmdline_extra+=(-xf77 -c)
+                       ;;
+               f95)
+                       in_ext='.f90'
+                       in_src='end'
+                       cmdline_extra+=(-xf95 -c)
+                       ;;
+
+               # C compiler/assembler/linker
+               c+ld)
+                       in_ext='.c'
+                       in_src='int main(void) { return 0; }'
+                       cmdline_extra+=(-xc)
+                       ;;
+       esac
+       local test_in=${T}/test-flag-${comp}.${lang}
+       local test_out=${T}/test-flag-${comp}.exe
+
+       printf "%s\n" "${in_src}" > "${test_in}" || return 1
+
        local cmdline=(
                "${comp[@]}"
                # Clang will warn about unknown gcc flags but exit 0.
                # Need -Werror to force it to exit non-zero.
                -Werror
-               # Use -c so we can test the assembler as well.
-               -c -o /dev/null
+               "$@"
+               # -x<lang> options need to go before first source file
+               "${cmdline_extra[@]}"
+
+               "${test_in}" -o "${test_out}"
        )
-       if "${cmdline[@]}" -x${lang} - </dev/null &>/dev/null ; then
-               cmdline+=( "$@" -x${lang} - )
-       else
-               # XXX: what's the purpose of this? does it even work with
-               # any compiler?
-               cmdline+=( "$@" -c -o /dev/null /dev/null )
-       fi
 
-       if ! "${cmdline[@]}" </dev/null &>/dev/null; then
+       if ! "${cmdline[@]}" &>/dev/null; then
                # -Werror makes clang bail out on unused arguments as well;
                # try to add -Qunused-arguments to work-around that
                # other compilers don't support it but then, it's failure like
                # any other
                cmdline+=( -Qunused-arguments )
-               "${cmdline[@]}" </dev/null &>/dev/null
+               "${cmdline[@]}" &>/dev/null
        fi
 }
 
@@ -491,6 +525,12 @@ test-flag-F77() { test-flag-PROG "F77" f77 "$@"; }
 # Returns shell true if <flag> is supported by the Fortran 90 compiler, else returns shell false.
 test-flag-FC() { test-flag-PROG "FC" f95 "$@"; }
 
+# @FUNCTION: test-flag-CCLD
+# @USAGE: <flag>
+# @DESCRIPTION:
+# Returns shell true if <flag> is supported by the C compiler and linker, else returns shell false.
+test-flag-CCLD() { test-flag-PROG "CC" c+ld "$@"; }
+
 test-flags-PROG() {
        local comp=$1
        local flags=()
@@ -548,6 +588,12 @@ test-flags-F77() { test-flags-PROG "F77" "$@"; }
 # Returns shell true if <flags> are supported by the Fortran 90 compiler, else returns shell false.
 test-flags-FC() { test-flags-PROG "FC" "$@"; }
 
+# @FUNCTION: test-flags-CCLD
+# @USAGE: <flags>
+# @DESCRIPTION:
+# Returns shell true if <flags> are supported by the C compiler and default linker, else returns shell false.
+test-flags-CCLD() { test-flags-PROG "CCLD" "$@"; }
+
 # @FUNCTION: test-flags
 # @USAGE: <flags>
 # @DESCRIPTION:
@@ -576,9 +622,7 @@ strip-unsupported-flags() {
        export CXXFLAGS=$(test-flags-CXX ${CXXFLAGS})
        export FFLAGS=$(test-flags-F77 ${FFLAGS})
        export FCFLAGS=$(test-flags-FC ${FCFLAGS})
-       # note: this does not verify the linker flags but it is enough
-       # to strip invalid C flags which are much more likely, #621274
-       export LDFLAGS=$(test-flags-CC ${LDFLAGS})
+       export LDFLAGS=$(test-flags-CCLD ${LDFLAGS})
 }
 
 # @FUNCTION: get-flag
index 7c078499d70cfe53f1a8b34b0233af87054921a7..90eaf3a6ffb08a05b8a78571055cfea59f049942 100755 (executable)
@@ -8,7 +8,7 @@ inherit flag-o-matic
 
 CFLAGS="-a -b -c=1 --param l1-cache-size=32"
 CXXFLAGS="-x -y -z=2"
-LDFLAGS="-l -m -n=3"
+LDFLAGS="-l -m -n=3 -Wl,--remove-me"
 ftend() {
        local ret=$?
        local msg="Failed; flags are:"