Discussion:
[PATCH] toolchain: check ARM EABI vs. EABIhf for external toolchains
Thomas Petazzoni
2013-07-16 22:06:06 UTC
Permalink
Following the introduction of the support of EABIhf as a second ARM
ABI, it is important to check whether the external toolchain provided
by the user actually uses the ABI that has been selected in the
Buildroot configuration. This commit introduces such a check, using a
similar solution to the one that was used to check OABI vs. EABI in
the past.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni-wi1+55ScJUtKEb57/***@public.gmane.org>
---
toolchain/helpers.mk | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index 95217e7..dc21f8a 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -280,8 +280,20 @@ check_uclibc = \
check_arm_abi = \
__CROSS_CC=$(strip $1) ; \
EXT_TOOLCHAIN_TARGET=`LANG=C $${__CROSS_CC} -v 2>&1 | grep ^Target | cut -f2 -d ' '` ; \
- if ! echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi(hf)?$$' ; then \
- echo "External toolchain uses the unsuported OABI" ; \
+ if echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabi" ; \
+ elif echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabihf$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabihf" ; \
+ else \
+ echo "Unsupported ABI of the external toolchain" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABI) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabihf" ] ; then \
+ echo "Incorrect ABI setting: EABI selected, but toolchain uses EABIhf" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABIHF) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabi" ] ; then \
+ echo "Incorrect ABI setting: EABIhf selected, but toolchain uses EABI" ; \
exit 1 ; \
fi
--
1.8.1.2
Yann E. MORIN
2013-07-16 22:39:53 UTC
Permalink
Thomas, All,
Post by Thomas Petazzoni
Following the introduction of the support of EABIhf as a second ARM
ABI, it is important to check whether the external toolchain provided
by the user actually uses the ABI that has been selected in the
Buildroot configuration. This commit introduces such a check, using a
similar solution to the one that was used to check OABI vs. EABI in
the past.
---
toolchain/helpers.mk | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/toolchain/helpers.mk b/toolchain/helpers.mk
index 95217e7..dc21f8a 100644
--- a/toolchain/helpers.mk
+++ b/toolchain/helpers.mk
@@ -280,8 +280,20 @@ check_uclibc = \
check_arm_abi = \
__CROSS_CC=$(strip $1) ; \
EXT_TOOLCHAIN_TARGET=`LANG=C $${__CROSS_CC} -v 2>&1 | grep ^Target | cut -f2 -d ' '` ; \
- if ! echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi(hf)?$$' ; then \
- echo "External toolchain uses the unsuported OABI" ; \
+ if echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabi" ; \
+ elif echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabihf$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabihf" ; \
That's not always the case. You can well have a toolchain which tuple
ends in eabi, but the toolchain uses the hard-float ABI.

That's the case by default for crosstool-NG toolchains, for example.
Since the *eabihf is recent, not all gcc or binutils versions recognise
it, while they are absolutely capable of emitting EABI using the
hard-float ABI. Hence, ct-ng allows adding the 'hf' suffix as an option.
(see attachment for an example of 'gcc -v' dump).

Checking for EABI, it is better and more reliable to run the
preprocessor, and check some defines are available or not (I always
need a bit of googling to get this):
ARM_TUPLE-gcc -E -dM -xc - </dev/null |grep __ARM_EABI__

However, I could not find a #define about the float ABI... :-(
Post by Thomas Petazzoni
+ else \
+ echo "Unsupported ABI of the external toolchain" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABI) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabihf" ] ; then \
Using this 'x$(VAR) = xy' construct is ugly. Just quote the variables,
it is easier to read:
if [ "$(BR2_ARM_EABI)" = "y" ... ]

The x$VAR construct was from a time when some shells where failing to
test against an empty string. That time is long gone. Virtaully all
shells can compare to empty strings, nowadays.
Post by Thomas Petazzoni
+ echo "Incorrect ABI setting: EABI selected, but toolchain uses EABIhf" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABIHF) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabi" ] ; then \
Ditto.
Post by Thomas Petazzoni
+ echo "Incorrect ABI setting: EABIhf selected, but toolchain uses EABI" ; \
exit 1 ; \
fi
Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ |
| +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. |
'------------------------------^-------^------------------^--------------------'
Peter Korsgaard
2013-07-17 05:27:42 UTC
Permalink
Hi,
Post by Thomas Petazzoni
+ else \
+ echo "Unsupported ABI of the external toolchain" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABI) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabihf" ] ; then \
Yann> Using this 'x$(VAR) = xy' construct is ugly. Just quote the variables,
Yann> it is easier to read:
Yann> if [ "$(BR2_ARM_EABI)" = "y" ... ]

Yann> The x$VAR construct was from a time when some shells where failing to
Yann> test against an empty string. That time is long gone. Virtaully all
Yann> shells can compare to empty strings, nowadays.

And we have SHELL=bash
--
Bye, Peter Korsgaard
Thomas Petazzoni
2013-07-17 07:25:19 UTC
Permalink
Dear Yann E. MORIN,
Post by Yann E. MORIN
Post by Thomas Petazzoni
EXT_TOOLCHAIN_TARGET=`LANG=C $${__CROSS_CC} -v 2>&1 | grep ^Target | cut -f2 -d ' '` ; \
- if ! echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi(hf)?$$' ; then \
- echo "External toolchain uses the unsuported OABI" ; \
+ if echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabi" ; \
+ elif echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabihf$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabihf" ; \
That's not always the case. You can well have a toolchain which tuple
ends in eabi, but the toolchain uses the hard-float ABI.
That's the case by default for crosstool-NG toolchains, for example.
Since the *eabihf is recent, not all gcc or binutils versions recognise
it, while they are absolutely capable of emitting EABI using the
hard-float ABI. Hence, ct-ng allows adding the 'hf' suffix as an option.
(see attachment for an example of 'gcc -v' dump).
Checking for EABI, it is better and more reliable to run the
preprocessor, and check some defines are available or not (I always
ARM_TUPLE-gcc -E -dM -xc - </dev/null |grep __ARM_EABI__
However, I could not find a #define about the float ABI... :-(
Ah, interesting. Originally, I wasn't planning on checking the tuple,
and I was instead thinking of using a specific tag in the ELF headers.

A binary compiled with an EABIhf toolchain:

$ arm-linux-gnueabihf-readelf -A toto.o | grep Tag_ABI_VFP_args
Tag_ABI_VFP_args: VFP registers
$

A binary compiled with an EABI toolchain:

$ arm-linux-gnueabihf-readelf -A toto.o | grep Tag_ABI_VFP_args
$

I would run this on the libc or ld.so provided with the toolchain.

What do you think?
Post by Yann E. MORIN
Post by Thomas Petazzoni
+ else \
+ echo "Unsupported ABI of the external toolchain" ; \
+ exit 1 ; \
+ fi ; \
+ if [ x$(BR2_ARM_EABI) = x"y" -a $${EXT_TOOLCHAIN_ABI} = "eabihf" ] ; then \
Using this 'x$(VAR) = xy' construct is ugly. Just quote the variables,
if [ "$(BR2_ARM_EABI)" = "y" ... ]
The x$VAR construct was from a time when some shells where failing to
test against an empty string. That time is long gone. Virtaully all
shells can compare to empty strings, nowadays.
Ok, will fix.

Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
Yann E. MORIN
2013-07-17 07:45:41 UTC
Permalink
Thomas, All,
Post by Thomas Petazzoni
Post by Yann E. MORIN
Post by Thomas Petazzoni
EXT_TOOLCHAIN_TARGET=`LANG=C $${__CROSS_CC} -v 2>&1 | grep ^Target | cut -f2 -d ' '` ; \
- if ! echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi(hf)?$$' ; then \
- echo "External toolchain uses the unsuported OABI" ; \
+ if echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabi$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabi" ; \
+ elif echo $${EXT_TOOLCHAIN_TARGET} | grep -qE 'eabihf$$' ; then \
+ EXT_TOOLCHAIN_ABI="eabihf" ; \
That's not always the case. You can well have a toolchain which tuple
ends in eabi, but the toolchain uses the hard-float ABI.
That's the case by default for crosstool-NG toolchains, for example.
Since the *eabihf is recent, not all gcc or binutils versions recognise
it, while they are absolutely capable of emitting EABI using the
hard-float ABI. Hence, ct-ng allows adding the 'hf' suffix as an option.
(see attachment for an example of 'gcc -v' dump).
Checking for EABI, it is better and more reliable to run the
preprocessor, and check some defines are available or not (I always
ARM_TUPLE-gcc -E -dM -xc - </dev/null |grep __ARM_EABI__
However, I could not find a #define about the float ABI... :-(
Ah, interesting. Originally, I wasn't planning on checking the tuple,
and I was instead thinking of using a specific tag in the ELF headers.
$ arm-linux-gnueabihf-readelf -A toto.o | grep Tag_ABI_VFP_args
Tag_ABI_VFP_args: VFP registers
Woot! I learned something! :-)
Post by Thomas Petazzoni
$ arm-linux-gnueabihf-readelf -A toto.o | grep Tag_ABI_VFP_args
$
I would run this on the libc or ld.so provided with the toolchain.
What do you think?
Yes, great! :-)

Regards,
Yann E. MORIN.
--
.-----------------.--------------------.------------------.--------------------.
| Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +0/33 662376056 | Software Designer | \ / CAMPAIGN | ^ |
| --==< O_o >==-- '------------.-------: X AGAINST | /e\ There is no |
| http://ymorin.is-a-geek.org/ | (*_*) | / \ HTML MAIL | """ conspiracy. |
'------------------------------'-------'------------------'--------------------'
Loading...