I'm new in ARM development. Now I'm really confused about the cross tool chain of ARM. Here some problems that I encountered:
Are the developers of gcc and arm-linux-gcc the same? Or there are many different developers of arm-linux-gcc for different versions? If there are, what is the origin of all arm-linux-gcc compilers? Is there an official website for arm-linux-gcc?
Where to get official documentation of arm-linux-gcc? Now I can only get official documentation of gcc from the official GNU website, but I downloaded my arm-linux-gcc from GNUTOOLCHAIN and cannot find any documents. According to my experience, the options of gcc and arm-linux-gcc are not exactly same.
Finally, what are the differences between different prebuilt versions of arm-linux-gcc? I guess the only difference between them is the default options of the compiler, am I right? Can I use a prebuilt arm-linux-gcc for arm1176 to compile a program for a cortex-A8? If so, what compile options should I pay attention to?
Is there any authoritative book about such things?
Answers for your questions are below:
There are different compiler options for doing compilation for arm from different developers. The one I commonly use are Linaro and Code Sourcery. You can search these keywords on Google and find their website easily.
arm-linux-gcc should support all the flags and options of gcc, so all the generic stuff is same as compared to gcc. So you can use the gcc documentation on official GNU website. For something specific you can use the documentation of the specific compiler.
The prebuilt versions are the ones with default options for a particular platform, but they might also include some fixes or maybe hacks to run it on a particular platform. For example in case of RPi you cannot use the generic linaro toolchain and have to use a prebuilt one.
When you work with embedded devices, you usually need a cross-compiler which runs on a fast host machine (e.g., x86) and compiles for a slower target machine (e.g., ARM).
arm-linux-gcc is the cross-compiler for arm. It is normal gcc compiler, but compiled to run on a host machine and to generate target for an ARM machine.
Related
I searched a little bit and one google search was enough to discover the differences between the gcc and cc compilers, but I did not find the advantages in using one or another to compile C programs
Which compiler should I use? and why?
The compiler installed as part of X-Code on OS/X is a recent version of clang whose development is sponsored by Apple.
gcc is not provided nor supported by Apple.
Unless you install gcc explicitly from one of its distributions, gcc is an alias for clang on OS/X, just like cc.
The reason for this is to support packages that use gcc explicitly as the C compiler.
On your system, it does not matter which alias you use, the compiler invoked will be clang, which has a high degree of compatibility with gcc extensions but generates different code. Both are very advanced and dependable.
There are lots of examples of using arm neon intrinsics for android, with the ndk even having an example. I've gotten that to work with no problem.
Arm also offer the ACLE (Arm C Language Extension), but I can find next to nothing by way of examples. The arm document itself merely suggests including the arm_acle.h header file, however I still get errors. Google has offered almost zero assistance :) Also searching the arm community boards has yielded little by way of results.
Do people not use the acle, and chose inline assembly instead?
When I inlcude the arm_acle.h and atttempt to use the __ssat() call, I have to further define a directive __ARM_FEATURE_CRC32, and when building I get the error" error: '__builtin_arm_qadd' was not declared in this scope"
The header doesn't seen to include any dependencies, and the documentation list no specific link dependencies.
Any advice?
Or am I overlooking something fundamental here?
Additional Information:
My target arch is armv7-a-neon and is correctly detected in the make file at build time.
I then further define "-mfloat-abi=softfp -mfpu=neon -march=armv7", but to no avail.
If I undo my additional debugging defines, I simply get " error: #error "ACLE intrinsics support not enabled." (Neon support and detection succeeds)
Searching my code base, the arm_acle.h header file is only present for the clang host tools, whereas arm_neon.h is is present for several prebuilts tool arm directories.
As I said, the arm_neon works detection works fine, and runs fine, it's the arm_acle component that doesn't work.
Searching the online repositories like http://androidxref.com seems to suggest only neon is supported?
The ARM C Language Extensions are currently not fully supported in GCC (as of version 5.1). The Android NDK normally uses a version of GCC older than this, which also does not have full support for ACLE.
This page https://gcc.gnu.org/onlinedocs/gcc/ARM-C-Language-Extensions-_0028ACLE_0029.html gives some idea of the current level of implementation of ACLE for both ARM and AArch64 targets. As you'll see there, the only features of ACLE currently provided by GCC are the CRC32 intrinsics in arm_acle.h and the Neon Intrinsics you've already found in arm_neon.h.
I am getting the following error while trying to compile some code for an ARM Cortex-M4
using
gcc -mcpu=cortex-m4 arm.c
`-mcpu=' is deprecated. Use `-mtune=' or '-march=' instead.
arm.c:1: error: bad value (cortex-m4) for -mtune= switch
I was following GCC 4.7.1 ARM options. Not sure whether I am missing some critical option. Any kickstart for using GCC for ARM will also be really helpful.
As starblue implied in a comment, that error is because you're using a native compiler built for compiling for x86 CPUs, rather than a cross-compiler for compiling to ARM.
GCC only supports a single general architecture type in any given compiler binary -- so, although the same copy of GCC can compile for both 32-bit and 64-bit x86 machines, you can't compile to both x86 and ARM with the same copy of GCC -- you need an ARM-specific GCC.
(As auselen suggests, getting a pre-built one will save you quite a lot of work, even if you're only using it as a starting point to get things set up. You need to have GCC, binutils, and a C library as a minimum, and those are all separate open-source projects that the pre-built versions have already done the work of combining. I'll recommend Sourcery CodeBench Lite since that's the one my company makes and I do think it's a fairly good one.)
As the error message says -mcpu is deprecated, and you should use the other options stated. However "deprectated" simply means that its use may not continue to be supported; it will still work.
ARM Cortex-M4 is ARM Architecture V7E-M, so you should use -march=armv7-m (the documentation does not specifically list armv7e-m, but that may have been added since the documentation was last updated. The E is essentially the difference between M3 and M4 - the DSP instructions, so the compiler will not generate code that takes advantage of these instructions. Using ARM's Cortex-M DSP library is probably the best way to use these instructions to benefit your application. If your part has an FPU, then other options will be needed enable code generation for that.
Like others already pointed out, you are using a compiler for your host machine, and you need a compiler for generating code for your target processor instead (a cross compiler). Like #Brooks suggested, you can use a pre-built toolchain, but if you want to roll out your own cross-compiler, libc and binutils, there is a nice tool called Crosstool-NG. It greatly simplifies the process of building a cross-compiler optimized to generate code for a specific processor, so you're not stuck with a generic prebuilt toolchain, which usually builds code for a family of compatible processors (e.g. you could tune the toolchain for generating ASM for your specific target, or floating point code for a hardware FPU which is specific to your processor, instead of using only software floating point routines, which are default to most pre-built toolchains).
I have the GNU GCC compiler for Windows. I read that it is able to function as a cross compiler.
How do I do this? What command option(s) will produce an shared library that can be used by MacOS/Linux platforms?
You need to build your own cross-compiler, i.e. you need to get the GCC sources and compile them with a desired target-architecture. Then you have to cross-compile all the libraries.
The process is fairly involved and lengthy. The usual GNU makefiles are pretty good at supporting this (through HOST, BUILD and ARCH variables), but if possible you should leave this to a higher-level abstraction. crosstool is one such tool that comes to mind, but I don't know if it's available for Windows.
It's possible that you'll be able to find pre-build Windows binaries of GCC on the internet that target a particular architecture.
Recently I've been playing around with cross compiling using GCC and discovered what seems to be a complicated area, tool-chains.
I don't quite understand this as I was under the impression GCC can create binary machine code for most of the common architectures, and all that else really matters is what libraries you link with and what type of executable is created.
Can GCC not do all these things itself? With a single build of GCC, all the appropriate libraries and the correct flags sent to GCC, could I produce a PE executable for a Windows x86 machine, then create an ELF executable for an embedded Linux MIPS device and finally an executable for an OSX PowerPC machine?
If not can someone explain how you would achieve this?
With a single build of GCC, all the
appropriate libraries and the correct
flags sent to GCC, could I produce a
PE executable for a Windows x86
machine, then create an ELF executable
for an embedded Linux MIPS device and
finally an executable for an OSX
PowerPC machine? If not can someone
explain how you would achieve this?
No. A single build of GCC produces object code for one target architecture. You would need a build targeting Intel x86, a build targeting MIPS, and a build targeting PowerPC. However, the compiler is not the only tool you need, despite the fact that you can build source code into an executable with a single invocation of GCC. Under the hood, it makes use of the assembler (as) and linker (ld) as well, and those need to be built for the target architecture and platform. Usually GCC uses the versions of these tools from the GNU binutils package, so you'd need to build that for the target platform too.
You can read more about building a cross-compiling toolchain here.
I don't quite understand this as I was
under the impression GCC can create
binary machine code for most of the
common architectures
This is true in the sense that the source code of GCC itself can be built into compilers that target various architectures, but you still require separate builds.
Regarding -march, this does not allow the same build of GCC to switch between platforms. Rather it's used to select the allowable instructions to use for the same family of processors. For example, some of the instructions supported by modern x86 processors weren't supported by the earliest x86 processors because they were introduced later on (such as extension instruction sets like MMX and SSE). When you pass -march, GCC enables all opcodes supported on that processor and its predecessors. To quote the GCC manual:
While picking a specific cpu-type will
schedule things appropriately for that
particular chip, the compiler will not
generate any code that does not run on
the i386 without the -march=cpu-type
option being used.
If you want to try cross-compiling, and don't want to build the toolchain yourself, I'd recommend looking at CodeSourcery. They have a GNU-based toolchain, and their free "Lite" version supports quite a few architectures. I've used it for Linux/ARM and Android/ARM.