Build using G++ on Ubuntu for RedHat - linux

Is there any way to link against RedHat static libraries while building on Ubuntu and using GCC?

Copy over the RedHat library and header files to a directory preserving directory structure and give GCC the --sysroot directive to tell it to look in that directory as prefix for searching libs and headers

I see two obvious solutions:
Copy /usr/lib, /lib and /usr/include from a Red Hat system into a subtree and point -I and -L to this subtree.
Install a minimal RedHat into a chroot and compile there.
The first solution is the easiest, but you might run into libc version issues. The second solution is guaranteed to work, but not far from running a complete RedHat for compilation.

Related

Fixing libc.so.6 unexpected reloc type 0x25

I'm trying to install gcc4.9 on a SUSE system without an internet connection. I compiled gcc on an Ubuntu machine and installed it into a prefix, then copied the prefix folder to the SUSE machine. When I tried to run it gcc complained about not finding GLIBC_2_14, so I downloaded an rpm for libc6 online and included it into the prefix folders. my LD_LIBRARY_PATH includes prefix/lib and prefix/lib64. When I try to run any program now (ls, cp, cat, etc) I get the error error while loading shared libraries: /home/***/prefix/lib64/libc.so.6: unexpected reloc type 0x25.
Is there any way I can fix this so that I can get gcc4.9 up and running on this system?
As an alternative, is it possible to build gcc staticaly so that I don't have to worry about linking at all when I transfer it between computers?
my LD_LIBRARY_PATH includes prefix/lib and prefix/lib64
See this answer for explanation of why this can't work.
Is there any way I can fix this so that I can get gcc4.9 up and running on this system?
Your best bet is to install whatever GCC package comes with the SuSE system, then use that GCC to configure and install gcc-4.9 on it.
If for some reason you can't do that, this answer has some of the ways in which you can build gcc-4.9 on a newer system and have it still work on an older one.
is it possible to build gcc staticaly so that I don't have to worry about linking at all when I transfer it between computers?
Contrary to popular belief, fully-static binaries are generally less portable then dynamic ones on Linux.

crosstool-ng, directory structure, and sysroot

I have a working cross-compiler toolchain, thanks to crosstool-ng :) -- however, crosstool-ng is very sparsely documented, and I am brand new to cross-compiling. The specific host and target are not, I think, important in this context.
I have some basic questions about the directory structure. The toolchain was installed into a directory named after the target. Inside that are a set of directories:
arm-unknown-linux-gnueabi
bin
include
lib
libexec
share
I presume this is for the actual cross-compiler bits, since the compilers in bin/ do work for this purpose. Notice that there is an inner arm-unknown-linux-gnueabi/ directory, ie, the path in there is ../arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi. Inside that there is another tree:
bin
debug-root
include
lib
lib32
lib64
sysroot
The lib* directories are symlinks into sysroot/. The stuff in bin seems to be the same set of cross-compile tools as in the parent directory /bin:
> bin/gcc -v
Using built-in specs.
COLLECT_GCC=./gcc
Target: arm-unknown-linux-gnueabi
Configured with: /usr/x-tool/.build/src/gcc-4.7.2/configure
--build=x86_64-build_unknown-linux-gnu
--host=x86_64-build_unknown-linux-gnu
--target=arm-unknown-linux-gnueabi
So my first question is: what are these for? And what is this directory for?
My second question then is: how should sysroot/ be used? It's apparently for support libraries native to the target platform, so I presume if I were building such a library I should use that as the --prefix, although it would amount to the same thing as using the parent directory, since lib* is symlinked...this "directory in the middle" with a bin and symlinks down to sysroot is confusing. I believe (some) autotools style packages can be configured "--with-sysroot". What is the significance of that, if I see it, and how should it be used in relation to other options such as --prefix, etc?
For your first question, as toolchain installed directory:
bin/arm-unknown-linux-gnueabi-gcc
arm-unknown-linux-gnueabi/bin/gcc
They are the same, indeed hard links.
You can use arm-unknown-linux-gnueabi-gcc by CC=arm-unknown-linux-gnueabi-gcc, e.g.
export PATH=<toolchain installed dir>/bin:$PATH
CC=arm-unknown-linux-gnueabi-gcc ./configure
make
Or
export PATH=<toolchain installed dir>/arm-unknown-linux-gnueabi/bin:$PATH
./configure
make
I always used the first form, and I am not sure if the latter form works.
For your second question, in my experience, you don't need to concern about sysroot. cross-compiler will find the correct C header files in sysroot/usr/include automatically.
Except that you want to cross-compile some libraries and install them into sysroot, you can get it by
export PATH=<toolchain installed dir>/bin:$PATH
CC=arm-unknown-linux-gnueabi-gcc ./configure --prefix=<toolchain installed dir>/arm-unknown-linux-gnueabi/arm-unknown-linux-gnueabi/sysroot
make
make install
Starting at 38:39 of the talk Anatomy of Cross-Compilation Toolchains by Thomas Petazzoni, the speaker gives an in-depth walk through of the output directory structure.

asm/errno.h: No such file or directory

While building gcc, I get this error:
In file included from /usr/include/bits/errno.h:25,
from /usr/include/errno.h:36,
from ../.././gcc/tsystem.h:96,
from ../.././gcc/crtstuff.c:68:
/usr/include/linux/errno.h:4:23: error: asm/errno.h: No such file or directory
make[2]: *** [crtbegin.o] Error 1
make[2]: Leaving directory `/opt/gcc-4.1.2/host-x86_64-unknown-linux-gnu/gcc'
I am building gcc 4.1 from source. I think I have to install build-essential. However installing that package in ubuntu 12.04 will automatically download and install gcc 4.6 and I don't want that.
Is there any other way?
I think the package you want is linux-libc-dev . I encountered this when building 32-on-64; so I needed linux-libc-dev:i386 .
This worked for me:
ln -s /usr/include/asm-generic /usr/include/asm
This worked for me:
sudo ln -s /usr/include/asm-generic /usr/include/asm
The reason being that what GCC expects to be called /usr/include/asm is renamed to /usr/include/asm-generic in some distros.
This fixed it for me.
sudo apt-get install linux-libc-dev:i386
This solved it for me on Debian 10, even though I was compiling with an LLVM-based compiler:
sudo apt install gcc-multilib
/usr/include/asm/errno.h is part of the linux headers. I can't speak directly to Ubuntu 12.04, but in general you can download the linux sources as a package for your distro and it shouldn't require you to download/install gcc. Failing that, you can manually download the linux headers for the version of your kernel (uname -a) and use an include directive to CFLAGS to specify the directory to look for those.
Edit: sudo apt-get install linux-headers-generic may work for you.
You are missing part of the development packages. I don't know Ubuntu, but you should be able to ask it's package management system to install the package containing /usr/include/asm/errno.h.
Do not copy some file with a similar name from somewhere on your system (or, even worse, from somewhere else). Missing files might mean that some package is damaged; again, ask your package manager to check everything and (re)install missing/broken pieces.
Unless you are running some LTS release, upgrade. Your Ubuntu is some 2 years old, i.e., ancient.
While we are at this, why on this beautiful planet are you building such an ancient compiler? Current GCC is just released 4.9.0, anything before 4.7 is ancient history, not longer supported.
On Ubuntu 16.04 x86_64 you could try this:
ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/asm
This works on my server.
If you want to use errno.h that is in the asm file, simply go to /usr/(ctrl + l, type /usr/) and then search for errno.h and errno-base.h. Once you did find them, copy the code in these two files, and place them in your include folder. And be careful, in "errno.h" the file includes "errno-base.h" as:
#include <asm-generic/errno-base.h>
Either create a directory with the same name above or change the code above to something different which is suitable for you to use.
If you can find:
usr/include/asm-generic/errno.h
by executing:
find /usr/include -name errno.h
then try to execute:
cp --archive /usr/include/asm-generic /usr/include/asm
It may fix that problem.
I had this issue while compiling Asterisk 1.8.24.0 and solved it with:
mkdir /usr/include/asm-generic
cp /usr/include/asm/errno-base.h /usr/include/asm-generic/
Don't know if it is the "right way" but i've read the comments above and that gave me the idea... and it worked :)

Suse Linux - make test for mpfr says libgmp.so.10 can't be found

I set up an ancient machine with SUSE Linux 10.1, and am trying to build a current distro of gcc, but that wants gmp, mprf and mpc.
Now, I installed gmp successfully, and I find it in /usr/local/include and /usr/local/lib. I also find the shared library libgmp.so.10 in /usr/local/lib. Alas, when I run make check for mpfr, it complains that it can not open the shared object file libgmp.so.10
The question, then, is what do I need to do to tell it where the shared object file is?
Thanks
Ted
Make sure /usr/local/lib is on the LD_LIBRARY_PATH environment variable.
Alternatively, configure mpfr with the --with-gmp=/usr/local/ option. You'll have to do the same with mpc when you build that, but you'll have to also add the --with-mpfr=/usr/local option when configuring it.

How do shared libraries work in a mixed 64bit/32bit system?

Good morning,
on a 64bit RedHat box we have to compile and run a 32bit application. Meanwhile I managed to compile the gcc version needed (4.0.3) and all required runtime libraries in 32bit and have set the LD_LIBRARY_PATH to point to the 32bit versions, but now during the remaining build process, a small java program needs to be executed which is installed in /usr/bin as a 64bit program, which now finds the 32bit version of libgcc_s.so first.
In general, if I set the LD_LIBRARY_PATH to the 32bit versions, I break the 64bit programs and vice versa.
How it this supposed to work at all? I am certain I am not the first person with this problem at hand. How is it solved usually?
Regards,
Stefan
Add both the 32-bit and 64-bit directories to the LD_LIBRARY_PATH.
If you do this, then the ld.so for 32-bit or 64-bit will use the correct libraries.
e.g. A 32-bit test app "test32" and 64-bit test app "test", with a locally-installed copy of a (newer version of) gcc and binutils in a user homedir, to avoid clobbering the system-wide install of gcc:
=> export LD_LIBRARY_PATH=/home/user1/pub/gcc+binutils/lib:/home/user1/pub/gcc+binutils/lib64
=> ldd ./test32
libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib/libstdc++.so.6 (0x00111000)
libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib/libgcc_s.so.1 (0x00221000)
=> ldd ./test
libstdc++.so.6 => /home/user1/pub/gcc+binutils/lib64/libstdc++.so.6 (0x00007ffff7cfc000)
libgcc_s.so.1 => /home/user1/pub/gcc+binutils/lib64/libgcc_s.so.1 (0x00007ffff7ad2000)
(Less interesting library paths removed)
This shows that the loaders know to ignore the libraries of the wrong architecture, at least on this Scientific Linux 6.3 (RHEL-derived) system. I would expect other distros to work similarly, but haven't tested this.
This may have only started being the case more recently than your (unspecified) distro version, however.
On Solaris one can use LD_LIBRARY32_PATH and LD_LIBRARY64_PATH, but that isn't supported on Linux.
In general, you should just never need to set LD_LIBRARY_PATH at all in the first place:
either install needed libraries into
/usr/lib32 or /usr/lib64 as
appropriate, or
build your 32-bit application with -Wl,-rpath=/path/to/32-bit/libs
As a workaround, wrap the Java call in a small shell script which unsets LD_LIBRARY_PATH and then calls the executable. Alternatively, this might also work:
LD_LIBRARY_PATH= java...
Note the space between "=" and the name of the executable.
Just set LD_LIBRARY_PATH to both paths (use colons to delimit). The linker will ignore the libraries that it cannot read.
I have faced this exact same problem when remastering a 32bit tinycore64 system running a 64bit kernel.
After much searching, I have discovered why these comments would make sense to both of them.
"That would be nice, but - at least in my environment - it did not
appear to work. The loader did complain; it did not simply skip the
libraries that do not match the bit-ness. Sadly!" - struppi
"This is very strange, could you describe how things failed? Also,
perhaps post the output of ldd?" - Adam Goode
And why this comment might appear to be true but is actually incorrect.
The linker will ignore the libraries that it cannot read.
This link shed's some light on it.
http://www.markusbe.com/2009/09/about-running-32-bit-programs-on-64-bit-ubuntu-and-shared-libraries/
And more to the point, you will find the ld.so manpage enlightening.
It turns out the path name can make a difference in what the runtime linker ld.so chooses as the library to load. On my 64bit linux system I have a range of odd directory names in addition to the standard ones. e.g. /lib/x86_64-linux-gnu. I actually thought I'd experiment by moving the libraries in that path to /lib64. When I did that, guess what happened? suddenly my 64bit app (brctl in this case) didn't work and complained with "Wrong ELF class". Hello... now we're onto something.
Now I'm not 100% certain but the key seems to be related to rpath token expansion.
I suspect the ${PLATFORM} expansion may have something to do with it. And the name x86_64 must be part of that.
In any case, I found when I put my 64-bit libraries in library paths named
x86_64-linux-gnu as apposed to just lib64, then they were preferred over the 32bit ones and things worked.
In your case, you probably want to do something very similar for 32bit libraries on 64. Try i386-linux-gnu.
So in my case where I am installing 64bit shared libraries onto a 32bit userland, I created the following paths:
mkdir /lib/x86_64-linux-gnu/
mkdir /usr/lib/x86_64-linux-gnu/
ln -s /lib/x86_64-linux-gnu /lib64
ln -s /usr/lib/x86_64-linux-gnu /usr/lib64
Add your 64bit libraries to the 64bit paths and 32bit libraries to the 32bit /lib & /usr/lib paths only.
Then add the 64bit specific paths to ld.so.conf and update your cache with ldconfig
Now your 32-bit & 64-bit applications will run seamlessly.

Resources