Building cross compiler: pthread.h: No such file or directory - linux

I'm currently trying to compile my own gcc 9.1.0 cross compiler for aarch64-linux-gnu target. I used this tutorial: https://wiki.osdev.org/GCC_Cross-Compiler
The compile progress for the gcc and g++ compiler seems to finish without errors, but allways when I try to compile libgcc with the command make all-target-libgcc I run into this error:
In file included from ../../../gcc-9.1.0/libgcc/gthr.h:148,
from ../../../gcc-9.1.0/libgcc/libgcov-interface.c:27:
./gthr-default.h:35:10: fatal error: pthread.h: No such file or directory
35 | #include <pthread.h>
| ^~~~~~~~~~~
compilation terminated.
g++ --version on my build maschine prints:
g++ (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And my configuration command for gcc is:
../gcc-9.1.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --without-headers
With:
export TARGET=aarch64-linux-gnu
export PREFIX=/opt/aarch64-linux-gnu
What do I forget?

From GCC installation manual:
In order to build GCC, the C standard library and headers must be
present for all target variants for which target libraries will be
built (and not only the variant of the host C++ compiler).
So you need a libc for aarch64.
If you want to build it yourself, Preshing has a good article on the topic, which I haven't read in full but recommend anyway. He even has a picture mentioning both pthread.h and libgcc.a.
AFAIK, GCC can pick up a symlink to newlib sources and build it automatically during the course of building a full cross compiler with target libraries. Not sure about Glibc.

Related

How to use patchelf with --set-interpreter?

I'm trying to do the following:
Change the libc of a simple test.c from the system default (Debian 9.11, libc-2.24.so) to libc 2.27.
This is my attempt:
user#pc:~/patchelf_test$ cat test.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("hello patchelf\n");
return 0;
}
user#pc:~/patchelf_test$ gcc test.c -o test
user#pc:~/patchelf_test$ ./test
hello patchelf
user#pc:~/patchelf_test$ ldd test
linux-vdso.so.1 (0x00007ffd9d1d8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7ea0290000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7ea0831000)
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.so test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ldd test
linux-vdso.so.1 (0x00007fff20b9a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa46a35e000)
./libc6-amd64_2.27-3ubuntu1_i386.so => /lib64/ld-linux-x86-64.so.2 (0x00007fa46a900000)
user#pc:~/patchelf_test$ ./test
GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 7.3.0.
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
user#pc:~/patchelf_test$
The expected result here, is that it should run the actual program. Actual results, are that it runs the linker itself.
Question: How do I need to modify my command to fix this?
I've also tried to use libc6-amd64_2.27-3ubuntu1_i386.ld instead of .so:
user#pc:~/patchelf_test$ !gcc
gcc test.c -o test
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.ld test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ./test
Segmentation fault
I've also tried to use my system default libc, and patch with that, just to establish that patchelf works at all, but again I get the same problem -- it executes the linker binary itself, instead of the test binary.
user#pc:~/patchelf_test$ !gcc
gcc test.c -o test
user#pc:~/patchelf_test$ patchelf --set-interpreter ./libc_default.so test
warning: working around a Linux kernel bug by creating a hole of 2093056 bytes in ‘test’
user#pc:~/patchelf_test$ ./test
GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
strace:
$ strace ./test
execve("./test", ["./test"], [/* 44 vars */]) = 0
write(1, "GNU C Library (Debian GLIBC 2.24"..., 616GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 6.3.0 20170516.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
) = 616
exit_group(0) = ?
+++ exited with 0 +++
This command makes no sense:
patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.so test
libc.so.6 and ld-linux.so.2 are not at all the same, and you are setting PT_INTERP to (equivalent of) libc.so.6.
This command is "correct":
patchelf --set-interpreter ./libc6-amd64_2.27-3ubuntu1_i386.ld test
but the result crashes most likely due to system GLIBC being a different version. As I said here, ld-linux and libc.so.6 must match exactly.
To make this all work, you should get rid of the funny libc-amd64... naming convention, fully extract the 2.27 build into e.g. ./libc6-amd64_2.27/ directory, then use something like:
patchelf --set-interpreter ./libc6-amd64_2.27/lib64/ld-linux-x86-64.so.2 test
LD_LIBRARY_PATH=./libc6-amd64_2.27/lib64 ./test

How do I link libraries from multiple locations (corresponding to multiple GCC versions)?

I am currently trying to use Oracle Linux 6 OS on a SPARC S7 server to run the NPB benchmarks (with OpenMP multithreading support). The OS comes preloaded with gcc 4.4.7, which is missing the Niagara 7 optimizations. I downloaded devtoolset-3 from the Oracle Yum Repository, which has gcc 4.9.2 installed in /opt/rh/devtoolset-3/root/usr/bin. However, when I compile the NPB benchmark using the newer gcc, it automatically links to libraries associated with the older gcc 4.4.7 (located in /usr/lib). This caused my program to segfault during execution. I believe that it is because libgomp 4.4.7 is incompatible with libgomp 4.9.2. I have tried several ways of linking to the libraries in the gcc 4.9.2 folder (which is /opt/rh/devtoolset-3/root/usr/lib/gcc); none of the methods work:
-Xlinker -rpath=lib_location
-Wl -Bstatic
-L lib_location
The closest I got was when using -Wl -Bstatic ~/libgomp.a or -static -L ~/libgomp.a. It fails to find libraries such as libm that reside in the default gcc lib folder (usr/lib).
The actual command used to link is:
/opt/rh/devtoolset-3/root/usr/bin/gcc -O3 -fopenmp -mcmodel=medmid -static -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2 -o ../bin/bt.W.x bt.o initialize.o exact_solution.o exact_rhs.o set_constants.o adi.o rhs.o x_solve.o y_solve.o solve_subs.o z_solve.o add.o error.o verify.o ../common/print_results.o ../common/c_timers.o ../common/wtime.o -lm -L/opt/rh/devtoolset-3/root/usr/lib/gcc/sparc64-redhat-linux/4.9.2/lib/
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lm
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lrt
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lpthread
/opt/rh/devtoolset-3/root/usr/libexec/gcc/sparc64-redhat-linux/4.9.2/ld: cannot find -lc
Is there a way I can link just the libgomp library from gcc 4.9.2 while linking the remaining libraries from gcc 4.4.7?
The devtoolset compilers are all using the system libgcc, libstdc++, version 4.4.7, and can therefore not compile e.g. c++11.
I guess the gcc53-c++-5.3.0-1.el6.x86_64.rpm will do. Comes with the internal */gcc53/lib64{libgcc_s.so**, libgomp.so**, libstdc++} (version 5.3.0) ... Provides /usr/bin/{ gcc53, g++53 }
The package was created a year ago ... well tested, as extra compiler. Download link : https://drive.google.com/file/d/0B7S255p3kFXNbTBneHgwSzBodFE/view?usp=sharing
If you're going to do the -Wl,-Bstatic thing, make sure to follow it immediately by -Wl,-Bdynamic to reset to normal after your added library argument. By default, not all system libraries have static versions installed, which is why you get e.g. cannot find -lc.
So you can try this as a modification of your workaround:
-Wl,-Bstatic ~/libgomp.a -Wl,-Bdynamic
Not pretty, and this question deserves a much better answer (this is still pretty much a hack), but it should get the job done for now.

What's the different about gcc and gcc++?

I follow my tutorial in linux to install some package:
yum install -y pcre pcre-devel openssl openssl-devel gcc gcc++
I am not sure about the gcc means GPN Compiler Collection or GPN C Compiler, I just not sure, because if it means the latter, the gcc++ maybe means GNU Compiler C++.
Who is there to answer my doubts?
gcc is GCC and gcc++ is G++ which are both GNU compilers
GCC is GNU’s C Compiler, and
G++ is GNU’s C++ Compiler
The difference is:
GCC will compile both .c and .cpp files. However, it will treat .c files as C programs and .cpp files as C++ programs.
G++ will also compile both .c and .cpp files just like the GCC compiler. The difference is that it will treat both .c and .cpp files as C++ programs.
From the "Programming Languages Supported by GCC" page:
The abbreviation GCC has multiple meanings in common use. The current official meaning is “GNU Compiler Collection”, which refers generically to the complete suite of tools. The name historically stood for “GNU C Compiler”, and this usage is still common when the emphasis is on compiling C programs. Finally, the name is also used when speaking of the language-independent component of GCC: code shared among the compilers for all supported languages.
And regarding the difference between the gcc and g++ commands, see the "GCC Command Options" page:
The usual way to run GCC is to run the executable called gcc, or machine-gcc when cross-compiling, or machine-gcc-version to run a specific version of GCC. When you compile C++ programs, you should invoke GCC as g++ instead. See Compiling C++ Programs, for information about the differences in behavior between gcc and g++ when compiling C++ programs.
and from "Compiling C++ Programs"
the use of gcc does not add the C++ library. g++ is a program that calls GCC and automatically specifies linking against the C++ library. It treats ‘.c’, ‘.h’ and ‘.i’ files as C++ source files instead of C source files unless -x is used.

"cmath: No such file or directory" when compiled with GCC

I wrote the simple program in linux ubuntu, when I use g++ there is no error but when I use gcc I see this error:
test.c:1:17: fatal error: cmath: No such file or directory #include <cmath>
Note : "as a matter of fact I see this error in compiling the package, I thought it might be related to gcc library which is not set to linux environment, so I wrote the simple program to determine the error clearly and whitout dependency!"
so the program should compile with gcc so that I can over come the main problem.
I khow that I can use math.h instead of cmath, but the packege used the cmath!
this is the simple program:
/*test.c*/
#include <cmath>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(){
double sinx = sin(3.14/3);
cout<< "sinx= " << sinx;
return 0;
}
here is cmath pathes:
root#geant4:/# find -name cmath
./opt/root5.32.00/cint/cint/include/cmath
./app/gcc/4.8.0/include/c++/4.8.0/ext/cmath
./app/gcc/4.8.0/include/c++/4.8.0/cmath
./app/gcc/4.8.0/include/c++/4.8.0/tr1/cmath
./usr/include/boost/compatibility/cpp_c_headers/cmath
./usr/include/boost/tr1/tr1/cmath
./usr/include/c++/4.5/cmath
./usr/include/c++/4.5/tr1_impl/cmath
./usr/include/c++/4.5/tr1/cmath
./usr/include/c++/4.6/cmath
./usr/include/c++/4.6/tr1/cmath
./usr/share/gccxml-0.9/GCC/2.95/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/stage1-i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c_global/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/c_std/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/include/tr1/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/testsuite/26_numerics/headers/cmath
./gcc-build/gcc-4.8.0/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/ext/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/cmath
./gcc-build/gcc-4.8.0/prev-i686-pc-linux-gnu/libstdc++-v3/include/tr1/cmath
and after installing gcc-4.8 I did this instruction:
root#geant4:~/Desktop# update-alternatives --install /usr/bin/gcc gcc /app/gcc/4.8.0/bin/gcc 40 --slave /usr/bin/g++ g++ /app/gcc/4.8.0/bin/g++
root#geant4:~/Desktop#update-alternatives --install /usr/bin/gcc gcc /app/gcc/4.8.0/bin/gcc 60 --slave /usr/bin/g++ g++ /app/gcc/4.8.0/bin/g++
root#geant4:~/Desktop# update-alternatives --config gcc
to make gcc-4.8 my default gcc.
now
root#geant4:~/Desktop# gcc --version
gcc (GCC) 4.8.0
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
as a matter of fact I wrote the main problem in https://askubuntu.com/questions/309195/cmath-no-such-file-or-directory-include-cmath
please help me
I don`t know what to do.
thanks
Some basics::
GCC:: GNU Compiler Collection
G++:: GNU C++ Compiler
Both are drivers which calls the compilers as needed.
Clearing your doubt::
The problem with GCC is that it doesn't links in the std C++ libraries by default as G++ does. GCC is just a front-end. The actual compiler is cc1plus. So it is always advisable to use G++ when compiling C++ files. The result can be same with both GCC and G++ if you do know the exact arguments to link them. You may find this link helpful.
But if you still want to use GCC, use it with linker-option -lstdc++ at the end of the command. This linker-option is added by default when you use G++. You can verify this by compiling your code using GCC with -### option and it will show you that -lstdc++ option is missing.
Compile C++ source files with g++, not gcc.

Getting GMP to work with GCC 4.5.2

I'm trying to make a cross compiler with the files from http://crossgcc.rts-software.org/doku.php?id=i386linuxgccformac
I'm on an Intel Mac (10.6.6, x86_64) I compiled: gmp, mpfr, mpc for the cross compiler as 32bit (as I'm on a 64bit Mac) but I'm getting
ld: warning: option -s is obsolete and being ignored
ld: warning: ignoring file /gmp1/lib/libmpc.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: ignoring file /gmp1/lib/libmpfr.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: ignoring file /gmp1/lib/libgmp.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
When compiling GCC with:
--prefix=/usr/local/i386-linux-4.5.2 --target=i386-linux --enable-languages=c --without-headers --disable-shared --disable-threads --disable-nls --with-gmp=/gmp1 --with-gmp-lib=/gmp1 --with-gmp-include=/gmp1 --with-mpfr=/gmp1 --with-mpfr-include=/gmp1 --with-mpfr-lib=/gmp1 --with-mpc=/gmp1 --with-mpc-lib=/gmp1 --with-mpc-include=/gmp1
Also, if I compile GMP with:
./configure --prefix=/gmp1 --host=i386-linux
I get:
configure: WARNING: +----------------------------------------------------------
configure: WARNING: | Cannot determine global symbol prefix.
configure: WARNING: | link -dump -symbols output doesn't contain a global data symbol.
configure: WARNING: | Will proceed with no underscore.
configure: WARNING: | If this is wrong then you'll get link errors referring
configure: WARNING: | to ___gmpn_add_n (note three underscores).
configure: WARNING: | In this case do a fresh build with an override,
configure: WARNING: | ./configure gmp_cv_asm_underscore=yes
configure: WARNING: +----------------------------------------------------------
checking how to switch to read-only data section... .data
checking for assembler .type directive...
checking for assembler .size directive...
checking for assembler local label prefix... configure: WARNING: "link -dump -symbols" failure
configure: WARNING: cannot determine local label, using default L
L
checking for assembler byte directive... .byte
checking how to define a 32-bit word... link: illegal option -- d
I think that you are confused about which package should be compiled for which platform:
GCC needs to be compiled for an x86_64 MacOS X host and an i386-linux target.
GMP, MPC and MPFR are runtime dependencies for GCC. Therefore they also need to be compiled for the GCC host - x86_64 in your case. Therefore, the --host=i386-linux option in the GMP configure command is incorrect.
In general, only libraries that will be linked in the programs compiled by GCC need to be built for the cross-compiler target (e.g. i386-linux). GMP and MPFR are not such libraries, unless your programs are actually using them - in that case you will need to have two copies of such libraries, one for GCC and a cross-build for the target.
EDIT:
Have you considered using MacPorts? It has all the dependencies for your cross-compiler:
gmp-5.0.1
mpfr-3.0.0
libmpc-0.8.2
There is also an older newlib-based cross-compiler for i386:
i386-elf-gcc-4.3.2
Even if you do not want to use these, you can still have a look at the build instructions in their Portfiles.
The bottom line is:
Apply whatever patches these libraries need - MacPorts already do that.
Compile the libraries for your build host i.e. MacOSX/x86_64. That means that in any --host options for their configure calls you should be something along the lines of --host=x86_64-darwin (or whatever your host needs). If configure can figure out the host on its own, you can skip the --host options altogether.
Compile GCC with --host being your build host (the 64-bit Mac OS X) and a target of i386-linux, e.g. --target=i386-linux. If I were you, I'd start simple with a compiler for the C and C++ languages only.
See also this tutorial. It has some information on how to produce a working toolchain with a proper glibc.
That said, I think that you'd be better off installing a proper Linux distribution in a virtual machine, for a whole bunch of reasons. Is there a reason for you to need a cross-compiler specifically? What do you want to do with that compiler?
Did you use the "ABI=32" option when compiling GMP? If not, I think it will use 64-bit code even if the host/target are specified as i386.

Resources