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
Related
I've mainly worked on Windows, so I'm quite unfamiliar with less common issues under Linux.
Here's the error I'm getting when dub tries to link my application:
/usr/bin/ld: .dub/obj/pixelperfectengine_pixelperfecteditor.o: undefined reference to symbol 'inflateEnd'
//lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Error: /usr/bin/gcc failed with status: 1
/usr/bin/ldc2 failed with exit code 1.
I've an image handling library as a dependency, which is required for the application, and it (obviously) uses zlib for *.png compression/decompression. I've installed zlib1g-dev for Ubuntu, but did not fix my issues, and the same exact code compiles without any issues under Windows.
You need to link in zlib, as mentioned before.
I would recommend to do so via the "libs" array (see this page: https://dub.pm/package-format-json.html). The advantage of using libs over lflags is that libs will try to use pkg-config, which is a generic way to get linker / compile flags for C[++] libraries on POSIX. It works on Linux and Mac OSX. If pkg-config is not found, dub will just default to do what lflags would do in the first place.
Here's an example from my own project: https://github.com/Geod24/libsodiumd/blob/9b397645e2fc3ca502acb58e1b4631d3faf094e2/dub.json
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
This error is telling you that you must add -lz to command line. I don't know what dub is, but somehow you must convince it to add -lz to the link command it constructs.
It's probably enough to add -lz to the lflags in your dub file.
On Linux, the D runtime library relies on the _end symbol in determining the GC root ranges (man 3 end), which is in fact very similar to what the Boehm GC does. However, when linking in libcurl, the symbol is no longer found by the linker:
$ cat test.c
#include <stdio.h>
extern char _end[];
int main() {
printf("%p\n", &_end);
return 0;
}
$ gcc test.c # works
$ gcc test.c -lcurl
/usr/bin/ld: /tmp/ccOPtbEv.o: undefined reference to symbol '_end'
/usr/bin/ld: note: '_end' is defined in DSO /usr/lib/libssl.so.1.0.0 so try adding it to the linker command line
/usr/lib/libssl.so.1.0.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
From a quick search on the D forums, libpq, libdw and several other libraries seem to trigger the same problem. Any idea what could be happening here? test.c doesn't even depend on symbols from libcurl. (Arch Linux x86_64, GCC 4.7.2, ld 2.23)
Also, please note that »try linking in libssl« is not the answer I am looking for, I want to understand what is happening here. I'm trying to fix this problem in a compiler I'm working on, so you can assume basic familiarity with how the linking process works.
Edit: The reason why I'm not particularly satisfied with telling the users to just link in libssl, ..., explicitly is that pkg-config --libs curl, curl-config --libs, etc. don't contain this information; requiring it would thus break build systems. If anyone has a better idea for determining the bounds of the data (initialized and BSS) segments, I'd be keen to know.
Edit 2: With the toolchain mentioned above, end (without the underscore) also seems to be defined, and it doesn't trigger the problem. Still baffled as to why it occurs, though.
please note that »try linking in libssl« is not the answer I am looking for.
But most likely it actually is the answer you are looking for. Your command line is all wrong. Try this instead:
gcc test.c -lcurl
The order of libraries and sources,objects on command line matters.
_end symbol is provided by linker. It points past the last object in bss. However, it's just a convention, no standard requires this. Your toolchain's linker doesn't do that, apparently.
I have the following warning during link:
/usr/bin/ld: warning: libxxx.so.6, needed by /a/b/c/libyyy.so, not found (try using -rpath or -rpath-link)
Setting environment variable LD_LIBRARY_PATH=path_to_libxxx.so.6 silence the warning (adding -Lpath_to_libxxx.so.6 doesn't help).
I have a separate compilation server, where the resulting binary is only compile.
The binary is executed on other server and there the libxxx.so.6 is seen by the binary (checked with ldd executable).
Is there're other way to get rid of the warning at compilation time (I have it several times and it's very annoying)?
You need to add the dynamic library equivalent of -L:
-Wl,-rpath-link,/path/to/lib
This will cause the linker to look for shared libraries in non-standard places, but only for the purpose of verifying the link is correct.
If you want the program to find the library at that location at run-time, then there's a similar option to do that:
-Wl,-rpath,/path/to/lib
But, if your program runs fine without this then you don't need it.
Make sure the paths to the needed libraries are known to the runtime linker. This is done by adding a file in /etc/ld.so.conf.d/ with the needed path. For example, /etc/ld.so.conf.d/foo with the following contents:
/usr/local/lib/foo/
If you have a very old Linux version, /etc/ld.so.conf.d/ might not be supported, in which case you might have to add the paths directly into the /etc/ld.so.conf file.
After you've done that, you need to update the linker's database by executing the "ldconfig" command.
I know this is old, but here's a better fix:
The root cause:
The problem actually happens when LD invoked by GCC starts resolving
library dependencies. Both GCC and LD are aware of the sysroot
containing libraries, however LD may be missing one critical
component: the /etc/ld.so.conf file. Here’s an exampleld.so.conf file
from a Raspberry PI system:
include /etc/ld.so.conf.d/*.conf
The /etc/ld.so.conf.d directory contains the following files:
00-vmcs.conf:
/opt/vc/lib
arm-linux-gnueabihf.conf:
/lib/arm-linux-gnueabihf /usr/lib/arm-linux-gnueabihf
libc.conf:
/usr/local/lib
The universal solution
The problem can be easily solved by copying the LD configuration files
to a location where the cross-toolchain’s LD can find them. There’s
one pitfall however: if your cross-toolchain was built with MinGW
(most are), it probably did not have access to the glob() function so
it won’t be able to parse a wildcard-enabled include statement
like *.conf. The workaround here is to just manually combine the
contents of all .conf files from /etc/ld.so.conf.d and paste them
into /etc/ld.so.conf
*/opt/vc/lib
/lib/arm-linux-gnueabihf
/usr/lib/arm-linux-gnueabihf
/usr/local/lib*
Once you create the ld.so.conf file in the correct folder, your
toolchain will be able to resolve all shared library references
automatically and you won’t see that error message again!
The only way to silence these warning using command line options would be the -L flag which curiously does not work for you (maybe you can post more details on this). Since the warning is generated by ld we could try to use -Wl,option to disable a linker warning but from the documentation of GNU ld however there is no option for (de)activating this warnings.
So this leaves us with writing a wrapper script filtering out this warning or compile a custom version of ld.
The project I'm currently working on uses a bunch of dynamic libs bundled together with the source code. There is a subset of libs which is named as follows:
for a given lib libABC, there are four files:
libABC.so
libABC.so.4
libABC.so.4.5
libABC.so.4.5.0
They are daisy-chained like this:
the first file, libABC.so, contains the following:
link libABC.so.4
whereas the next file, libABC.so.4, contains the following:
link libABC.so.4.5
and so on till the actual lib file, libABC.so.4.5.0.
I know that this kind of stuff should be done using symlinks, but we can't change that, it's a commercial project. So the linker chokes on that!
/usr/bin/ld: path/to/the/packaged/libs/libABC.so:unrecognized file format, treating as linker script
(which it actually is, heh)
/usr/bin/ld: path/to/the/packaged/libs/libABC.so:1:syntax error
Now I can't seem to find any info on the GNU ld linker script command "link" or any complete reference to the GNU ld linker script commands.
What could that be?
The linker script format is described in the GNU ld manual.
I found this issue myself today, and what happens is when you do a checkout using SVN on Windows (e.g. TortoiseSVN), the Linux symlink is converted into a text file.
Then, on the build process, ld is receiving a text file instead of a symlink that would lead to the concrete file.
Solution: svn checkout on the Linux machine.
I am attempting to install an application. During compilation it fails with the following error:
/usr/bin/ld: cannot find -lemu
I have installed the libemu library, and it now currently resides in /opt/libemu/. However, when I try and compile my application the library is not found. Is there any way to correct this?
EDIT: It also looks like the make is resulting in:
It also looks like the make file is compiling with the following:
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions
build/temp.linux-x86_64-2.6/libemu_module.o
-L/opt/libemu/lib -lemu -o build/lib.linux-x86_64-2.6/libemu.so
I have tried setting my LD_LIBRARY_PATH to /opt/libemu, still doesn't work - fails with the error mentioned above.
You need to tell the linker where it is:
gcc stuff -L/opt/libemu -lemu
or:
gcc stuff /opt/libemu/libemu.a
where stuff is your normal compile/link options files etc.
You can also specify library paths in the LIBRARY_PATH environment variable:
LIBRARY_PATH=/opt/libemu
export LIBRARY_PATH
before you run your build. Yet another option is to see where gcc looks for libraries by running:
gcc --print-search-dirs
and put your library in one of the listed directories.
Edit: It is really not clear from your latest info what you are trying to build. Are you trying to turn a static library into a shared library? Most important - What is the exact filename of the library file you have copied into the /opt/libemu directory?
The environment variable LD_LIBRARY_PATH should include (but probably does not by default) /opt/libemu.
try running:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/libemu
make install