Gcc compilation for different targets - gcc

I was just trying to understand something about cross compilers which made me ask this question.
gcc is a cross-compiler.
By default what it the target architecture for gcc compilation if none is specified is the native target on which I am compiling the source. Correct ?
If the above is correct then how does it manage to generate the code for several different architectures even when it is explicitly specified ?
Shouldn't it have to know all the ISA's ? How is this managed ? Do they have all the information for all the existing ISA's ?

A given (particular) gcc is built for a particular given target. Use gcc -v to find out which.
Often, cross-compilers are installed as different commands, e.g. avr-gcc on Debian for the Atmel AVR processor (with specific options ...)
On some architectures and systems (typically x86 & Linux) you may compile for a different variant. See this. In particular you may want to use -mtune=native or -march=haswell or -m32 ...
If you build gcc yourself from its source tarball, you'll give it at configure time specific configure options (e.g. --program-suffix=-avr and --target=avr for the avr-gcc etc....)

Related

Identify Compiler Versions with arm-none-eabi cross compiling

I'm trying to figure out the compiler versions that are used in my project (to sync them across the team).
I'm using ChibiOS on an STM32 and it uses a makefile to compile. In the Makefile it uses
TRGT = arm-none-eabi-
CC = $(TRGT)gcc
Which makes it clear that arm-none-eabi-gcc is being used. However unclear to me is, if the version of my gcc compiler (gcc --version) is at all relevant to the compilation. As far a I understand gcc just is being set to a specific target here? Whats the relationship between my gcc/cc executable and the arm-none-eabi-gcc executable?
There is no relationship. It is a separate compiler which usually comes with its own include files, libraries, startup file and linker scripts. Usually, it is called a toolchain as often it comes with other tools as well (linker, specific versions of gdb and other tools).

How to change compiler of OpenMPI

I have OpenMPI which is using gcc to compile. I need to cross compile from an x86_64 host architecture to an aarch64 target architecture. Instead of using gcc to compile, I want to use aarch64-linux-gnu-gcc to cross compile.
Anyone know how to change the compiler from gcc to aarch64-linux-gnu-gcc?
Thanks in advance.
openmpi allows using their mpi-wrappers (i.e., mpicc, mpic++, ...) with a different compiler by specifying:
OMPI_CC=COMPILER_NAME_OR_PATH
OMPI_CXX=COMPILER_NAME_OR_PATH
e.g.,
OMPI_CC=clang
OMPI_CXX=clang++
or
OMPI_CC=/usr/bin/gcc-11
OMPI_CXX=/usr/bin/g++-11
In some cases, you might need to export these variables by prepending the export keyword.

arm gcc by default compiling its libc

I am trying to compile an SDK with the an embedded arm gcc compiler in cygwin. It is a makefile based SDK. My target is a cortex m3 device. My problem is, the SDK has a custom libc implementation for the target, and when I compile with the arm compiler (arm-none-eabi-gcc) it looks to pick up the gnu arm libc, not the SDK libc. This is resulting in a compilation error. I am positive the makefiles are correct (I copy and pasted the entire SDK from a computer where this was working). I no longer have access to that computer to try and verify / compare settings. I don't know how to prevent the arm gcc compiler from looking for its own implementation of the libc and instead point it to the correct implementation. Any help is greatly appreciated.
There are perhaps two solutions:
Create an environment specific to your tool - the GNU toolchain uses a number of environment variables to define default behaviour. For a custom toolchain, you will need to set all necessary variables to override the system defaults.
Use the -nostdlib linker option and explicitly link your desired library and C Runtime start-up code, so your linker command line might include the following:
-nostdlib -L/usr/myarmtools/gcc/lib -lc crt0.o
Note that -nostdlib suppresses the default linking of libc libstdc++ and crt0.o, so you must provide search path (-L) to the libraries, or explicitly link them by their full path and file name and link the C runtime object code for your target.
I use option 2 for preference as it will work in any environment. However if you wish to use common makefiles for building for multiple targets, option 1 may be useful.

gcc arm-none-eabi binaries don't run

I build a cross compile toolchain on OSX with:
binutils-2.23.52
gcc-4.6.4
gcc-core-4.6.4
gcc-g++-4.6.4
gdb-7.6.1
gmp-4.3.2
mpc-1.0.1
mpfr-2.4.2
newlib-2.0.0
for the target EFM32 wich is a ARM Cortex-m3, so the gcc target is arm-none-eabi.
All compiled fine.
But making programs with this toolchain like blink.c don't actually run on the EFM32 board.
I checked the blink.bin I did with a binary created with a IAR commercial toolchain delivered in the demos from energymicro, also gcc based and the they look very different internally (as expected :).
So has my toolchain wrong libs/versions or is it simply a matter of gcc/ld/ar switches wrong and what would be the steps to systematicly analyse this?

Force CMake to use static libraries

[Shamelessly cross-posted from the CMake help list]
I'm trying to create binaries as statically as possible. The fortran code I've got has got X11 and quadmath as dependencies, and I've come across a number of issues (maybe each of these issues should be in a different question?):
My variables are currently
set(CMAKE_LIBRARY_PATH /usr/X11/lib /usr/X11/include/X11 ${CMAKE_LIBRARY_PATH})
find_package(X11 REQUIRED)
find_library(X11 NAMES X11.a PATHS /usr/X11/include/X11/ /usr/X11/lib)
find_library(X11_Xaw_LIB NAMES Xaw Xaw /usr/X11/include/X11/ /usr/X11/lib ${X11_LIB_SEARCH_PATH})
find_library(Xaw Xaw7 PATHS ${X11_LIB_SEARCH_PATH})
set(CMAKE_LIBRARY_PATH /usr/lib/gcc/x86_64-linux-gnu/4.7 /usr/lib/gcc/x86_64-linux-gnu/4.7/x32 /usr/lib/gcc/x86_64-linux-gnu/4.7/32 ${CMAKE_LIBRARY_PATH})
find_library(quadmath NAMES quadmath.a)
set(BUILD_SHARED_LIBS ON)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(LINK_SEARCH_START_STATIC TRUE)
set(LINK_SEARCH_END_STATIC TRUE)
set(SHARED_LIBS OFF)
set(STATIC_LIBS ON)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
Using these, CMake attempts to build every program statically (as expected) - however, it fails because I don't have Xaw.a - I can't find out whether this actually should exist. I have installed the latest libxaw7-dev which I was expecting to fix it. One option would be to compile the X11 libraries myself, but I don't really want to do that...
if I comment out only set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static"), then CMake compiles everything, but uses shared libraries for every program, even though I specify the location of .a X11 libraries in my find_library() calls. I was expecting CMake to use the .a files where it could and then only use shared libraries - is there a way to force this behaviour?
does anyone know yet of a fix for the bug described here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46539; whereby gfortran seemingly can't statically link libquadmath? I tried the fix using gcc but I can't get CMake to recognise the libgfortran flag:
cmake -DCMAKE_Fortran_COMPILER=gcc -DCMAKE_Fortran_FLAGS=-gfortran
results in
-- The Fortran compiler identification is unknown
-- Check for working Fortran compiler: /usr/bin/gcc
-- Check for working Fortran compiler: /usr/bin/gcc -- broken
CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestFortranCompiler.cmake:54 (message):
The Fortran compiler "/usr/bin/gcc" is not able to compile a simple test program.
However, as you might have noticed, I set the location of the libquadmath.a; when I build a program which doesn't use X11 but does use quadmath when I use
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
then the program does compile successfully (running ldd reports 'not a dynamic executable') - does this mean that the bug has been fixed, or does it only work because I set the location in CMake?
I was having a similar problem. Turns out that cmake was implicitly linking against libgfortran and libquadmath. To fix this I put the following in my top level CMakeLists.txt:
unset(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES)
I could then explicitly link again the libraries using:
SET_TARGET_PROPERTIES(main_f PROPERTIES LINKER_LANGUAGE "C"
LINK_FLAGS
"/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libgfortran.a
/usr/local/Cellar/gcc/7.1.0/lib/gcc/7/libquadmath.a -lm -lgcc"
)
The static version of libgfortran is necessary because the shared library also depends on libquadmath. The added "-lm" and "-lgcc" bring in the system dynamic versions of these libraries. On a mac system, you would want to use the full path to your libm.a as well.
I guess your questions are not that much related, I don't know the answer for all of them.
For your static linking problems, since you're using GCC, you can pass multiple -static and -dynamic flags to it:
set(CMAKE_EXE_LINKER_FLAGS "-static ${STATIC_LIBS} -dynamic ${EVERYTHING ELSE} -static ${MORE_STATIC_LIBS}")
I don't know why Xaw.a isn't available on your system, probably because the package maintainer of your Linux distribution didn't really make them available.
Also, compiling everything static might make things not compatible between all distros out there and you cripple the ability for others to use improved, up-to-date libraries with your program, it might not be what you want.
If you intend to make a self-contained package of your program, it might be better just to include the shared libraries you used together, like Dropbox and many other proprietary applications do (Humble Bundle games are other example).

Resources