[powerpc64le] Use the target 'objcopy' when cross-compiling.

Message ID 20210707155547.15277-1-ludo@gnu.org
State Rejected
Headers
Series [powerpc64le] Use the target 'objcopy' when cross-compiling. |

Checks

Context Check Description
dj/TryBot-apply_patch fail Patch failed to apply to master at the time it was sent
dj/TryBot-32bit fail Patch series failed to apply

Commit Message

Ludovic Courtès July 7, 2021, 3:55 p.m. UTC
  When cross-compiling to powerpc64le-linux-gnu,
sysdeps/powerpc/powerpc64/le/Makefile would use "objcopy", leading to
errors like:

  objcopy: Unable to recognise the format of the input file `…/no_ldbl_gnu_attribute.o'

This patch changes 'configure.ac' to use AC_CHECK_TOOL rather than
'$CC -print-prog-name=objcopy' to determine the value of the OBJCOPY
variable.  That way, OBJCOPY is set to TRIPLET-objcopy when
cross-compiling for TRIPLET.
---
 aclocal.m4   |  2 --
 configure    | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 configure.ac |  1 +
 3 files changed, 94 insertions(+), 5 deletions(-)

The issue was initially reported at:

  https://issues.guix.gnu.org/49417

It is a followup to a similar patch I sent regarding objdump:

  https://sourceware.org/pipermail/libc-alpha/2021-July/128333.html

Thanks,
Ludo’.
  

Comments

Florian Weimer July 7, 2021, 4:06 p.m. UTC | #1
* Ludovic Courtès via Libc-alpha:

> When cross-compiling to powerpc64le-linux-gnu,
> sysdeps/powerpc/powerpc64/le/Makefile would use "objcopy", leading to
> errors like:
>
>   objcopy: Unable to recognise the format of the input file `…/no_ldbl_gnu_attribute.o'
>
> This patch changes 'configure.ac' to use AC_CHECK_TOOL rather than
> '$CC -print-prog-name=objcopy' to determine the value of the OBJCOPY
> variable.  That way, OBJCOPY is set to TRIPLET-objcopy when
> cross-compiling for TRIPLET.

Hmm.  Why doesn't '$CC -print-prog-name=objcopy' result in the right
command name?

Thanks,
Florian
  
Ludovic Courtès July 7, 2021, 10:05 p.m. UTC | #2
Hi,

Florian Weimer <fweimer@redhat.com> skribis:

> * Ludovic Courtès via Libc-alpha:
>
>> When cross-compiling to powerpc64le-linux-gnu,
>> sysdeps/powerpc/powerpc64/le/Makefile would use "objcopy", leading to
>> errors like:
>>
>>   objcopy: Unable to recognise the format of the input file `…/no_ldbl_gnu_attribute.o'
>>
>> This patch changes 'configure.ac' to use AC_CHECK_TOOL rather than
>> '$CC -print-prog-name=objcopy' to determine the value of the OBJCOPY
>> variable.  That way, OBJCOPY is set to TRIPLET-objcopy when
>> cross-compiling for TRIPLET.
>
> Hmm.  Why doesn't '$CC -print-prog-name=objcopy' result in the right
> command name?

Is it supposed to?  Looking at gcc/gcc.c:find_a_file, I’m not sure.
For me it prints ‘objcopy’, and when I run:

  strace aarch64-linux-gnu-gcc -print-prog-name=objcopy

… I only see it look for ‘objcopy’, not ‘aarch64-linux-gnu-objcopy’.

Could it be a packaging issue?

Thanks,
Ludo’.
  
H.J. Lu July 8, 2021, 12:07 a.m. UTC | #3
On Wed, Jul 7, 2021 at 3:06 PM Ludovic Courtès via Libc-alpha
<libc-alpha@sourceware.org> wrote:
>
> Hi,
>
> Florian Weimer <fweimer@redhat.com> skribis:
>
> > * Ludovic Courtès via Libc-alpha:
> >
> >> When cross-compiling to powerpc64le-linux-gnu,
> >> sysdeps/powerpc/powerpc64/le/Makefile would use "objcopy", leading to
> >> errors like:
> >>
> >>   objcopy: Unable to recognise the format of the input file `…/no_ldbl_gnu_attribute.o'
> >>
> >> This patch changes 'configure.ac' to use AC_CHECK_TOOL rather than
> >> '$CC -print-prog-name=objcopy' to determine the value of the OBJCOPY
> >> variable.  That way, OBJCOPY is set to TRIPLET-objcopy when
> >> cross-compiling for TRIPLET.
> >
> > Hmm.  Why doesn't '$CC -print-prog-name=objcopy' result in the right
> > command name?
>
> Is it supposed to?  Looking at gcc/gcc.c:find_a_file, I’m not sure.
> For me it prints ‘objcopy’, and when I run:
>
>   strace aarch64-linux-gnu-gcc -print-prog-name=objcopy
>
> … I only see it look for ‘objcopy’, not ‘aarch64-linux-gnu-objcopy’.
>
> Could it be a packaging issue?

Your cross compiler isn't built properly.   Glibc scripts/build-many-glibcs.py
can build proper cross compilers.
  
Joseph Myers July 8, 2021, 4:49 p.m. UTC | #4
On Thu, 8 Jul 2021, Ludovic Courtès via Libc-alpha wrote:

> > Hmm.  Why doesn't '$CC -print-prog-name=objcopy' result in the right
> > command name?
> 
> Is it supposed to?  Looking at gcc/gcc.c:find_a_file, I’m not sure.
> For me it prints ‘objcopy’, and when I run:
> 
>   strace aarch64-linux-gnu-gcc -print-prog-name=objcopy
> 
> … I only see it look for ‘objcopy’, not ‘aarch64-linux-gnu-objcopy’.

I'd expect it to look for objcopy in $exec_prefix/$target/bin (binutils 
installs it as objcopy in that directory and as $target-objcopy in 
$exec_prefix/bin, see TOOL_PROGS in binutils/Makefile.am).  (That path may 
well in turn be computed via GCC's libexecsubdir, I see output such as 
/scratch/jmyers/glibc-bot/install/compilers/aarch64-linux-gnu/lib/gcc/aarch64-glibc-linux-gnu/12.0.0/../../../../aarch64-glibc-linux-gnu/bin/objcopy.)

I'd expect the code to work both before and after the patch.  If there is 
some advantage to the change proposed in the patch, it would be a good 
idea for the commit message to explain in more detail the circumstances 
when the objcopy in $exec_prefix/$target/bin isn't found.
  
Ludovic Courtès July 9, 2021, 2:02 p.m. UTC | #5
Hi Joseph,

Joseph Myers <joseph@codesourcery.com> skribis:

> On Thu, 8 Jul 2021, Ludovic Courtès via Libc-alpha wrote:
>
>> > Hmm.  Why doesn't '$CC -print-prog-name=objcopy' result in the right
>> > command name?
>> 
>> Is it supposed to?  Looking at gcc/gcc.c:find_a_file, I’m not sure.
>> For me it prints ‘objcopy’, and when I run:
>> 
>>   strace aarch64-linux-gnu-gcc -print-prog-name=objcopy
>> 
>> … I only see it look for ‘objcopy’, not ‘aarch64-linux-gnu-objcopy’.
>
> I'd expect it to look for objcopy in $exec_prefix/$target/bin (binutils 
> installs it as objcopy in that directory and as $target-objcopy in 
> $exec_prefix/bin, see TOOL_PROGS in binutils/Makefile.am).  (That path may 
> well in turn be computed via GCC's libexecsubdir, I see output such as 
> /scratch/jmyers/glibc-bot/install/compilers/aarch64-linux-gnu/lib/gcc/aarch64-glibc-linux-gnu/12.0.0/../../../../aarch64-glibc-linux-gnu/bin/objcopy.)

Oh, got it.  That only works when GCC and Binutils are installed in the
same prefix, then.

In Guix, each package is installed in its own prefix.  The cross
Binutils has $exec_prefix/$target/bin as you write:

--8<---------------cut here---------------start------------->8---
$ find /gnu/store/aj1zbw51fvngxrl1r2g6xcxfnlkshr82-binutils-cross-aarch64-linux-gnu-2.34/ -name objdump
/gnu/store/aj1zbw51fvngxrl1r2g6xcxfnlkshr82-binutils-cross-aarch64-linux-gnu-2.34/aarch64-linux-gnu/bin/objdump
--8<---------------cut here---------------end--------------->8---

… but GCC is instead looking for it in its own prefix:

--8<---------------cut here---------------start------------->8---
$ strace -e stat aarch64-linux-gnu-gcc -print-prog-name=objdump
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/tls/haswell/x86_64", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/tls/haswell", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/tls/x86_64", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/tls", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/haswell/x86_64", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/haswell", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/fa6wj5bxkj5ll1d7292a70knmyl7a0cr-glibc-2.31/lib/x86_64", 0x7ffc8fcfb630) = -1 ENOENT (No such file or directory)
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/bin/aarch64-linux-gnu-gcc", {st_mode=S_IFREG|0555, st_size=997752, ...}) = 0
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/bin/aarch64-linux-gnu-gcc", {st_mode=S_IFREG|0555, st_size=997752, ...}) = 0
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/libexec/gcc/aarch64-linux-gnu/7.5.0/lto-wrapper", {st_mode=S_IFREG|0555, st_size=909104, ...}) = 0
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/libexec/gcc/aarch64-linux-gnu/7.5.0/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/libexec/gcc/aarch64-linux-gnu/7.5.0/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/1m16gz0q4v4j10k52i5q641sz6lvdwha-gcc-cross-aarch64-linux-gnu-7.5.0/libexec/gcc/aarch64-linux-gnu/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/029zph27cyn3wvbxmlqh2xqrnk3h3323-gcc-cross-aarch64-linux-gnu-7.5.0-lib/lib/gcc/aarch64-linux-gnu/7.5.0/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/029zph27cyn3wvbxmlqh2xqrnk3h3323-gcc-cross-aarch64-linux-gnu-7.5.0-lib/lib/gcc/aarch64-linux-gnu/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/029zph27cyn3wvbxmlqh2xqrnk3h3323-gcc-cross-aarch64-linux-gnu-7.5.0-lib/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/7.5.0/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
stat("/gnu/store/029zph27cyn3wvbxmlqh2xqrnk3h3323-gcc-cross-aarch64-linux-gnu-7.5.0-lib/lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/objdump", 0x7ffc8fcfc110) = -1 ENOENT (No such file or directory)
objdump
+++ exited with 0 +++
--8<---------------cut here---------------end--------------->8---

… which fails.

> I'd expect the code to work both before and after the patch.  If there is 
> some advantage to the change proposed in the patch, it would be a good 
> idea for the commit message to explain in more detail the circumstances 
> when the objcopy in $exec_prefix/$target/bin isn't found.

I reworded the commit log of the two patches (attached).

Let me know what you think.

Thanks,
Ludo’.
  

Patch

diff --git a/aclocal.m4 b/aclocal.m4
index 13a791ffde..5b370c07a2 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -118,8 +118,6 @@  AS=`$CC -print-prog-name=as`
 LD=`$CC -print-prog-name=ld`
 AR=`$CC -print-prog-name=ar`
 AC_SUBST(AR)
-OBJCOPY=`$CC -print-prog-name=objcopy`
-AC_SUBST(OBJCOPY)
 GPROF=`$CC -print-prog-name=gprof`
 AC_SUBST(GPROF)
 
diff --git a/configure b/configure
index fe0eda1cd5..3a08270734 100755
--- a/configure
+++ b/configure
@@ -654,7 +654,6 @@  MAKE
 LD
 AS
 GPROF
-OBJCOPY
 AR
 LN_S
 INSTALL_DATA
@@ -689,6 +688,7 @@  sysheaders
 ac_ct_CXX
 CXXFLAGS
 CXX
+OBJCOPY
 OBJDUMP
 READELF
 CPP
@@ -3054,6 +3054,98 @@  else
   OBJDUMP="$ac_cv_prog_OBJDUMP"
 fi
 
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objcopy; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_OBJCOPY+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJCOPY"; then
+  ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJCOPY=$ac_cv_prog_OBJCOPY
+if test -n "$OBJCOPY"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCOPY" >&5
+$as_echo "$OBJCOPY" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJCOPY"; then
+  ac_ct_OBJCOPY=$OBJCOPY
+  # Extract the first word of "objcopy", so it can be a program name with args.
+set dummy objcopy; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJCOPY"; then
+  ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJCOPY="objcopy"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY
+if test -n "$ac_ct_OBJCOPY"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY" >&5
+$as_echo "$ac_ct_OBJCOPY" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJCOPY" = x; then
+    OBJCOPY="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJCOPY=$ac_ct_OBJCOPY
+  fi
+else
+  OBJCOPY="$ac_cv_prog_OBJCOPY"
+fi
+
 
 # We need the C++ compiler only for testing.
 ac_ext=cpp
@@ -4645,8 +4737,6 @@  AS=`$CC -print-prog-name=as`
 LD=`$CC -print-prog-name=ld`
 AR=`$CC -print-prog-name=ar`
 
-OBJCOPY=`$CC -print-prog-name=objcopy`
-
 GPROF=`$CC -print-prog-name=gprof`
 
 
diff --git a/configure.ac b/configure.ac
index 924af12738..2148cd2ec8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@  AC_SUBST(cross_compiling)
 AC_PROG_CPP
 AC_CHECK_TOOL(READELF, readelf, false)
 AC_CHECK_TOOL(OBJDUMP, objdump, false)
+AC_CHECK_TOOL(OBJCOPY, objcopy, false)
 
 # We need the C++ compiler only for testing.
 AC_PROG_CXX