I am trying to set up a GCC 4.9.4 cross-compiler for a QCA955X-based router with Linux 2.6.31. This is a MIPS32R2-abi CPU that uses uClibc-0.9.30.1 (as found in /lib.) Due to this, I have decided to compile a GCC 4.x with the matching uClibc and binutils-2.19.1a. My host system is Ubuntu 18.04 with Linux 4.17-rc5 and gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)
~/mips-cross-gcc/staging_dir is my prefix, and ~/mips-cross-gcc/staging_dir/sysroot is the makeshift sysroot for my system.
1) I downloaded binutils-2.19.1a.tar.bz2, gcc-4.9.4.tar.bz2, linux-2.6.31.9.tar.xz, and uClibc-0.9.30.1.tar.bz2 into ~/mips-cross-gcc/sources.
2) I untar'd all the sources.
3) Install linux headers:
make ARCH=mips INSTALL_HDR_PATH=/home/user/mips-cross-gcc/staging_dir/sysroot/usr headers_install
4) Build binutils:
cd binutils-2.19.1
./configure --prefix=/home/user/mips-cross-gcc/staging_dir --target=mips-linux-uclibc --disable-multilib --disable-werror --enable-shared --without-newlib --with-sysroot=/home/user/mips-cross-gcc/staging_dir/sysroot --enable-languages=c,c++ --disable-libgomp
make all-binutils
make all-ld
make all-gas
make install-binutils
make install-ld
make install-gas
5) Build "stage 1" gcc, to bootstrap uClibc:
cd gcc-4.9.4
mkdir -p build/gcc-stage1
../../configure --target=mips-linux-uclibc --prefix=/home/user/mips-cross-gcc/staging_dir --disable-werror --disable-libgomp --without-newlib --disable-multilib --enable-languages=c,c++ --enable-shared --disable-__cxa_atexit --enable-target-optspace --disable-nls --disable-libmudflap --disable-libssp --with-float=soft --with-sysroot=/home/user/mips-cross-gcc/staging_dir/sysroot --with-gnu-ld --without-headers
make all-gcc
make install-gcc
6) Install uClibc headers:
cd uClibc-0.9.30.1
make PREFIX=/home/user/mips-cross-gcc/staging_dir/sysroot install_headers
7) Build libgcc for target arch:
cd gcc-4.9.4
make all-target-libgcc
Libgcc is compiled all the way until the final libgcc_s linking stage:
/home/daniel/mips-cross-gcc/staging_dir/mips-linux-uclibc/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
Makefile:937: recipe for target 'libgcc_s.so' failed
I thought that bootstrapping a GCC would not require a libc, because it has not been compiled yet, right? What could I be doing wrong? I would use this compiled GCC to build uClibc, and then I would compile GCC again with my new uClibc so that I can cross-compile software. The fact that GCC requires libc in the first build seems wrong.
I tried to use the first gcc without compiling libgcc for building uClibc, but nearly instantly I received:
LD ld-uClibc-0.9.30.1.so
mips-linux-uclibc-gcc: error: libgcc.a: No such file or directory
ldso/ldso/Makefile.in:54: recipe for target 'lib/ld-uClibc.so' failed
So, uClibc needs libgcc to link itself, and gcc needs a libc (of any type, including uClibc) to link its own libgcc. This seems like a chicken-and-egg problem. How would one fix this?
I fixed it. Apparently, GCC has to be built without shared libraries enabled (--disable-shared) so that it doesn't link the generated libraries like libgcc dynamically (i.e to libc,) but that still didn't work. -lc was still not found.
I did some more googling, and I found this helpful message from eglibc, about making their own toolchain with gcc: eglibc.org
The First GCC
For our work, we need a cross-compiler targeting a PowerPC Linux
system. However, that configuration includes the shared library
'libgcc_s.so', which is compiled against the EGLIBC headers (which we
haven't installed yet) and linked against 'libc.so' (which we haven't
built yet).
Fortunately, there are configuration options for GCC which tell it not
to build 'libgcc_s.so'. The '--without-headers' option is supposed to
take care of this, but its implementation is incomplete, so you must
also configure with the '--with-newlib' option. While '--with-newlib'
appears to mean "Use the Newlib C library", its effect is to tell the
GCC build machinery, "Don't assume there is a C library available."
Looks like with enough digging, someone's bound to find the exact problem one has.
In short, changing --enable-shared to --disable-shared and adding --with-newlib to GCC's
./configure solved the issue and compiled + linked a libgcc_s.so that I used to compile uClibc, and then recompiled gcc with the newly generated libc, from uClibc. Indeed, it is possible to compile a 2016 GCC 4.x with a 2011 uClibc on a 2018 GCC 7.x.
Related
I am trying to recompile binutils and GCC as a cross-compiler for m68k architecture. I am following these instructions:
http://darkdust.net/writings/megadrive/crosscompiler
However, the process keeps failing on one part or another. I have tried with binutils 2.16.1 and gcc 3.4.6, binutils 2.15 and gcc 3.4.2 and binutils 2.15 and gcc 3.4.6.
This last attempt fails when running "make" on gcc, after making and installing binutils. It gives the following error:
gcc -g -O2 -DIN_GCC -DCROSS_COMPILE -W -Wall -Wwrite-strings -Wstrict-
prototypes -Wmissing-prototypes -pedantic -Wno-long-long -DHAVE_CONFIG_H
-I. -I. -I../../gcc-3.4.2/gcc -I../../gcc-3.4.2/gcc/. -I../../gcc-
3.4.2/gcc/../include \
-DTARGET_MACHINE=\"m68k-coff\" \
-c ../../gcc-3.4.2/gcc/collect2.c -o collect2.o
In file included from /usr/include/fcntl.h:289:0,
from ../../gcc-3.4.2/gcc/system.h:214,
from ../../gcc-3.4.2/gcc/collect2.c:30:
In function ‘open’,
inlined from ‘collect_execute’ at ../../gcc-3.4.2/gcc/collect2.c:1535:20:
/usr/include/x86_64-linux-gnu/bits/fcntl2.h:50:4: error: call to
‘__open_missing_mode’ declared with attribute error: open with O_CREAT or
O_TMPFILE in second argument needs 3 arguments
__open_missing_mode ();
^
Makefile:1364: recipe for target 'collect2.o' failed
make[1]: *** [collect2.o] Error 1
make[1]: Leaving directory '/home/gabriel/src/gcc-build/gcc'
Makefile:23339: recipe for target 'all-gcc' failed
make: *** [all-gcc] Error 2
I don't expect to fix this error, but does anyone know of a combination of binutils and gcc release that work? Should I be using a certain version of gcc to recompile gcc successfuly?
Thanks for any insight you may have on this!
EDIT:
My linux has GCC 5.4.0 so I just downloaded the 5.4.0 source to try and rebuild that for m68k cross-compiling. I now get the following error when running "make" on the gcc source:
*** Configuration m68k-unkown-coff not supported
What could be the cause of this? Is it because I need an older version of GCC? (the binutils version i'm using definately supports the m68k target). The tutorial I'm using always defines "--target=m68k-coff", should that instead be "--target=m68k-unkown-coff"?
EDIT 2:
So I tried compiling for m68k-elf but now I get this error:
checking for m68k-elf-gcc... /home/gabriel/src/gcc-build/./gcc/xgcc -B/home/gabriel/src/gcc-build/./gcc/ -B/opt/m68k/m68k-elf/bin/ -B/opt/m68k/m68k-elf/lib/ -isystem /opt/m68k/m68k-elf/include -isystem /opt/m68k/m68k-elf/sys-include
checking for suffix of object files... configure: error: in `/home/gabriel/src/gcc-build/m68k-elf/libgcc':
configure: error: cannot compute suffix of object files: cannot compile
I ran download_prerequisites before building so it should not be a problem with the MPC library. Any idea how to move on? I need assembler only so I don't mind what the format of the object files is. Thanks!
I used to do pretty much what you are doing right now.
My advice is to use crosstool-ng (http://crosstool-ng.github.io), as it does pretty much everything in an automated manner.
If you are studying m68k assembly, I used to host a modified version of gcc-explorer by Matt Godbolt (https://godbolt.org/). You can find a runnable docker image here (https://hub.docker.com/r/esantoro/acso-explorer/) and some more details here (https://znpy.wordpress.com/2017/05/08/decommisioning-acso-explorer-santoro-tk/)
Hope it helps,
znpy
you can build most versions with a current Linux. To install the prerequisites have a look at https://github.com/bebbo/amiga-gcc
unpack the gcc archive, e.g. to /opt/cross/gcc-6.5.0
create a separate build folder, e.g. /opt/cross/xcc-6.5.0 - never build inside gcc's source folder!
create the prefix folder, that's where binaries are installed to, e.g. /opt/cross/gcc65
ensure that these folders exist and are writable, then
configure from within that build folder using an absolute path for configure
cd /opt/cross/xcc-6.5.0/
/opt/cross/gcc-6.5.0/configure --target=m68k-elf --program-prefix=m68k-elf- --enable-languages=c,c++ --prefix=/opt/cross/gcc65 --disable-libssp --disable-nls --disable-multilib
make all-gcc
make install-gcc
I'm also running the compiler explorer for 68k gccs at https://franke.ms/cex/
I'm trying to make an "C" application for my NXP(Freescale) imx6 that Debian OS installed on it. My host machine is Ubuntu 16.04. I'm using eclipse as an IDE and I can manage to cross compile until today. I use arm-linux-gnueabihf-gcc as an compiler and arm-linux-gnueabihf-ld as an linker. I added -lasound option to my linker parameter, but still can not build the application. I get an error
arm-linux-gnueabihf-ld: cannot find -lasound
I think I don't have the libasound.so file on my Ubuntu (Host) machine and my linker couldn't link to library to my application.
I copied the libasound.so file from my ARM machine to my host machine to the /home/user/Downloads folder, but still couldn't compile.
Is there a step to use ALSA library in Cross Compilation project before build?
Here is the output of build operation
Building target: tihc_linux_application
Invoking: GCC C Linker
/usr/bin/arm-linux-gnueabihf-ld -static -L/home/user/Downloads -pthread -lasound -o "main" ./src/main.o
/usr/bin/arm-linux-gnueabihf-ld: mode armelf_linux_eabi
/usr/bin/arm-linux-gnueabihf-ld: cannot find -lasound
You ask for static link (via -static) but provide shared library so ld probably ignores it (to be sure you can run with -Wl,--verbose). One option is to cross-compile libalsa from scratch and then use resulting static lib to link your app. Another option is to search for pre-compiled gnueabihf libalsa somewhere...
I'm new to Homebrew (I usually use Macports, but I'm trying out Homebrew on a 2nd computer), and I wish to install the openmpi (or mpich2) package. Steps are as follows (carried out on Mac OS X Yosemite with Xcode 6 installed):
brew install gcc
brew install openmpi
However, I suspect the linking may have been done incorrectly, due to the following reasons:
The symbolic link for /usr/local/bin/gcc is missing:
$ which gcc
/usr/bin/gcc
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include/c++/4.2.1
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
$ which gcc-4.9
/usr/local/bin/gcc-4.9
$ gcc-4.9 --version
gcc-4.9 (Homebrew gcc 4.9.2) 4.9.2
Copyright (C) 2014 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.
mpicc may have been linked to the Apple gcc:
$ which mpicc
/usr/local/bin/mpicc
$ mpicc --version
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
My questions are as follows:
How do I get the /usr/local/bin/gcc symbolic link? Or is Homebrew deliberately avoiding this for certain reasons? e.g. if Homebrew is compiling all its packages using Apple gcc, which is assumed to be in the path, would changing the path to gcc-4.9 mean that Homebrew now compiles its packages with gcc-4.9 instead?
Is the Homebrew-installed Open MPI linked to the Apple gcc (and not the Homebrew gcc)? If yes, is it possible (or advisable) to change the linking?
Alternatively, how necessary is it to fix the linkages? Could I run into certain problems if I choose not to fix it? For example, I'm considering using ln -s to forcibly create the /usr/local/bin/gcc symbolic link. But is this a good idea (*)?
(*) I understand there are likely to be issues when linking object files created by different compilers. So with (1), (2) and (3), I'm hoping to find a solution that avoids combinations whereby I'm creating object files with different compilers (some with gcc-4.9 and some with the Apple gcc).
You need to do the following:
1) Add environment variables for homebrew (you can also add these lines to your ~\.bashrc):
$ export HOMEBREW_CC=gcc-4.9
$ export HOMEBREW_CXX=g++-4.9
2) Rebuild and reinstall openmpi and its dependencies from source
$ brew reinstall openmpi --build-from-source
3) In the end you will get a message like:
==> Reinstalling open-mpi
==> Using Homebrew-provided fortran compiler.
This may be changed by setting the FC environment variable.
==> Downloading http://www.open-mpi.org/software/ompi/v1.8/downloads/openmpi-1.8.
Already downloaded: /Library/Caches/Homebrew/open-mpi-1.8.4.tar.bz2
==> ./configure --prefix=/usr/local/Cellar/open-mpi/1.8.4 --disable-silent-rules
==> make all
==> make check
==> make install
Warning: open-mpi dependency gcc was built with a different C++ standard
library (libstdc++ from clang). This may cause problems at runtime.
🍺 /usr/local/Cellar/open-mpi/1.8.4: 785 files, 23M, built in 41.2 minutes
$ mpicc --showme
gcc-4.9 -I/usr/local/Cellar/open-mpi/1.8.4/include -L/usr/local/opt/libevent/lib -L/usr/local/Cellar/open-mpi/1.8.4/lib -lmpi
On my MacBook I had some conflicts with XCode 6.2, which were solved following this instructions
If you want to install mpich
$ unlink openmpi
$ brew unlink gcc
$ brew install homebrew/versions/gcc5
$ brew install mpich --build-from-source
$ mpicc -v
mpicc for MPICH version 3.2
Using built-in specs.
COLLECT_GCC=gcc-5
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc5/5.4.0/libexec/gcc/x86_64-apple-darwin14.5.0/5.4.0/lto-wrapper
Target: x86_64-apple-darwin14.5.0
Configured with: ../configure --build=x86_64-apple-darwin14.5.0 --prefix=/usr/local/Cellar/gcc5/5.4.0 --libdir=/usr/local/Cellar/gcc5/5.4.0/lib/gcc/5 --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-5 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl014 --with-system-zlib --enable-libstdcxx-time=yes --enable-stage1-checking --enable-checking=release --enable-lto --disable-werror --with-pkgversion='Homebrew gcc5 5.4.0' --with-bugurl=https://github.com/Homebrew/homebrew-versions/issues --enable-plugin --disable-nls --enable-multilib
Thread model: posix
gcc version 5.4.0 (Homebrew gcc5 5.4.0)
It would probably be cleaner if you simply modify the configuration file for the Open MPI compiler wrapper and make it invoke gcc-4.9 instead of simply gcc. As I have no idea where exactly Homebrew puts Open MPI and therefore cannot give you the correct path directly, you should search for it:
$ find /usr/local -name mpicc-wrapper-data.txt
Once you have found mpicc-wrapper-data.txt, find the line that starts with compiler= and modify it to read:
compiler=gcc-4.9
You should also modify all other files that match the shell glob mpi*-wrapper-data.txt and modify the compiler=... line accordingly. Use g++-4.9 in mpic++, mpicxx, and mpiCC. Use gfortran-4.9 (if installed) in mpif77 and mpif90 (for Open MPI versions < 1.8) or for mpifort (for versions >= 1.8).
Mixing object code produced by different compilers on the same platform should be fine as long as all of them adhere to the same ABI, which is more or less the case with Clang and GCC. In the end, all programs are linked against the system libraries that come with OS X and those are compiled with Clang only.
I wanted to configure an autotooled project to invoke a non-standard
linker (the gold linker),
using the stock autotools of Linux Mint 16/Ubuntu 13.10
I believed I would achieve this by:
libtoolize-ing the project
Running ./configure LD=/path/to/my/linker ... etc.
However this has been ineffective. libtoolize has been successful. After
a standard ./configure; make I now see that libtool is doing the
linking:
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -o helloworld helloworld.o
But passing LD=/path/to/my/linker to configure makes no difference. Experimentally,
I even ran:
./configure LD=/does/not/exist
expecting to provoke an error, but I didn't. The output contains:
checking if the linker (/does/not/exist -m elf_x86_64) is GNU ld... no
checking whether the g++ linker (/does/not/exist -m elf_x86_64) supports shared libraries... yes
And thereafter a make continues to link, successfully, invoking g++ exactly as before.
What is the right way to configure a non-standard linker?
But passing LD=/path/to/my/linker to configure makes no difference
This is because LD is almost never and should almost never be used to link any user-space program. Correct links are performed by using the appropriate compiler driver (gcc, g++, etc) instead.
What is the right way to configure a non-standard linker?
If you have /some/path/ld and you want gcc to use that ld, pass -B/some/path flag to gcc.
It then follows that you likely want:
./configure CC='gcc -B/some/path' CXX='g++ -B/some/path' ...
I landed on this via a Google search, though my scenario is a bit different from yours; there was no libtool involved. An old open source program's Makefile was hard-coding ld to create an object file with a symbol from binary data.
This is what I ended up doing to work around the lack of $(LD) being recognized when passed to configure:
https://github.com/turboencabulator/tuxnes/commit/bab2747b175ee7f2fc3d9afb28d69d82db054b5e
Basically I added to configure.ac:
AC_CHECK_TOOL([LD], [ld])
Leaving this answer here for if someone else lands via a google search.
I type gcc hello.c and this appears:
gcc: internal compiler error: Illegal instruction (program as)
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
hello.c is just:
int main()
{
return 0;
}
I can't think of any way to make it simpler! (The same happened with printf in there.)
So: how do you fix this? I'm on Raspian, on Raspberry Pi.
Edit
gcc -v gives
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.6/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.3-14+rpi1' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-sjlj-exceptions --with-arch=armv6 --with-fpu=vfp --with-float=hard --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
Thread model: posix
gcc version 4.6.3 (Debian 4.6.3-14+rpi1)
No I didn't install it.
As for updates, sudo apt-get install gcc gives
Reading package lists... Done
Building dependency tree
Reading state information... Done
gcc is already the newest version.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Yes, you can run as, it says Illegal instruction with no arguments.
I have no idea what swap space is.
gcc -O0 -g hello.c gives the same error.
gcc does not recognise --enable-debug.
Got it! I uninstalled gcc, installed gcc-4.7, and ... nothing.
I cleared out the end of gcc-4.6 and re-ran sudo apt-get install gcc-4.7 and ... nothing.
I updated binutils and ... it worked!
So, as didn't appear to be affected by updating GCC, but updating it more directly did it for me.
(It was from 2.22-7.1 to 2.22-8, if that helps anyone.)
I can only shed some light on the error message:
gcc: internal compiler error: Illegal instruction (program as)
gcc does several things when compiling. It first translates your C program into assembler and then converts the assembler into machine code.
The name of the assembler program with gcc is just as. So the error message tells you, that running the assembler fails, because the assembler executable contains an illegal instruction.
This might really be an hardware error, meaning that the executable of the assembler is broken.
To check:
Does gcc -S hello.c work ? That should create a "hello.s" containing the C code compiled to assembler
You might try with gcc -v -c hello.c to find out what happens exactly.
Found on raspberryPi forums:
Grabbed the sources and tried a cross-compile on an x86-64 box for a generic arm target. Something inside filter/hq2x.cpp is causing GCC to go nuts and consume memory & swap, so I wouldn't be at all surprised if it triggers a fatal error on a Pi. Some sources suggest that it is the compiler's (cc1plus) internal stack overflowing.
One possible fix is to run the configure script with --enable-debug - This should reduce optimization to a minimum and avoid stack overflows at the expense of increased binary size.
So you can try to set compiler flags to
-O0 -g
and check whether it helps.
Got similar problem.
But it happened after move of VirtualBox image (with Xubuntu 16.04/gcc-5) from Haswell based machine to Sandy Bridge. Problem was somewhere in build-essential / gcc / binutils packages. I reinstalled all of them (with apt remove and apt install - no oneshot reinstall) - it helped.
Try updating the compiler and try
sudo apt-get install build-essential
That might solve the problem.