Cannot find /lib/libc.so.6 - linker

I'm cross-compiling an application, but linking blows up with an error that it
"cannot find /lib/libc.so.6".
The libc.so.6 that it should be using is the one that sits at /home/work/worldcom/filesys/lib/libc.so.6. What have I got wrong here?
linking libobj.so
arm-none-linux-gnueabi-g++ obj1.o obj2.o obj2.o -o libobj.so -L/home/work/worldcom/filesys/usr -Wl,-O1 -Wl,-z,defs -Wl,--enable-new-dtags -Wl,--sort-common -Wl,--as-needed -Wl,--hash-style=both -L/home/work/worldcom/filesys -L/home/work/worldcom/filesys/lib -L/home/work/worldcom/filesys/usr/lib -lcurl -shared
/home/lishevita/armv5tel/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/bin/ld: skipping incompatible /lib/libc.so.6 when searching for /lib/libc.so.6
/home/lishevita/armv5tel/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find /lib/libc.so.6
collect2: ld returned 1 exit status<br />
make: *** [libobj.so] Error 1<br />
My makefile is handwritten (i.e. not generated by Autotools). In order to avoid a blanket "your Makefile is broken" here are some details from the makefile that might help clarify.
CROSS_COMPILE = arm-none-linux-gnueabi-
SYSROOT = /home/work/worldcom/filesys/
DESTDIR = /home/work/worldcom/filesys/
RELEASE_CXXFLAGS = -Os
DEBUG_CXXFLAGS = -O0 -gstabs
PKGCONFIG=`env ROOT=/home/work/worldcom/filesys cross-pkg-config glib-2.0 libcurl --cflags`
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar
LDFLAGS = -Wl,-O1 -Wl,-z,defs -Wl,--enable-new-dtags -Wl,--sort-common -Wl,--as-needed -Wl,--hash-style=both -L$(SYSROOT) -L$(SYSROOT)lib -L$(SYSROOT)usr -L$(SYSROOT)usr/lib -lcurl
libobj.so: $(LIBOBJ_OBJS)
#echo linking $#
$(CXX) $^ -o $# $(LDFLAGS) -shared $(PKG_LIBS)
Of course there is also a definition and target for the LIBOBJ_OBJS but those are irrelevant to the problem.

You didn't indicate what gcc version you are using, but if it is a recent enough one (4.0.0 and above me thinks) you should try adding the --sysroot flag to g++/ld. Point it to $SYSROOT as defined in your Makefile. For example:
--sysroot=$(SYSROOT)
Assuming recent enough gcc version, it will work.

I just went through the same issue; adding --sysroot=/rootfs/prefix helped me get closer to the real issue. I got it fixed by installing package libstdc++-dev in target.

Have you not considered that possibly the LIBPATH is set and hard-coded to look for the /lib/libc.so.6 and therefore the /lib path?
Have you tried to set the environment variable like this on the command line, prior to issuing make when cross-compiling:
LIBPATH=/home/work/worldcom/filesys/lib
In your specific case, as you have mentioned in the tag 'cross-compiling', it might be worth it to remove any references to /lib to wholly force the linker to look in your own home directory instead as not to interfere with the cross-compile process.
The other possibility is that the gcc compiler when it was built for your environment, the configuration during the building of the compiler from source, was specified to point to the /lib path.
Hope this helps,
Best regards,
Tom.

It seems that the makefile is broken, because the libc.so.6 is assumed to be located in the /lib/ folder (note the preceding slash indicating an absolute path! ). This seems to be the issue.

Related

Linking with shared libraries

I'm trying to compile and link some .c file. I have been using Eclipse IDE for C/C++ developers, and in my local machine i can compile without problems. However, when i try to compile and link the same file in a RedHat OS (gcc version is 4.9.2-6 in this OS) i'm having problems. I get some warnings at compile time, but those are fine, i think, i just ignored and the application still runs fine. Here are the commands i executed and the associated output:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -MMD -MP -MF"example.d" -MT"example.d" -o "example.o" "example.c"
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
warning: implicit declaration of function ‘wait’ [-Wimplicit-function-declaration]
This generates two files, example.d and example.o. Then, i try to link them, without luck, with the following command:
gcc -Xlinker -L/usr/lib -lrt -static -pthread example.o -o example
/usr/bin/ld: cannot find -lrt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
The commands are taken directly from the ones that Eclipse generates, and work just fine in my local computer (Ubuntu OS) but not in the RedHat environment. The last command didn't work, with and without the -L option. I suppose the directory in -L is fine, as i run, for example,
locate libpthread.so
And one of the locations i get is /usr/lib (also /usr/lib64, but neither work).
Any help will be greatly appreciated!! :)
If you try to link a static executable, it will look for the *.a versions of the libraries, not what you usually want. Remove the -static flag. Or you can install the static libraries if you really want to. It also should not be necessary to add -L/usr/lib explicitly.

undefined reference to `explain_read' ...... No such file or directory

I need to include libexplain to my project to do certain job. I install it and add the header libexplain/read.h to my code, so far so good and no error reported by the complier. But when I use the function explain_read() provided by libexplain and build the project it says:
/tmp/cc7NjAw0.o: In function `xl45_read(int, unsigned char*)':
connections.cpp:(.text+0x2f): undefined reference to `explain_read'
collect2: error: ld returned 1 exit status
and the build script is:
#!/bin/bash
echo > ./stdafx.h
g++ -O1 -Wall -o ./local_proxy (*.cpp...here is the source file list) -lz -lpthread -lpcap -L/usr/local/lib
actually when I type
whereis libexplain
in terminal, I get
libexplain: /usr/lib/libexplain.so /usr/lib/libexplain.a /usr/include/libexplain
I do a lot of searches and still have no idea what's going wrong. ):
You need to link your object files with libexplain. You can do it using the -l<library name>, like so:
g++ -O1 -Wall -o ./local_proxy *.cpp -lz -lpthread -lpcap -lexplain -L/usr/local/lib
Note the -lexplain flag. For a library with the a file name like libABC.so, you'd use -lABC to refer to that library. The documentation for link options with GCC can shed more light on it.

How do I link the correct library so __aeabi_idiv and __aeabi_idivmod work?

This is the question I'm following up on. I have the same problem as regomodo did in that thread way back in 2011:
I'm trying to run a little program on my Raspberry Pi, and I'm using operators that aren't natively supported by ARM:
hello.c:(.text+0x64): undefined reference to `__aeabi_idiv'
hello.c:(.text+0x7c): undefined reference to `__aeabi_idivmod'
I understand that I need to link a library that knows about division and modding, but I can't quite get that to work (newbie to the Makefile life).
So I gave it a kind of pathetic stab and tried just adding the -lgcc:
LDFLAGS = -L../lib -lgcc
that wasn't super fruitful:
arm-none-eabi-ld: cannot find -lgcc
any advice would be so appreciated.
[edit1] here's the start of my makefile:
ARMGNU ?= arm-none-eabi
CPPFLAGS = -I../include
CFLAGS = $(ARCHFLAGS) -Wall -O2 -nostdlib -nostartfiles -ffreestanding
LDFLAGS = -L../lib -lgcc
LIBS = -lpi
Make sure the libgcc.a archive is in the path you specify in your Makefile.
I know is quite late, but I was having the same problem, I'm using ArchLinux and it turns out that the libgcc.a file was not located at
/usr/arm-none-eabi/lib/
and/or its child folders which is the default installation directory for arm-none-eabi compiler in my system, instead, the libgcc.a library is located at
/usr/lib/gcc/arm-none-eabi/(version)
So whatever system you're using, you should look for that library in your default lib directory.

How to solve this linking problem in Makefile?

Here's my Makefile:
DIR=..
ARG=$(QUERY_STRING)
MAIN=main
SRC_DIR=$(DIR)/src
BIN_DIR=$(DIR)/bin
INC_DIR=$(DIR)/inc
LIB_DIR=$(DIR)/lib
LIBS=markdown
all: $(MAIN) exec
$(MAIN): $(MAIN).o
$(LD) $^ -L $(LIB_DIR) -l $(LIBS) -o $(BIN_DIR)/$#
$(MAIN).o: $(SRC_DIR)/$(MAIN).c
$(CC) $^ -I $(INC_DIR) -o $#
exec:
$(BIN_DIR)/$(MAIN) $(ARG)
clean:
rm -f *.o core.* $(BIN)/$(MAIN)
It's clearly defined how my project is organized, so I will not explain it. It does compile without any problems, but on binary execution $(BIN_DIR)/$(MAIN) the following error appears:
../bin/main: error while loading shared libraries: rintf: cannot open shared object file: No such file or directory
make: *** [exec] Error 127
What library does rintf belong? I tried to link -lc too, but that doesn't solves the problem.
Is there something wrong with my Makefile? Or should I link something extra to $(MAIN)?
Thanks in advance for your responses.
You should essentially never link a program by invoking ld directly; always use your compiler to do the linking. It passes all sorts of extra arguments to ld to make things work. Replace the $(LD) with $(CC). Do that regardless of whether it actually fixes your problem or not.
'Tis odd that you are not getting the name of the shared object specified in the error message.
This manual page for rintf() indicates that it is declared in <math.h>; most likely, you need to add the maths library to the link line: -lm.
I would rewrite some of your makefile:
LIB1 = -lmarkdown
LIB2 = -lm
LIBS = $(LIB1) $(LIB2)
LDFLAGS = -L $(LIB_DIR)
...
$(MAIN): $(MAIN).o
$(CC) $^ $(LDFLAGS) $(LIBS) -o $(BIN_DIR)/$#
Usually, this error appears when the linker is not able to find the needed shared object (.so file).I am assuming Linux platform.
In Linux OS, you can search for the file using: find, or locate. If you can find the .so file, try to update the linker cache using ldconfig. If it did not work, check the linker configuration files under /etc/ld.conf.d/ to see if the library path is included. If you changed the configuration, don't forget to update the cache again!

How to link a specific version of a shared library in makefile without using LD_LIBRARY_PATH?

I know that LD_LIBRARY_PATH is evil and it's a good habit to avoid using it.
I have a program called server.c on a remote Solaris 9 server that holds two versions of openssl library (0.9.8 and 1.0.0) and I'm using gcc 3.4.6. My program need to link to 1.0.0a version. Because it's work environment, I don't have the right to modify anything in the openssl library directory. I figured out to compile my program with both -L and -R options without setting LD_LIBRARY_PATH and it worked fine. (I noticed it won't work without setting -R option) But the compiled program kept linking to /usr/local/ssl/lib/libssl.so.0.9.8 instead of /.../libssl.so.1.0.0. Is there a work-around for this?
BTW, please correct me if I'm wrong: is it the -R option that actually "link" the shared libraries at runtime and -L option only "load" shared libraries at compile time?
Any help will be much appreciated!
Z.Zen
//////////////////////////////////////////////
Here is my Makefile:
CC = gcc
OPENSSLDIR = /usr/local/ssl
CFLAGS = -g -Wall -W -I${OPENSSLDIR}/include -O2 -D_REENTRANT -D__EXTENSIONS__
RPATH = -R${OPENSSLDIR}/lib
LD = ${RPATH} -L${OPENSSLDIR}/lib -lssl -lcrypto -lsocket -lnsl -lpthread
OBJS = common.o
PROGS = server
all: ${PROGS}
server: server.o ${OBJS}
${CC} server.o ${OBJS} -o server ${LD}
clean:;
${RM} ${PROGS} *.ln *.BAK *.bak *.o
I figured out that I can include the absolute path of the specific library that I want to link to and it worked fine for me:
LD = ${RPATH} -lsocket -lnsl -lpthread ${OPENSSLDIR}/lib/libssl.so.1.0.0 \
${OPENSSLDIR}/lib/libcrypto.so.1.0.0
If you are using g++, Piotr Lesnicki pointed out that -l:libssl.so.1.0.0 also works. See more at the original post.
Do you have any links to the SSL lib?
If not, can you create a link to the the desired SSL lib like
ln -s libssl.so.1.0.0 libssl.so
in the ssl directory and try it

Resources