package/Makefile.in: append endianness argument to TARGET_LD for MIPS
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
We don't use a wrapper for ld in Buildroot like we do for gcc, so when using ld for linking (instead of gcc) the process can fail if the appropriate arguments are not passed to it. For instance, this happens when building perf (Linux -> Linux Kernel Tools -> perf) for MIPS little endian, and this is how the error message looks like:
LD /br/output/build/perf-custom/fd/libapi-in.o
/br/output/host/usr/bin/mips-linux-gnu-ld:
/br/output/build/perf-custom/fd/array.o: compiled for a little endian system and target is big endian
In this case the linker is called without passing any argument to indicate the endianness, so the default one is used, which is big endian and therefore the process fails because the object files were built for little endian instead.
This patch doesn't fix the problem in perf. It just appends the right endianness argument (-EL or -EB) to the TARGET_LD variable when building for MIPS architecture.
--- package/Makefile.in | 13 +++++++++++++ 1 file changed, 13 insertions(+)
package/Makefile.in +13 -0
@@ -190,6 +190,19 @@ TARGET_READELF = $(TARGET_CROSS)readelf TARGET_OBJCOPY = $(TARGET_CROSS)objcopy TARGET_OBJDUMP = $(TARGET_CROSS)objdump +# Append the endianness argument to ld for MIPS architecture in order to +# avoid problems like this one when using ld instead of gcc for linking: +# mips-linux-gnu-ld: failed to merge target specific data of file foo.o +# mips-linux-gnu-ld: foo.o: compiled for a little endian system and +# target is big endian +ifeq ($(BR2_mips)$(BR2_mipsel)$(BR2_mips64)$(BR2_mips64el),y) +ifeq ($(BR2_ENDIAN),"BIG") +TARGET_LD += -EB +else +TARGET_LD += -EL +endif +endif + ifeq ($(BR2_STRIP_strip),y) STRIP_STRIP_DEBUG := --strip-debug STRIP_STRIP_UNNEEDED := --strip-unneeded
Signature · 1 line
2.4.10
PATCH 2/2 linux/linux.mk: add LD="$(TARGET_LD)" to LINUX_MAKE_FLAGS
Some Linux tools like perf use ld for linking instead of gcc, and that may cause problems on certain architectures (MIPS, for instance) since we don't use a wrapper for ld as we do for gcc and the call to the linker may lack some necessary arguments (which would be included if we were using a wrapper). The problem is explained in detail below.
perf defines the value of LD on its Makefile by doing this:
$(call allow-override,LD,$(CROSS_COMPILE)ld)
So, if we don't pass an LD variable to override its value it will set the value using the content of the CROSS_COMPILE variable and the result will be something like <arch>-linux-gnu-ld.
This works fine for all architectures (because the value will be the same as the TARGET_LD variable) except for MIPS, because the value of TARGET_LD when building for MIPS also contains the argument to set the endianness.
Due to that, perf will fail to build for MIPS little endian because the linker (ld) will not receive any argument to set the endianness and the default one (-EB for big endian) will be used instead. The error looks like this:
LD /br/output/build/perf-custom/fd/libapi-in.o
/br/output/host/usr/bin/mips-linux-gnu-ld:
/br/output/build/perf-custom/fd/array.o: compiled for a little endian system and target is big endian
So in order to make sure that perf will call the linker as we want (using the value of the TARGET_LD variable), we define an LD variable which value is the same as TARGET_LD, and we add that variable to the LINUX_MAKE_FLAGS one. Then, since the linux-tool-perf.mk file uses that variable, the value of LD in the perf Makefile will be overriden with ours and the problem will be fixed.
--- linux/linux.mk | 1 + 1 file changed, 1 insertion(+)
linux/linux.mk +1 -0
@@ -79,6 +79,7 @@ LINUX_MAKE_FLAGS = \ HOSTCC="$(HOSTCC)" \ HOSTCFLAGS="$(HOSTCFLAGS)" \ ARCH=$(KERNEL_ARCH) \ + LD="$(TARGET_LD)" \ INSTALL_MOD_PATH=$(TARGET_DIR) \ CROSS_COMPILE="$(TARGET_CROSS)" \ DEPMOD=$(HOST_DIR)/sbin/depmod
Signature · 1 line
2.4.10
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
In reply to Vicente Olivert RieraDear Vicente Olivert Riera,
Quoted 35 lines · Vicente Olivert Riera
We don't use a wrapper for ld in Buildroot like we do for gcc, so when using ld for linking (instead of gcc) the process can fail if the appropriate arguments are not passed to it. For instance, this happens when building perf (Linux -> Linux Kernel Tools -> perf) for MIPS little endian, and this is how the error message looks like:
LD /br/output/build/perf-custom/fd/libapi-in.o
/br/output/host/usr/bin/mips-linux-gnu-ld:
/br/output/build/perf-custom/fd/array.o: compiled for a little endian system and target is big endianIn this case the linker is called without passing any argument to indicate the endianness, so the default one is used, which is big endian and therefore the process fails because the object files were built for little endian instead.
This patch doesn't fix the problem in perf. It just appends the right endianness argument (-EL or -EB) to the
TARGET_LDvariable when building for MIPS architecture.Signed-off-by Vicente Olivert Riera <[email protected]>--- package/Makefile.in | 13 +++++++++++++ 1 file changed, 13 insertions(+)package/Makefile.in +2
-0@@ -190,6 +190,19 @@ TARGET_READELF = $(TARGET_CROSS)readelf TARGET_OBJCOPY = $(TARGET_CROSS)objcopy TARGET_OBJDUMP = $(TARGET_CROSS)objdump +# Append the endianness argument to ld for MIPS architecture in order to +# avoid problems like this one when using ld instead of gcc for linking:
package/Makefile.in TARGET_READELF = $(TARGET_CROSS)readelf · line 204
Quoted 10 lines
package/Makefile.in +10
-0+# mips-linux-gnu-ld: failed to merge target specific data of file foo.o +# mips-linux-gnu-ld: foo.o: compiled for a little endian system and +# target is big endian +ifeq ($(BR2_mips)$(BR2_mipsel)$(BR2_mips64)$(BR2_mips64el),y) +ifeq ($(BR2_ENDIAN),"BIG") +TARGET_LD += -EB +else +TARGET_LD += -EL +endif +endif
This is really an horrible fix IMO. First because TARGET_LD is only meant to contain the path to the linker, and not additional flags. Additional flags should go in TARGET_LDFLAGS.
And secondly because programs should not use ld directly for linking, but gcc. Remember Vicente, you already fixed this issue in other packages and the fix was to use gcc instead of ld.
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
Quoted 8 lines · Thomas Petazzoni
Dear Vicente Olivert Riera,
Quoted 5 lines · Vicente Olivert Riera
We don't use a wrapper for ld in Buildroot like we do for gcc, so when using ld for linking (instead of gcc) the process can fail if the appropriate arguments are not passed to it. For instance, this happens when building perf (Linux -> Linux Kernel Tools -> perf) for MIPS little endian, and this is how the error message looks like:
[snip]
Quoted 17 lines
package/Makefile.in TARGET_READELF = $(TARGET_CROSS)readelf · line 204
Quoted 12 lines
package/Makefile.in +12
-0+# Append the endianness argument to ld for MIPS architecture in order to +# avoid problems like this one when using ld instead of gcc for linking: +# mips-linux-gnu-ld: failed to merge target specific data of file foo.o +# mips-linux-gnu-ld: foo.o: compiled for a little endian system and +# target is big endian +ifeq ($(BR2_mips)$(BR2_mipsel)$(BR2_mips64)$(BR2_mips64el),y) +ifeq ($(BR2_ENDIAN),"BIG") +TARGET_LD += -EB +else +TARGET_LD += -EL +endif +endifThis is really an horrible fix IMO. First because
TARGET_LDis only meant to contain the path to the linker, and not additional flags. Additional flags should go inTARGET_LDFLAGS.
Quoted 3 lines
And secondly because programs should not use ld directly for linking, but gcc. Remember Vicente, you already fixed this issue in other packages and the fix was to use gcc instead of ld.
So, are we really going to "fix" all packages that use ld directly? I don't see
why a package shouldn't be allowed to call ld when it is really doing linking without any other toolchainy stuff.
LDFLAGS has a bit of the same problem: there will probably be packages that
don't (completely) honour it.
For CFLAGS, that was the reason why we introduced the wrapper. So I think we
should just add a wrapper for ld as well.
Ideally the ld wrapper and the gcc wrapper should be refactored into the same
source file, but I think we could start out with separate sources and factor later.
Any takers?
Unless Vicente volunteers to work on an ld wrapper, I guess on the short term
we should take patches like these. That said, it should really be passed through LDFLAGS and not LD itself.
Regards,
Arnout
Quoted 3 lines
Thomas
Signature · 6 lines
Arnout Vandecappelle arnout at mind be Senior Embedded Software Architect +32-16-286500 Essensium/Mind http://www.mind.be G.Geenslaan 9, 3001 Leuven, Belgium BE 872 984 063 RPR Leuven LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
Arnout,
Quoted 3 lines · Arnout Vandecappelle
So, are we really going to "fix" all packages that use ld directly? I don't see
why a package shouldn't be allowed to call ld when it is really doing linking without any other toolchainy stuff.
Which isn't the case here. It's linking perf, i.e a normal userspace application.
But it might indeed be difficult to convince the kernel developers to change this, except if you have a solid argumentation.
Quoted 2 lines
LDFLAGS has a bit of the same problem: there will probably be packages that
don't (completely) honour it.
Yes, and we should fix this IMO.
Quoted 2 lines
For CFLAGS, that was the reason why we introduced the wrapper. So I think we
should just add a wrapper for ld as well.
Why not.
Quoted 3 lines
Unless Vicente volunteers to work on an ld wrapper, I guess on the short term
we should take patches like these. That said, it should really be passed through LDFLAGS and not LD itself.
And the hack be limited to those specific packages that are broken, IMO. At least until we realize how many packages are affected by this. It would be annoying to put those additional flags globally just to fix one single package.
So I would like a patch that touches only the perf build logic for now, until we see other packages in the same situation.
Thanks!
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Thomas" == Thomas Petazzoni <[email protected]> writes:
Hi,
Quoted 8 lines
Quoted 3 lines
Unless Vicente volunteers to work on an ld wrapper, I guess on the short term we should take patches like these. That said, it should really be passed through LDFLAGS and not LD itself.
And the hack be limited to those specific packages that are broken, IMO. At least until we realize how many packages are affected by this. It would be annoying to put those additional flags globally just to fix one single package.
As I understood it from Vicente on IRC:
- The endian flags are always required when linking
- The options are understood both when linking with gcc and ld
Which is why I suggested we do it globally.
Signature · 1 line
Bye, Peter Korsgaard
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
Hello Peter, Thomas and Arnout,
so, do you prefer a patch to just fix perf?
The perf Makefile doesn't read an environmental LDFLAGS variable, so adding -EL/-EB to LDFLAGS will not work.
Also, doing LD="$(TARGET_CC)" in order to use gcc for linking doesn't work either and it fails with errors about '-lgcc_s' not found.
Are you ok with doing LD="$(TARGET_LD) -EL/-EB" only when building perf for MIPS architecture?
Regards,
Vincent.
Quoted 20 lines · Peter Korsgaard
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Thomas" == Thomas Petazzoni <[email protected]> writes:
Hi,
Quoted 8 lines
Quoted 3 lines
Unless Vicente volunteers to work on an ld wrapper, I guess on the short term we should take patches like these. That said, it should really be passed through LDFLAGS and not LD itself.
And the hack be limited to those specific packages that are broken, IMO. At least until we realize how many packages are affected by this. It would be annoying to put those additional flags globally just to fix one single package.
As I understood it from Vicente on IRC:
- The endian flags are always required when linking
- The options are understood both when linking with gcc and ldWhich is why I suggested we do it globally.
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
Quoted 5 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Vicente" == Vicente Olivert Riera <[email protected]> writes:
Hello Peter, Thomas and Arnout,
so, do you prefer a patch to just fix perf?
Quoted 8 lines
The perf
Makefiledoesn't read an environmental LDFLAGS variable, so adding -EL/-EB to LDFLAGS will not work.Also, doing LD="$(TARGET_CC)" in order to use gcc for linking doesn't work either and it fails with errors about '-lgcc_s' not found.
Are you ok with doing LD="$(TARGET_LD) -EL/-EB" only when building perf for MIPS architecture?
Yes, for 2016.02 I think this is fine.
Signature · 2 lines
Venlig hilsen, Peter Korsgaard
PATCH 1/2 package/Makefile.in: append endianness argument to TARGET_LD for MIPS
In reply to Arnout VandecappelleQuoted 44 lines · Arnout Vandecappelle
Quoted 8 lines · Thomas Petazzoni
Dear Vicente Olivert Riera,
Quoted 5 lines · Vicente Olivert Riera
We don't use a wrapper for ld in Buildroot like we do for gcc, so when using ld for linking (instead of gcc) the process can fail if the appropriate arguments are not passed to it. For instance, this happens when building perf (Linux -> Linux Kernel Tools -> perf) for MIPS little endian, and this is how the error message looks like:
[snip]
Quoted 17 lines
package/Makefile.in TARGET_READELF = $(TARGET_CROSS)readelf · line 204
Quoted 12 lines
package/Makefile.in +12
-0+# Append the endianness argument to ld for MIPS architecture in order to +# avoid problems like this one when using ld instead of gcc for linking: +# mips-linux-gnu-ld: failed to merge target specific data of file foo.o +# mips-linux-gnu-ld: foo.o: compiled for a little endian system and +# target is big endian +ifeq ($(BR2_mips)$(BR2_mipsel)$(BR2_mips64)$(BR2_mips64el),y) +ifeq ($(BR2_ENDIAN),"BIG") +TARGET_LD += -EB +else +TARGET_LD += -EL +endif +endifThis is really an horrible fix IMO. First because
TARGET_LDis only meant to contain the path to the linker, and not additional flags. Additional flags should go inTARGET_LDFLAGS.Quoted 3 lines
And secondly because programs should not use ld directly for linking, but gcc. Remember Vicente, you already fixed this issue in other packages and the fix was to use gcc instead of ld.
So, are we really going to "fix" all packages that use ld directly? I don't see
why a package shouldn't be allowed to call ld when it is really doing linking without any other toolchainy stuff.LDFLAGS has a bit of the same problem: there will probably be packages that
don't (completely) honour it.For CFLAGS, that was the reason why we introduced the wrapper. So I think we
should just add a wrapper for ld as well.Ideally the ld wrapper and the gcc wrapper should be refactored into the same
source file, but I think we could start out with separate sources and factor later.
Quoted 6 lines
Any takers?
Unless Vicente volunteers to work on an ld wrapper, I guess on the short term
we should take patches like these. That said, it should really be passed through LDFLAGS and not LD itself.
Hi,
I'm following this discussion in the scope of this 'ld wrapper' in toolchain-wrapper, as there are still other packages out there that have this issue (e.g. Dmalloc using ld directly). Without proper knowledge on what is the 'correct' way I saw also following (old) comment I wanted to point to:
From: http://lists.busybox.net/pipermail/buildroot/2013-june/073430.html
On 6 June 2013, Markos Chandras <[email protected]> wrote:
[snip]
Quoted 7 lines
I am inclined to say that binutils do not need to be changed, because you should never call the linker directly to do the linking (I recall directfb does that and fails with the same problem). You should be using gcc instead and it will pass all the appropriate linker flags to the linker. Such build systems need fixing instead of trying to workaround the problem in the toolchain.
Quoted 6 lines
Having said that, the entire patchset [heyleke: topic was ld-toolchain-wrapper] could be seen as a temporary workaround for this problem. In the libiscsi case, I need to
understand why libtool invokes the linker without the correct flags.
If you try to compile a simple test program using the buildroot
mip64-linux-gcc toolchain (pass -v as well) you will notice that gcc
passes -melf64btsmip correctly.
That being said and pointed to, there is this old patchset from Thomas Petazzoni on toolchain-wrapper for 'ld'. The main principles are not changes since the original patch, but toolchain-wrapper was moved and other patches were added later, so I had to rework it a bit, and tested it, it fixes the issue for mips and dmalloc package, the original patch and discussion:
Http://thread.gmane.org/gmane.comp.lib.uclibc.buildroot/60942
Although it was reviewed back then, it looks like it never made into the buildroot repository. As said, I've rebased and reworked it a bit, I'll put it on the mailing list. But as said, I'm not saying it is the 'correct' or 'incorrect' way of fixing this mips-ld stuff, but it does fix it for the way dmalloc's buildsystem is constructed (using ld directly).
Best regards,
Jan
Quoted 20 lines
Regards,
ArnoutQuoted 3 lines
Thomas
--
Arnout Vandecappelle arnout at mind be Senior Embedded Software Architect +32-16-286500 Essensium/Mind http://www.mind.be G.Geenslaan 9, 3001 Leuven, Belgium BE 872 984 063 RPR Leuven LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF_______________________________________________
buildroot mailing list
buildroot at busybox.net
http://lists.busybox.net/mailman/listinfo/buildroot