Why Does Arm-Linux-Gnueabi-G++-4.4 Always Build a "7-A" Binary

Why does arm-linux-gnueabi-g++-4.4 always build a 7-A binary?

Your compiler supports armv4t, problem is your linker has to link your object file with other files like libc, crt.o to create an executable. However in your toolchain all those files have been compiled for 7-A, thus result executable ends up being one as well. This is a problem with ubuntu cross toolchains, they are armv7a by default.

If you just compile your source file, you'll see that compiler outputs right object file type.

$ arm-linux-gnueabi-g++-4.4 -mcpu=arm9tdmi -march=armv4t -O -c main.cpp -o CPPTest

$ readelf -A CPPTest
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "ARM9TDMI"
Tag_CPU_arch: v4T
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
Tag_FP_arch: VFPv3-D16
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: SP and DP
Tag_ABI_optimization_goals: Prefer Speed
Tag_DIV_use: Not allowed

So a toolchain is more than a compiler and every component of it needs to play along.

Failed to build capnproto on ARM, test failed

When cross-compiling, you need to first build and install Cap'n Proto on the host machine, so that the commands capnp and capnpc-c++ are available on the command line.

Once you've done that, you can cross-compile. Pass --with-external-capnp to ./configure when configuring cross-compiling, to tell it to use the installed copy of the tools rather than the self-built copy. Also make sure you make clean or build in a different directory so that the build doesn't accidentally try to use the host-built objects.

If this "doesn't help", you'll need to provide more detail on what you're doing and what went wrong.

Distro provided cross compiler vs custom built gcc

When developers talk about building software (cross compiling) for a different machine (target) compared to their own (host) they use the term toolchain to describe the set of tools necessary to build binary files. That's because when you need to build an executable binary, you need more than a compiler.

You need routines (crt0.o) to initialize runtime according to requirements of operating system and standard libraries. You need standard set of libraries and those libraries need to be aware of the kernel on target because of the system calls API and several os level configurations (f.e. page size) and data structures (f.e. time structures).

On the hardware side, there are different set of ARM architectures. Architectures can be backward compatible but a toolchain by nature is binary and targeted for a specific architecture. You can have the most widespread architecture by default but then that won't be too fruitful for an already constraint environment (embedded device). If you have the latest architecture, then it won't be useful for older architecture based targets.

When you build a binary on your host for your host, compiler can look up all the necessary bits from its own environment or use what's on the host - so most of the above details are invisible to developer. However when you build for a different target than your host type, toolchain must know about hardware, os and standard library details. The way you tell these to toolchain is... by building it according to those details which might require some level of bootstrapping. (or you can do this via extensive set of parameters if toolchain supports / built for it.)

So when there is a generic (stock) cross compile toolchain, it has already some target specifics set and that might not meet your requirements. Please see this recent question about the situation on Ubuntu for an example.

How to I get crosstool-ng C++ compiler working

From, http://briolidz.wordpress.com/2012/02/07/building-embedded-arm-systems-with-crosstool-ng/

Refine your configuration by running the menuconfig interface:

$ ./ct-ng menuconfig

In this step, navigate to the C Compiler menu. Then you can select C++ or de-select Java, Fortran, etc. Since crosstool-ng is just a bunch of scripts and patch files, it is very rare that a development build breaks things. You can always pull from the hg repository.

hg clone http://crosstool-ng.org/hg/crosstool-ng

cd crosstool-ng

./bootstrap

make

sudo make install

This will have the latest fixes. I have built arm cross compilers with C++ support many times using this method [including Canadian crosses for Mingw and i386 from an x86_64 host].

EDIT: I see that the wordpress link recommends a local install of ct-ng. The commands above do a full install, putting things in /usr/local. Also, it seems the OP did try to set menuconfig's C++ option. Try altering the sjlj value, use the latest version of ct-ng and install it. This produces an ARM Linux C++ cross-compiler on Ubuntu for me. The build.log output can be helpful in determining if ct-ng decided some configuration was impossible.

Finally, the mailing list crossgcc@sourceware.org doesn't require subscription afaik. The archives at http://sourceware.org/ml/crossgcc/ can be helpful. If you still have issues, I am sure someone on the mailing list will be able to help you.

EDIT: With the latest ct-ng installed try,

$ ct-ng arm-cortex_a15-linux-gnueabi #Alternate arm-yem-linux-gnueabi

$ ct-ng menuconfig # Tweak for your processor, gcc version, etc.

$ ct-ng build # Go have a coffee (or work on something else).

Sorry, your host compiler was made with Linaro. I was reading too much into your edit.

what is arm-linux-gcc and how to install this in ubuntu

You are missing the gcc compiler with arm target set. This has been prepackaged in the ubuntu archive for quite a while, so you shouldn't need to build this from source.

sudo apt-get install gcc-arm-linux-gnueabi to install

Selecting a specific ARM arch for compiling

Since Armv7a and Armv8a architectures use different/incompatible instructions sets, the compiler you will use will be specific to one of the Armv7a/Armv8a architectures.

It will therefore not need to 'know' for which architecture it is compiling your kernel for, because it will have no choice.

Your 'make' commands will have to begin with one these statements:

# Armv7a/Aarch32/32 bit Arm Linux kernel
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf- ...

# Armv8a/Aarch64/64 bit Arm Linux kernel
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- ...

All different combinations of ARCH/CROSS_COMPILE will not work.

Please note that the exact name of for toolchains may vary slightly - I used the Arm toolchains triplets for the purpose of this answer.

Libraries compatibilty by cross-compiling node for armv5

Finally, instead of trying to change libraries, I decided to have a better cross-compiler which matches with my target perfectly.

I used Crosstools-NG for that, but I could use the official QNAP Maxwell-ARM Toolchain too (I saw it too late...)

gcc (GCC) 4.2.4
g++ (GCC) 4.2.4
GNU ld (crosstool-NG 1.20.0) 2.19.1
ldd (crosstool-NG) 1.20.0
Python 2.7.6 (with gyp)

But a problem was always here, there's a node dependecy (libuv) which uses a library named linux-atomic, and that library was introduced in GCC since version 4.4.X. So here is the workaround I made to fix it :

cd /src
wget -q https://ftp.gnu.org/gnu/gcc/gcc-4.6.3/gcc-core-4.6.3.tar.gz
tar -zxf gcc-core-4.6.3.tar.gz
sed -i -e 's/define HIDDEN.*/define HIDDEN/' /src/gcc-4.6.3/gcc/config/arm/linux-atomic.c
export CC=arm-none-linux-gnueabi-gcc
export AR=arm-none-linux-gnueabi-ar
export RANLIB=arm-none-linux-gnueabi-ranlib
cd /src/gcc-4.6.3/gcc/config/arm
libtool --tag=CC --mode=compile $CC -g -O2 -MT linux-atomic.lo -MD -MP -MF linux-atomic.Tpo -c -o linux-atomic.lo linux-atomic.c
$AR cru /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a /src/gcc-4.6.3/gcc/config/arm/.libs/linux-atomic.o
$RANLIB /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a

# IMPORTANT: Assign environment variables like I made in my question above.

# Go to node src dir and configure
./configure --without-snapshot --dest-cpu=arm --dest-os=linux --prefix="${PREFIX_DIR}"

# When configuration is done, edit out/node.target.mk
vi out/node.target.mk

# Find LD_INPUTS files list and add your new library as last one:
# -> /src/gcc-4.6.3/gcc/config/arm/.libs/liblinux-atomic.a

# Now you can build node !
make -j4 #-jX where X is the number of available cores
make install DESTDIR=$TEMPDIR # Use DESTDIR to avoid installation directly in $PREFIX_DIR path

Workaround reference

With that configuration, I also could compile node with GCC 4.1.3 for x86 processors. And I made QPKG for QNAP users who doesn't want to compile by themselves : https://github.com/jbltx/nodejs-QPKG/tree/master/node-v0.10.35



Related Topics



Leave a reply



Submit