Is there a gcc option to print the target triplet when cross-compiling? - gcc

gcc -dumpmachine is almost perfect, but it doesn't respect flags that affect the target. On the other hand, clang does:
$ gcc -dumpmachine
x86_64-unknown-linux-gnu
$ gcc -dumpmachine -m32
x86_64-unknown-linux-gnu
$ clang -dumpmachine
x86_64-unknown-linux-gnu
$ clang -dumpmachine -m32
i386-unknown-linux-gnu

Perhaps -print-multiarch is useful. According to the documentations, this option "display the target's normalized GNU triplet, used as a component in the library path".
In my box (x86_64) I get:
$ gcc -print-multiarch
x86_64-linux-gnu
$ gcc -print-multiarch -m32
i386-linux-gnu

Related

Cross compiling with arm-linux-gnueabihf

I am quite new to cross compiling. After downloading the arm-linux-gnueabihf tool from arm. I tried to use the binary called arm-linux-gnueabihf-g++ and arm-linux-gnueabihf-gcc to compile my code. My command looks something like:
~/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -Isrc -I/usr/include -std=c++11 -Wall -Wno-unknown-pragmas -O0 -g3 -D__DEBUG_BUILD__ -DDEVELOPMENT -MMD -c -o "Debug/src/BatteryStatus.o" "src/BatteryStatus.cpp"
I immediately run into this issue:
~/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/stdlib.h:133:35: error: missing binary operator before token "("
#if __HAVE_FLOAT16 && __GLIBC_USE (IEC_60559_TYPES_EXT)
It's weird that the issue happens in the tool chain, I would expect some incompatibilities in the libraries I am using. The environment entails CentOS 7.2, c++ 11 and I am compiling for an ARM 32-bit target on a x86_64 host machine. Building a simple hello world program went fine, it compiled and ran successfully on the target machine.
You are pointing to your native header files directory, /usr/include, in your build command. This is very likely the cause of your problem. Try this command instead:
~/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -Isrc -std=c++11 -Wall -Wno-unknown-pragmas -O0 -g3 -D__DEBUG_BUILD__ -DDEVELOPMENT -MMD -c -o "Debug/src/BatteryStatus.o" "src/BatteryStatus.cpp
The default directories used by the toolchain can be displayed using:
echo | /opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -v -x c -E -
Using built-in specs.
COLLECT_GCC=/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
Target: arm-linux-gnueabihf
Configured with: /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/configure --target=arm-linux-gnueabihf --prefix= --with-sysroot=/arm-linux-gnueabihf/libc --with-build-sysroot=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/install//arm-linux-gnueabihf/libc --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-mpfr=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-mpc=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-isl=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-arch=armv7-a --with-fpu=neon --with-float=hard --with-arch=armv7-a --with-pkgversion='GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)'
Thread model: posix
gcc version 8.3.0 (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36))
COLLECT_GCC_OPTIONS='-v' '-E' '-mfloat-abi=hard' '-mfpu=neon' '-mtls-dialect=gnu' '-marm' '-march=armv7-a+simd'
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/8.3.0/cc1 -E -quiet -v -iprefix /opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/ -isysroot /opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc - -mfloat-abi=hard -mfpu=neon -mtls-dialect=gnu -marm -march=armv7-a+simd
ignoring duplicate directory "/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/8.3.0/include"
ignoring nonexistent directory "/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/local/include"
ignoring duplicate directory "/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed"
ignoring duplicate directory "/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/../../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/include
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/include
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "<stdin>"
COMPILER_PATH=/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/8.3.0/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../libexec/gcc/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/
LIBRARY_PATH=/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/lib/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/lib/:/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-E' '-mfloat-abi=hard' '-mfpu=neon' '-mtls-dialect=gnu' '-marm' '-march=armv7-a+simd'
That is, on my system, the correct, default directories for the header files would be:
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/include
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/include
/opt/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include
and not /usr/include.

GCC Default Link -l

When I need to use, for example, the gnu function gsl_sf_bessel_J0 in a program, I simply compile it with gcc -lgsl -o gsl_test.c gsl_test. Why do I have to include -lgsl for it to work? Is there any way I can set it as a default so I don't have to type it out everytime?
If you compile with the -v flag, you'll see the command the GCC front-end invokes to link your final executable*. If your program uses a function like gsl_sf_bessel_J0 that isn't in one of the default libraries (possibly limited to libc and maybe also libm), you need to explicitly link it.
If you don't like typing it all the time, make a simple Makefile. Your case is simple enough that you can handle it with just environment variables, actually:
$ export CC=gcc
$ export LDLIBS=-lgsl
$ make gsl_test
gcc gsl_test.c -lgsl -o gsl_test
$
make's default built-in rules will do the rest.
*: for reference, my compiler links your example as:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld"
-demangle
-dynamic
-arch x86_64
-macosx_version_min 10.12.0
-o gsl_test
/var/folders/cp/wvm69p1n7_bbjpxxqmttwn700000gn/T/gsl_test-0afe3a.o
-lgsl
-lSystem
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a

gfortran linking flag for openmp

I'm trying to link multiple .o files using gfortran. I've compiled the files like so (in a makefile):
gfortran -c -fopenmp file1.f
gfortran -c -fopenmp file2.f
Now I'd like to link the files with an option for OpenMP. I know with the Intel compiler the linking flag is -liomp5, so to link the files with the Intel compiler one would call:
ifort -o a.out file1.o file2.o -liomp5
This is obviously not the correct flag for the GNU compiler. What is the correct OpenMP linking flag for gfortran?
It is -fopenmp as well:
gfortran -fopenmp -o a.out file1.o file2.o

Why GCC can't pass options to `gas` assembler with `-Wa,-adhln=a.lst`?

When I want to generate the list file of a.c with the name a.lst, I execute the command:
gcc -v -S -Wa,-adhln=a.lst a.c
and some of the output is as following:
gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2)
COLLECT_GCC_OPTIONS='-v' '-S' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1 -quiet -v -imultiarch x86_64-linux-gnu a.c -quiet -dumpbase a.c -mtune=generic -march=x86-64 -auxbase a -version -o a.s -fstack-protector-strong -Wformat -Wformat-security
So, according to the output, I can't find the options of assembler -adhln=a.lst is being passed, and there is no a.lst file generated. My gcc version is gcc (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413, as version is GNU assembler (GNU Binutils for Ubuntu) 2.26. What's wrong with me?
The -Wa option passes flags to the assembler.
Your command uses -S which means "do not run the assembler".

GCC equivalent of llvm-link

I use the following LLVM tools to convert a cpp project which is written in multiple files into "ONE" single assembly file.
clang *.cpp -S -emit-llvm
llvm-link *.s -S -o all.s
llc all.s -march=mips
Is there any way of doing this in GCC? In particular, is there any way of linking GCC generated assembly files into one assembly file? i.e., what is the equivalent of LLVM-LINK?
Perhaps LTO (Link Time Optimization) is what you want.
Then, compile each compilation unit with gcc -flto e.g.
gcc -flto -O -Wall -c src1.c
g++ -flto -O -Wall -c src2.cc
and use also -flto (and the same optimizations) to link them:
g++ -flto -O src1.o src2.o -lsomething
LTO works in GCC by putting, in each generated assembly file and object file, some representation of the internal GCC representations (like Gimple). See its documentation
You might want to use MELT to customize GCC (or simply use its probe to understand the Gimple, or try just gcc -fdump-tree-all).

Resources