Homebrew linking fails with incompatible i386 files already on machine - gcc

I'm hitting this error with anything I have tried to install.
The machine is running redhat and devops has installed newer versions of programs/components in non-standard locations. I only have user level access.
I have forced homebrew to use non-standard locations of curl and git, but I do not know how to point to a newer version of gcc or tell it to add options to the linker to handle the older (glibc?) files.
ld: i386 architecture of input file '/lib/crti.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file '/lib/crtn.o' is incompatible with i386:x86-64 output
Thanks for any help.

First adjust LD_LIBRARY_PATH and LIBRARY_PATH variables so that multiarch lib-dirs take lead of other ones. For example, /lib/x86_64-linux-gnu stands before /usr/lib64 and /lib. Now, make this link:
ln -s /lib64 /lib/x86_64-linux-gnu
The above linking assumes you do not have /lib/x86_64-linux-gnu directory. If you have that directory but it is empty, please first remove it then make link. If that directory is not empty, make individual library linking:
ln -s /lib64/crti.o /lib/x86_64-linux-gnu/crti.o
ln -s /lib64/crtn.o /lib/x86_64-linux-gnu/crtn.o
Overall, to overcome this type of error, the compiler should find correct library (regarding 32bit or 64bit architecture) and necessarily in multiarch lib-dirs, which are:
/usr/lib/i386-linux-gnu
/usr/lib/x86_64-linux-gnu
/lib/i386-linux-gnu
/lib/x86_64-linux-gnu
Also take a look at my answer to similar (though opposite) error here.

Related

GCC ld: can't find -lcurses

I'm trying to use make install, and I get error:
cannot find -lcurses
In my /usr/lib/curses/ I have two files: libcurses.so and libcurses.a.
So I do have that library, gcc just doesn't see it. I've read almost everything I can find but still couldn't make this work.
Any help would be appreciated.
This is output:
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: skipping incompatible /usr/lib/libcurses.so when searching for -lcurses
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: cannot find -lcurses
collect2: error: ld returned 1 exit status
Makefile:125: recipe for target 'samtools' failed
make: *** [samtools] Error 1
Note: I've read every similar topic on this website, so please, don't mark this as duplicate.
The linker says:
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: \
skipping incompatible /usr/lib/libcurses.so when searching for -lcurses
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: cannot find -lcurses
You are performing a 64-bit build, but the the only libcurses.so the linker
can find is 32-bit, so it is skipped.
It is unclear from your several postings how this 32-bit /usr/lib/libcurses.so got
there. The official latest openSUSE
curses runtime package is libncurses5-5.9-53.4.x86_64.rpm. The official latest developent package is ncurses-devel-5.9-53.4.x86_64.rpm.
If you install either of these packages, they do not place any 32-bit binaries under /usr/lib, so I surmise
that your /usr/lib/libcurses.so got there in some unorthodox way.
Delete this /usr/lib/libcurses.so. Install the ncurses-devel rpm from your distribution's package manager,
e.g.zypper install ncurses-devel. To make sure you have done it successfully, check that /usr/lib64/libncurses.so exists afterwards.
Then in your makefile change:
LIBCURSES= -lcurses
to:
LIBCURSES= -lncurses
You will find that this change is described in paragraph 3 of the samtools INSTALL file.
You need a development library for ncurses installed, i.e., ncurses-devel (for SuSE).
Without the development library, the shared libraries for ncurses are only present as runtime files.
The ncurses development package installs files or symbolic links to make these options work: -lcurses, -lncurses (since the former is standard). It also installs the file to make -lncursesw link, but OP is not using that.
That message
skipping incompatible /usr/lib/libcurses.so
makes it seem as if OP copied files from some other system rather than installing OpenSuSE packages.
The extra question in SuperUser (GCC ld: can't find -lcurses) gives more information, but not enough to see why the file /usr/lib/libcurses.so is incompatible. It may be conflicting with the development package, however.

Fedora 21 with clang, without gcc

Can you (reasonably) get Fedora 21 to where it only has llvm/clang/libc++/libc++abi? (I found some things suggesting no, but they were all about 3 years old, and llvm/clang has come a long way since then.)
With a fresh install, I tried
yum install gcc gcc-c++
(downloaded, built, installed llvm/cfe(clang)/compiler-rt/libcxx/libcxxabi from svn)
yum remove gcc gcc-c++
added to /etc/profile: export CC=/usr/local/bin/clang \ export CXX=/usr/local/bin/clang++
(in case of hard wiring)
ln -s /usr/local/bin/clang /usr/local/bin/gcc
ln -s /usr/local/bin/clang /usr/local/bin/cc
ln -s /usr/local/bin/clang++ /usr/local/bin/g++
ln -s /usr/local/bin/clang++ /usr/local/bin/c++
ldconfig
I was all happy, then went to build something, and I got:
ld: cannot find crtbegin.o
ld: cannot find -lgcc
ld: cannot find -lgcc_s
clang -v includes
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.9.2
ldconfig && ldconfig -p | grep libgcc does show
libgcc_s.so.1 (libc6,x86-64) => /lib64/libgcc_s.so.1
And /lib64 is a symlink to /usr/lib64. And, /usr/lib64/libgcc_s.so.1 is a symlink to /usr/lib64/libgcc_s-4.9.2-20150212.so.1, which exists as a real file (92816 bytes.)
So, I don't get what ld's problem is on -lgcc_s. crtbegin is nowhere to be found, and gcc (no _s) is nowhere to be found.
yum install libgcc says it's already installed and latest version, nothing to do.
Since I have an installed clang source build, can I re-build clang, this time using clang rather than gcc, to get rid of the dependency? (Maybe then the "candidate GCC installation" bit goes away.)
Can I force -stdlib=c++ and -lc++abi to be default, or at least have libc++ and libc++abi installed without gcc?
Having spent some time trying to get clang to work with libc++ and libc++abi without GCC, I have found that it is indeed possible, even if a bit problematic given the current state of LLVM/clang. In addition to small test programs, I've been able to build CMake and some other software packages written in C++ with no GCC installed, and with the resulting binaries being independent of libstdc++; they only depend on libc++/libc++abi according to ldd output. Unfortunately, I haven't been able to build clang itself with clang that was build using GCC. I've been experimenting on different Linux platforms (Fedora 21 32-bit, Amazon Linux release 2015.3 (RPM-based) 64-bit, CentOS 7.1 64-bit, and Ubuntu 14.04 64-bit).
Even though one can build software with clang using libc++/libc++abi without dependency on libstdc++ and without GCC compiler present, a typical Linux installation is so tied to libgcc and libstdc++ that getting rid of these is not practical. Try removing these two packages and you will see how much of the system depends on them. Even on FreeBSD 10.1, with clang being the default compiler and no GCC installed, libgcc.a, libgcc_s.so, and a few crt*.o files are used when building a program as revealed by the -v option. Also, on FreeBSD 10.1, resulting binaries depend on libgcc according to ldd. On Ubuntu, which has dpkg as the package manager, the files
libgcc.a
libgcc_s.so
crtbegin.o
crtbeginT.o
crtbeginS.o
crtendS.o
crtend.o
are in the libgcc-devel package, while on an RPM-based system, such as Fedora, these are in the gcc package. In addition, you might possibly need these files, even though I didn't need them for the code I tried building:
crtfastmath.o
crtprec32.o
crtprec80.o
crtprec64.o
Thus one might argue that the aforementioned files better belong in libgcc, rather than in gcc. As far as I can tell, the following needs to be done on an RPM-based system before removing the gcc package:
1) Create the symlink
libgcc_s.so -> libgcc_s.so.1
in whatever directory libgcc_s.so.1 is located.
2) Copy the crt*.o files listed above to that directory.
3) In the same directory create the symlink (libstdc++.so.x should already be there; x is a number):
libstdc++.so -> libstdc++.so.x
You only need this if you are going to use libstdc++; this isn't needed if you only plan to use libc++. On some
systems libstdc++.so, which is a symlink to libstdc++.so.x belonging to the libstdc++ package, is placed by the libstdc++-devel package into the GCC library directory, so you can remove that directory after uninstalling GCC and just create the symlink in the same directory where libstdc++.so.x lives.
Now you should be able to do the following:
1) Build a C program:
clang progname.c
2) Build a C++ program using libstdc++ headers/libs:
clang++ -I<location of headers> progname.cpp
On RPM-based systems I've looked at, the libstdc++ headers are part of the libstdc++-devel package and their location can be found from rpm -ql on the package.
3) Build a C++ program using libc++ headers/libs:
clang++ -I/<location of headers> progname.cpp -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc -lgcc_s
The location of the headers is wherever they were installed when you built LLVM+clang etc.
Please see http://libcxx.llvm.org/ for additional information. When building C++ code using libc++/libc++abi, you may use -stdlib=libc++ instead of the -I flag, but in my testing that only worked with clang built from source, not with clang installed from a repository (you can install clang from repo and use it to build libc++/libc++abi; or you can use gcc to build libc++(abi), then remove gcc and use the libs with the repo-provided clang).
When configuring a software package to build it using clang + libc++, you might need to set the following:
LIBS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
CXX=clang++
CXXFLAGS="-stdlib=libc++"
CC=clang
Please note that to configure CMake source in order to build it I had to use a wrapper script like this:
#!/bin/bash
MYLFLAGS="-nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc"
# Catch the case when we only want to compile; this helps us avoid some warnings:
if echo "$#" | egrep "(^-c | -c | -c$)" >/dev/null 2>&1; then
MYLFLAGS=""
fi
/usr/local/bin/clang++ -stdlib=libc++ "$#" $MYLFLAGS
It might be useful for other purposes as well.
For more information please see my article at http://www.omniprog.info/clang_no_gcc.html

How do I change GCC's default search directory for crti.o?

I'd like to specify GCC's search directory for the startfile and
endfile: crt1.o, crti.o and crtn.o. Passing -B on the command line to
the GCC driver works, but is inconvenient. How do I modify the specs
file (lib/gcc/x86_64-unknown-linux-gnu/4.9.2/specs) to specify the search path for startfile?
I tried adding the -B option to the startfile spec and got the error:
ld: unrecognized option '-B/gsc/btl/linuxbrew/lib'
I then tried adding the -B option to the cc1 spec and got the error:
cc1: error: command line option '-B/gsc/btl/linuxbrew/lib' is valid
for the driver but not for C
If it's not possible to do this via the specs file, is there an environment variable or a configure option to GCC that accomplishes the same goal?
I've installed a recent version of glibc in my home directory. Everything's working great. I've modified the specs file to link against the new version of glibc, but it's still linking against the old system version in /usr of startfile and endfile.
Here's a the unanswered question on the gcc-help mailing list. Here's a related Linuxbrew bug, gfortran is broken with stand alone Linuxbrew, and a proposed fix, gcc, binutils: link to Cellar instead of system libs.
Thanks,
Shaun
You can use an absolute path in the *startfile: and *endfile: sections in the specs file, instead of the default relative paths. This will override GCC's choice of the default location.
As per https://wiki.debian.org/Multiarch/LibraryPathOverview, gcc will look for startup files such as crt1.o in $(sysroot)/lib, so you can specify the --sysroot option when running gcc, or compile gcc with --with-sysroot.

Compiling gcc-4.1

Unfortunately I'm forced to use gcc-4.1 and I'm using debian wheezy. Since gcc-4.1 is not in repository I'm trying to build gcc from sources.
But I'm getting compiling error:
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libc.so when searching for -lc
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libc.a when searching for -lc
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/lib/x86_64-linux-gnu/crti.o' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/lib/x86_64-linux-gnu/crtn.o' is incompatible with i386 output
It looks that ld is picking wrong version of libraries, but I checked my /usr/lib32 and /usr/lib/x86_64-linux-gnu/ and it contains those files:
/usr/lib32/libc.a
/usr/lib32/libc.so
/usr/lib32/crtn.o
/usr/lib32/crti.o
/usr/lib/x86_64-linux-gnu/libc.a
/usr/lib/x86_64-linux-gnu/libc.so
/usr/lib/x86_64-linux-gnu/crtn.o
/usr/lib/x86_64-linux-gnu/crti.o
And ld should have access to them
~$ echo $LIBRARY_PATH
/usr/lib/x86_64-linux-gnu:/usr/lib32/
So I have no idea where the problem is.
I managed to work around the problem.
Run configure with:
./configure --disable-multilib ...
But than I encountered another problem with makeinfo, if you have newer version >=4.10 than it might not be found by configure. So simple fix in generated makefile worked for me:
Change this line:
MAKEINFO = /home/lecopivo/Downloads/gcc412/gcc412/gcc-4.1.2/missing makeinfo
To this:
MAKEINFO = makeinfo
I found this helpful.
LD_LIBRARY_PATH is only for running programs already linked.
You probably need to set LDFLAGS when you configure gcc:
./configure LDFLAGS="-L/usr/lib32" .....
It might be LDFLAGS_FOR_HOST or LIBS or something like that though.
I had this problem recently and finally solved it this way:
ln -s /usr/lib32 /usr/lib/i386-linux-gnu
Notes:
I assumed you do not have /usr/lib/i386-linux-gnu directory in your 64bit linux. If this directory exists and is empty, please delete it and make the above link.
If the directory already exists and is not empty, you have to make links inside it for (32bit) libraries which cause build error one by one; e.g.:
ln -s /usr/lib32/crti.o /usr/lib/i386-linux-gnu/crti.o
ln -s /usr/lib32/crtn.o /usr/lib/i386-linux-gnu/crtn.o
...
If 32bit development libraries are not installed, you may have to install them first. I've searched different forums and found that installing following set of packages in ubuntu will provide them:
libc6-dev libc6-dev-i386
gcc-multilib g++-multilib
zlib1g-dev lib32z1-dev
libncurses5-dev lib32ncurses5-dev libncursesw5-dev lib32ncursesw5-dev
Also adjust LD_LIBRARY_PATH and LIBRARY_PATH variables so that they contain /usr/lib/i386-linux-gnu and /usr/lib/x86_64-linux-gnu (i.e. multiarch lib-dirs). I am not sure which one of above variables is effective, so I adjust both of them the same.
If you use ./configure --disable-multilib as it is frequently suggested on web, though gcc will be built, but when you want to use that gcc for compiling e.g. legacy grub, you probably get error of "gcc cannot build executable" (or such).
Optionally, you can make similar linking for these pair of libdirs:
ln -s /lib32 /lib/i386-linux-gnu
Doing so, I managed to compile gcc-3.4.6 in a Ubuntu 16.04.6-amd64 used for compiling old 32bit programs like SDL 1.2 and legacy GRUB4DOS 0.4.4.
Also take a look at my answer to similar (though opposite) error here.
Good luck.

GLIBCXX_3.4.9 not found

I have a problem concerning libstdc++.so.
I installed a new version of gcc and tried to compile C++ code. The compiling worked, but when I try to execute the binary (m5.opt is its name) I've got the following error:
build/ALPHA_SE/m5.opt: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by build/ALPHA_SE/m5.opt).
Do I need to replace libstdc++.so? And if so, where can I download the version I want? On the GCC-website they say libstdc++ is a part of gcc now.
Details
GCC:
I had gcc 4.1.2 before, but I downloaded gcc 4.2.4. From the untarred gcc-directory I executed ./configure; make; sudo make install`.
When I tried to use gcc or g++ to compile, it's default version was still 4.1.2. To overcome this I replaced some links:
mv /usr/bin/gcc /usr/bin/gcc_bak
ln -s /usr/local/bin/gcc gcc
mv /usr/bin/g++ /usr/bin/g++_bak
ln -s /usr/local/bin/g++ g++
GLIBC(++) -- libstdc++:
/usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.8
/usr/local/lib/libstdc++.so -> libstdc++.so.6.0.9
/lib/libc.so.6 -> libc-2.5.so -> libc-2.5.so
Linux-version:
uname -a gives:
Linux madmax 2.6.18-128.4.1.el5 #1 SMP Tue Aug 4 12:51:10 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
The problem is that you built your new GCC incorrectly: on Linux you should use
./configure --prefix=/usr
The default installation prefix is /usr/local, which is why make install put gcc and g++ binaries into /usr/local/bin, etc.
What's happening to you now is that you compile and link using the new (symlinked) GCC 4.2.4, but at runtime your program binds to the old /usr/lib64/libstdc++.so.6 (version 6.0.8, instead of required 6.0.9). You can confirm that by running ldd build/ALPHA_SE/m5.opt: you should see that it uses /usr/lib64/libstdc++.so.6.
There are several fixes you could do.
env LD_LIBRARY_PATH=/usr/local/lib64 ldd build/ALPHA_SE/m5.opt
should show you that setting LD_LIBRARY_PATH is sufficient to redirect the binary to correct library, and
LD_LIBRARY_PATH=/usr/local/lib64 build/ALPHA_SE/m5.opt
should just run. You could "bake" this path into m5.opt binary by relinking it with -Wl,-rpath=/usr/local/lib64.
A more permanent solution is to fix the libraries the same way you fixed the binaries:
cd /usr/lib64 && mv libstdc++.so.6 libstdc++.so.6_bak &&
ln -s /usr/local/lib64/libstdc++.so.6 .
An even better solution is to reconfigure the new GCC with --prefix=/usr, and then make all install.
I know this is a very old question, but ...
It's not usually a good idea to replace the system compiler (i.e. the one in /usr) because the entire system will have been built with it and depend on it.
It's usually better to install the new compiler to a separate location and then see the libstdc++ FAQ How do I insure that the dynamically linked library will be found? and Finding Dynamic or Shared Libraries in the manual for how to ensure the correct libstdc++.so is found at runtime.
The other answers here should be fine, but the 'quick and easy' solution if you do happen to have gcc installed to /usr/local/ is to just add the new libs to the LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
You can also check the to see if you have the right versions of GLIBC installed using
strings /usr/lib/libstdc++.so.6 | grep GLIBC
strings /usr/local/lib64/libstdc++.so.18 | grep GLIBC
I got this last tip from another forum so credits due where credits due!

Resources