I'm trying to compile a program but it throws the following error:
[cc] /usr/bin/ld: cannot find -ludev
I checked other topics on SO but the responses were to install something while I seem to be having libudev installed.
In /lib/x86_64-linux-gnu I also have:
lrwxrwxrwx 1 root root 16 lut 19 21:30 libudev.so.1 -> libudev.so.1.3.5
-rw-r--r-- 1 root root 67600 lut 19 21:31 libudev.so.1.3.5
I've tried linking libudev.so.0 to libudev.so.1 but it's still not working. What is ld looking for and why is it not working? How can I solve this?
When you use -lfoo the linker will look for a file named libfoo.a or libfoo.so.
So in your case, you need libudev.so without any suffix number.
Some Linux distributions, such as Debian and derivates (Ubuntu?), do not install these symlinks by default. So instead of creating that symlink yourself, try first looking for the *-dev package (libudev-dev).
ld is the command for linker, you need to update your LIBPATH variable to include the library location.
check the value of the env variable LIBPATH and change it to LIBPATH=LIBPATH:<lib location> and compile again.
Related
I'm building a project using a GNU tool chain and everything works fine until I get to linking it, where the linker complains that it is missing/can't find crti.o. This is not one of my object files, it seems to be related to libc but I can't understand why it would need this crti.o, wouldn't it use a library file, e.g. libc.a?
I'm cross compiling for the arm platform. I have the file in the toolchain, but how do I get the linker to include it?
crti.o is on one of the 'libraries' search path, but should it look for .o file on the library path?
Is the search path the same for gcc and ld?
crti.o is the bootstrap library, generally quite small. It's usually statically linked into your binary. It should be found in /usr/lib.
If you're running a binary distribution they tend to put all the developer stuff into -dev packages (e.g. libc6-dev) as it's not needed to run compiled programs, just to build them.
You're not cross-compiling are you?
If you're cross-compiling it's usually a problem with gcc's search path not matching where your crti.o is. It should have been built when the toolchain was. The first thing to check is gcc -print-search-dirs and see if crti.o is in any of those paths.
The linking is actually done by ld but it has its paths passed down to it by gcc. Probably the quickest way to find out what's going on is compile a helloworld.c program and strace it to see what is getting passed to ld and see what's going on.
strace -v -o log -f -e trace=open,fork,execve gcc hello.c -o test
Open the log file and search for crti.o, as you can see my non-cross compiler:
10616 execve("/usr/bin/ld", ["/usr/bin/ld", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=both", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o"
, "test", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-g
nu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., "-L/lib/../lib", "-L/usr/lib/../lib", "-L/usr/lib/gcc/x86_64-linux-gnu
/"..., "/tmp/cc4rFJWD.o", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "/usr/lib/gcc/x86_
64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."...], "COLLECT_GCC=gcc", "COLLECT_GCC_OPTIONS=\'-o\' \'test\' "..., "COMPILER_PATH=/usr/lib/gcc/x86_6"..., "LIBRARY_PATH=/usr/lib/gcc/x86_64"..., "CO
LLECT_NO_DEMANGLE="]) = 0
10616 open("/etc/ld.so.cache", O_RDONLY) = 3
10616 open("/usr/lib/libbfd-2.18.0.20080103.so", O_RDONLY) = 3
10616 open("/lib/libc.so.6", O_RDONLY) = 3
10616 open("test", O_RDWR|O_CREAT|O_TRUNC, 0666) = 3
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crt1.o", O_RDONLY) = 4
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crti.o", O_RDONLY) = 5
10616 open("/usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtbegin.o", O_RDONLY) = 6
10616 open("/tmp/cc4rFJWD.o", O_RDONLY) = 7
If you see a bunch of attempts to open(...crti.o) = -1 ENOENT, ld is getting confused and you want to see where the path it's opening came from...
I had the same issue while cross-compiling. crti.o was in <sysroot>/usr/lib64 but the linker would not find it.
Turns out that creating an empty directory <sysroot>/usr/lib fixed the issue. It seems that the linker would search for a path <sysroot>/usr/lib first, and only if it exists it would even consider <sysroot>/usr/lib64.
Is this a bug in the linker? Or is this behaviour documented somewhere?
In my case Linux Mint 18.0/Ubuntu 16.04, I have no crti.o at all:
$ find /usr/ -name crti*
I find nothing so I install developer package:
sudo apt-get install libc6-dev
If you find some libs read here
OK I had to reinstall the tool chain, so that the missing files were then included. It seems strange since it should have found it on the gcc path. The main problem I guess was that I had 15 or so different crti.o files on my computer and wasn't point to the correct one. Still doesn't make since but it works now :-) Thanks for your help :-)
I had a similar problem with a badly set-up cross-compiler. I got around it like so:
/home/rob/compiler/usr/bin/arm-linux-gcc --sysroot=/home/rob/compiler hello.c
This assumes /lib, /usr/include and so on exist in the location pointed to by the sysroot option. This is probably not how things are supposed to be done, but it got me out of trouble when I needed to compile a simple C file.
If you are cross-compiling , add sysroot option in LDFLAGS
export LDFLAGS=""--sysroot=${SDKTARGETSYSROOT}" -L${SDKTARGETSYSROOT}/lib -L${SDKTARGETSYSROOT}/usr/lib -L${SDKTARGETSYSROOT}/usr/lib/arm-poky-linux-gnueabi/5.3.0"
I get the same kind of issue on a default Ubuntu 8.04 install. I had to get the libc developer headers/files manually for it to work.
This solved for me (cross compiling pjsip for ARM):
export LDFLAGS='--sysroot=/home/me/<path-to-my-sysroot-parent>/sysroot'
I'm trying to link a Qt program I have cross-compiled for a MacOS target on a Linux host. I followed the instructions found here (https://github.com/Tatsh/xchain) to succesfully build gcc, and I can compile and link both simple test programs as on that page to produce executables which run fine on MacOS.
I have built my own Qt from source using this gcc, and I can compile my Qt program without a hitch. The problem comes at the linking stage, when the object files of my program should be linked to the Qt libs, it almost seems as if the Qt libs can't be found at all, or are ignored because they are somehow incompatible.
The object files of my program and the Qt libs I built both seem to be ok:
$ file MainWindow.o
MainWindow.o: Mach-O object i386
$ file /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2
/usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2: Mach-O dynamically linked shared library i386
The g++ invocation goes like this:
$ i686-apple-darwin10-g++ -o myapp.app/Contents/MacOS/myapp
main.o MainWindow.o ...
-L/usr/local/myqt/mac32/Qt-4.8.2/lib -lQtCore -lQtGui ...
Of course there are many more object files and many more Qt libs, I have left them out for brevity.
The errors I get are typical of simply not adding an object or lib to the command line, for example:
...
"QMainWindow::event(QEvent*)", referenced from:
vtable for MainWindowin moc_MainWindow.o
"QDir::~QDir()", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
and it seems that basically every Qt lib is not being found.
I have also tried specifying the lib files directly instead of the -L/path and -lQtFoo combo, and I even tried renaming them from .dylib to .so :)
If I run g++ with -v to see the linker call, then also add -v to that, I can see that the paths being checked for libs look ok:
$ i686-apple-darwin10-ld64 -dynamic -arch i386 -headerpad_max_install_names
-macosx_version_min 10.4 -syslibroot /usr/i686-apple-darwin10
-weak_reference_mismatches non-weak -o myapp.app/Contents/MacOS/myapp
-lcrt1.o /usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/bin/../lib/gcc/i686-apple-darwin10/4.2.1/crt3.o
main.o MainWindow.o
...
-L/usr/local/myqt/mac32/Qt-4.8.2/lib -lQtCore -lQtGui ...
-v
#(#)PROGRAM:ld64 PROJECT:odcctools-622.3od16
Library search paths:
/usr/local/myqt/mac32/Qt-4.8.2/lib
/usr/i686-apple-darwin10/usr/X11/lib
/usr/local/myqt/mac32/Qt-4.8.2/lib
/usr/i686-apple-darwin10/usr/lib/i686-apple-darwin10/4.2.1
/usr/i686-apple-darwin10/usr/lib
/usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/lib/gcc/i686-apple-darwin10/4.2.1
/usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/lib/gcc
/usr/i686-apple-darwin10/usr/lib/gcc/i686-apple-darwin10/4.2.1
/usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/i686-apple-darwin10/lib
/usr/i686-apple-darwin10/SDKs/MacOSX10.6.sdk/usr/i686-apple-darwin10/lib
/usr/i686-apple-darwin10/usr/lib
/usr/local/lib
Framework search paths:
/usr/i686-apple-darwin10/Library/Frameworks/
/usr/i686-apple-darwin10/System/Library/Frameworks/
The lib location and setup looks ok:
$ ls -lh /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib*
lrwxrwxrwx. 1 root root 21 Aug 7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib -> libQtCore.dylib.4.8.2
lrwxrwxrwx. 1 root root 21 Aug 7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4 -> libQtCore.dylib.4.8.2
lrwxrwxrwx. 1 root root 21 Aug 7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8 -> libQtCore.dylib.4.8.2
-rwxr-xr-x. 1 root root 2.7M Aug 7 05:22 /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtCore.dylib.4.8.2
The lib contents also seem to be ok, but I am not too familiar with this part... actually I just discovered 'nm' on another question here just now.
$ i686-apple-darwin10-nm /usr/local/myqt/mac32/Qt-4.8.2/lib/libQtGui.dylib.4.8.2 | grep event
U __ZN16QCoreApplication5eventEP6QEvent
U __ZN16QEventTransition5eventEP6QEvent
U __ZN16QEventTransition9eventTestEP6QEvent
U __ZN17QVariantAnimation5eventEP6QEvent
U __ZN19QAbstractTransition5eventEP6QEvent
U __ZN23QCoreApplicationPrivate15eventDispatcherE
U __ZN7QObject11eventFilterEPS_P6QEvent
U __ZN7QObject5eventEP6QEvent
I am also not too familiar with 'name mangling', but I get the feeling it may have something to do with this.
It has been quite a long journey so far with this whole cross-compiling thing, so it sucks to be this close to the end and hit something that really stumps me this much - any advice would be greatly appreciated!
** EDIT ***
I found that if I take out the -dynamic flag for the ld64 call, different function names are shown as missing. For example the missing reference to "QMainWindow::event(QEvent*)" mentioned above becomes:
"__ZN11QMainWindow5eventEP6QEvent", referenced from:
__ZTV10MainWindow in moc_MainWindow.o
And now I can see that these names are indeed, NOT found in the Qt libs I built (configuration issue...?). This didn't enlighten me much as to what should be done to fix the problem, but perhaps it might give somebody else a clue.
I don't have a full answer for you, but I can tell you that the 'U' in your nm output means the symbol is not defined in that executable (or library in this case) but is expected to be defined in an externally linked library, suggesting that something may actually be wrong with that library.
As a side note, you can use the -C argument to nm to have it demangle your C++ symbols.
I managed to get past this problem, although without totally understanding the details of it. Originally I had these two lines in the mkspecs file and although they did not cause any errors when building Qt, commenting them out fixed the problem:
QMAKE_RANLIB = i686-apple-darwin10-ranlib
QMAKE_STRIP = i686-apple-darwin10-strip
I had set these to the cross-compiler executables like this thinking it was necessary, but it seems that everything in the tool-chain is taken care of simply by specifying the correct gcc and g++.
When I run ldd against a shared library such as libphp5.so I see that it has a dependency on libmysqlclient.so.16:
$ ldd ./libphp5.so
libmysqlclient.so.16 => /usr/lib/mysql/libmysqlclient.so.16
[other dependencies snipped out]
Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16) baked into the shared library binary? Or is this path determined by some other means such as via /etc/ld.so.conf.d/mysql-i386.conf, which incidentally contains:
/usr/lib/mysql/
One other thing is puzzling me:
There is a shared library I have that I compile from source. This has a dependency on libmysqlclient_r. The gcc compiler switches to produce this this library look like:
gcc -shared -L/usr/lib/mysql -lmysqlclient_r [+various other switches]
When I do ldd mylib.so I see:
libmysqlclient_r.so.16 => /usr/lib/mysql/libmysqlclient_r.so.16 (0x0055c000)
However in the /usr/lib/mysql directory I see:
-rwxr-xr-x. libmysqlclient_r.so -> libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient_r.so.16 -> libmysqlclient_r.so.16.0.0
-rwxr-xr-x. libmysqlclient_r.so.16.0.0
lrwxrwxrwx. libmysqlclient.so -> libmysqlclient.so.16.0.0
lrwxrwxrwx. libmysqlclient.so.16 -> libmysqlclient.so.16.0.0
-rwxr-xr-x. libmysqlclient.so.16.0.0
libmysqlclient_r.so is a symbolic link to libmysqlclient_r.so.16.0.0, so why does ldd show the dependency as libmysqlclient_r.so.16. Is there some magic I'm missing here?
Having been a Windows dev for many years I'm a bit new to gcc and development on Linux.
My Linux distribution is CentOS 6.0 x86-32bit.
You can see which paths are coming from where by running
LD_DEBUG=libs ldd ./libphp5.so
Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16) baked into the shared library binary?
The filename almost certainly is. The path usually isn't. You can see what is baked into the binary with
readelf -d ./libphp5.so
Look for (NEEDED) and (RPATH) entries.
Also give man ld.so a read. There are many factors that affect how dynamic loader searches for shared libraries: ld.so.conf, LD_LIBRARY_PATH, whether the executable is suid or not, how glibc was configured, which -rpath settings were given at link time, etc. etc.
Are these dependency filenames and paths (/usr/lib/mysql/libmysqlclient.so.16) baked into the shared library binary?
Yes, they can be and often are. The keyword here is -rpath. However, ld.conf also has its say. The whole system is quite complex, unfortunately.
Installing liboost-dev on Debian Squeeze gives me several libraries like /usr/lib/libboost_thread.so.1.42.0, but no libboost_thread.so. Now I can't link using the -l flag of gcc / ld because the names don't end in .so.
I notice that /usr/lib has plenty of other libraries of the form libfoo.so.N without a libfoo.so, so this isn't peculiar to Boost. I ended up adding libboost_thread.so.1 and libboost_thread.so symlinks links by hand. (The man page for ldconfig suggests it will add the links, but it didn't do anything).
Everything works fine, but it feels dirty. What should I have done?
use some more specific linker option I haven't found yet (at the cost of making my makefiles depend on a specific version number).
just add the symlinks by hand (at the risk of subverting package management).
some other Debian 'right way' to do it.
You installed the run-time package libboost-thread1.42.0 but the development package libboost-thread-dev (or even the catch-all package libboost-all-dev.
Once you have the corresponding -dev package, linking will work. That is a general feature of most Linux distribution---you almost never want to mess with the symlinks by hand.
Edit: In response to your comment:
edd#max:~$ ls -l /usr/lib/libboost_thread.*
-rw-r--r-- 1 root root 176324 2010-10-21 00:56 /usr/lib/libboost_thread.a
lrwxrwxrwx 1 root root 25 2011-05-14 10:17 /usr/lib/libboost_thread.so -> \
libboost_thread.so.1.42.0
-rw-r--r-- 1 root root 88824 2010-10-21 00:56 /usr/lib/libboost_thread.so.1.42.0
edd#max:~$ dpkg -S /usr/lib/libboost_thread.so
libboost-thread1.42-dev: /usr/lib/libboost_thread.so
edd#max:~$
Clearly the package management system created the links, and owns them.
Dirk's answer is correct about the general principle but there seems to be an extra trap for the unwary with the boost packaging.
Normally the headers and the library symlink are in the same package, so you get the library symlink without thinking about it. However with boost "libboost<version>-dev" provides the headers but "libboost-<lib><version>-dev" provides the shared library symlink. So if you only install the former you get stuff compiling but not linking.
Everybody out there,
I'm writing a c code which have a strange problem when I compile it .
The source code is OK.
I compile it with following option:
$ gcc above_sample.c -I/home/hadoop/project/hadoop-0.20.2/src/c++/libhdfs -L/home/hadoop/project/hadoop-0.20.2/c++/Linux-amd64-64/lib -lhdfs -o above_sample.
But it show the out put like that:
/usr/bin/ld: warning: libjvm.so, needed by /home/hadoop/project/hadoop-0.20.2/c++/Linux-amd64-64/lib/libhdfs.so, not found (try using -rpath or -rpath-link) /home/hadoop/project/hadoop-0.20.2/c++/Linux-amd64-64/lib/libhdfs.so: undefined reference to `JNI_CreateJavaVM#SUNWprivate_1.1'
/home/hadoop/project/hadoop-0.20.2/c++/Linux-amd64-64/lib/libhdfs.so: undefined reference to `JNI_GetCreatedJavaVMs#SUNWprivate_1.1'
collect2: ld returned 1 exit status
I searched for libjvm.so i found It in my system in /usr/java/lib.
I made a symbolic link of it but did not work.
i copied the library in to several places like usr/lib check the LD_library_Path
but could not manage to compile the program it showing the same error again and again
Can any one tell me what I'm doing wrong ?
how to link .so file to gcc ?
or how .so files are linked in program?
Try adding:
-L/usr/java/lib
To your linker command, since that's the library your linker is not being able to find: I_GetCreatedJavaVMs#SUNWprivate_1.1.
A little piece of advice: it's not a good idea to mess with LD_LIBRARY_PATH. Just fix your linker command.
Linker gives a warning about not found reference to function JNI_CreateJavaVM#SUNWprivate_1.1
/usr/bin/ld: warning: libhdfs.so: undefined reference to
`JNI_CreateJavaVM#SUNWprivate_1.1'
This function name might be specific for library from Sun/Oracle HotSpot JVM. Other JVMs may have another name. For example, mine OpenJDK had only shorter name such as JNI_CreateJavaVM and linker gave me the same warning.
You may get list of the functions from your libjvm.so by running command:
readelf -s libjvm.so | grep JNI_CreateJavaVM # given that you are in catalog containing libjvm.so
If output does not contain required function, then you might want to install another JDK.
That's what worked for me:
CDH=/opt/cloudera/parcels/CDH
OS_ARCH=amd64
gcc hdfs_example.c -I$CDH/include -L$CDH/lib64 \
-L/usr/java/default/jre/lib/${OS_ARCH}/server \
-ljvm -lhdfs -o hdfs_write_test