I have written a gstreamer plugin using the boilerplate template refrenced in the gstreamer plugin writers guide (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/chapter-building-boiler.html). I first built the plugin without full implementation of the chain function (basically an empty plugin that passed data from the source to sink with no changes).
I am now implementing the chain function to perform a basic filtering on the data in the buffer. The filtering uses an external sharpening library (which I have successfully used outside of gstreamer). When building using autotools I get no errors, but when creating a pipeline using the new plugin, I get an undefined symbol error
(gst-plugin-scanner:6512): GStreamer-WARNING **: Failed to load plugin '/usr/local/lib/gstreamer-1.0/libgstsharpening.so': /usr/local/lib/gstreamer-1.0/libgstsharpening.so: undefined symbol: InitializeSharpeningModule
I am admittedly very new to autotools, and I believe my problem lies somewhere in that process, but I can't figure out where. The external sharpening library being used can be found here
/public/gstreamer_pipeline/lib/libsharpening.so
I edited the plugin Makefile.am found in the src directory for my plugin
/public/gstreamer_pipeline/src/gst-sharpening/src
The contents of the edited Makefile.am are
plugin_LTLIBRARIES = libgstsharpening.la
libgstsharpening_la_SOURCES = gstsharpening.c gstsharpening.h
libgstsharpening_la_CFLAGS = $(GST_CFLAGS) -I/public/gstreamer_pipeline/include
libgstsharpening_la_LIBADD = $(GST_LIBS) -lsharpening
libgstsharpening_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -L/public/gstreamer_pipeline/lib
libgstsharpening_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
noinst_HEADERS = gstsharpening.h
The undefined symbol error is occuring in the case of creating the pipeline from a main program, or creating the pipeline from the command line using
gst-launch-1.0 fakesrc ! sharpening ! fakesink
The output of running ldd on the new created plugin library (without modifying LD_LIBRARY_PATH) is
ldd /usr/local/lib/gstreamer-1.0/libgstsharpening.so
linux-vdso.so.1 => (0x00007fff17bc0000)
libgstbase-1.0.so.0 => /usr/local/lib/libgstbase-1.0.so.0 (0x00007f3c51778000)
libgstcontroller-1.0.so.0 => /usr/local/lib/libgstcontroller-1.0.so.0 (0x00007f3c51568000)
libgstreamer-1.0.so.0 => /usr/local/lib/libgstreamer-1.0.so.0 (0x00007f3c51250000)
libgmodule-2.0.so.0 => /usr/local/lib/libgmodule-2.0.so.0 (0x00007f3c5104d000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3c50db0000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f3c50bac000)
libgobject-2.0.so.0 => /usr/local/lib/libgobject-2.0.so.0 (0x00007f3c5095f000)
libffi.so.6 => /usr/local/lib/../lib64/libffi.so.6 (0x00007f3c50755000)
libglib-2.0.so.0 => /usr/local/lib/libglib-2.0.so.0 (0x00007f3c50420000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3c50203000)
librt.so.1 => /lib64/librt.so.1 (0x00007f3c4fffa000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3c4fc67000)
/lib64/ld-linux-x86-64.so.2 (0x0000003406c00000)
The configure.log output http://pastie.org/10450341
The output of make and make install http://pastie.org/10450352
Most likely the runtime linker/loader cannot find the auxiliary libraries (libsharpening.so) in the non-standard paths (/public/gstreamer_pipeline/lib/).
(You tell automake where to look for that library for the linking step in the build-process; this does not mean that the runtime linker will look at the same place).
There are various ways to fix that:
install the library in a place where the runtime linker will look for it, e.g. /usr/local/lib/ (that's the good way)
configure the runtime linker to permanently look for libraries in your non-standard paths, by adding it to /etc/ld.so.config (or - if your sytem supports it - by adding it to the new file /etc/ld.so.conf.d/gstreamer_pipeline.conf)
tell the runtime linker to use an additional path for library resolving, via the LD_LIBRARY_PATH environmental variable.
e.g.
LD_LIBRARY_PATH=/public/gstreamer_pipeline/lib/ gst-launch-1.0 \
fakesrc ! sharpening ! fakesink
Related
I'm trying to compile a program, I need to set a prefix path on shared library path, I try using -Wl,-rpath -Wl,-dynamic-linker and what I got from ldd was:
linux-vdso.so.1 => (0x00007fff75336000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f19d55b8000)
/pathtolib/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000055d3d67e1000)
but what I expecting to get was:
linux-vdso.so.1 => (0x00007fff75336000)
libc.so.6 => /pathtolib/lib/x86_64-linux-gnu/libc.so.6 (0x00007f19d55b8000)
/pathtolib/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000055d3d67e1000)
I really need to setup this and force program to use non-default path (/pathtolib) for all shared libraries.
this is the command I used to compile:
gcc list/list.c -o bin/list -Wl,-rpath,/pathtolib -Wl,--dynamic-linker,/pathtolib/lib64/ld-linux-x86-64.so.2
what did I do wrong?!! :|
The -rpath option does not specify a prefix for individual directories in the search path; rather, it specifies a colon-delimited list of paths. The dynamic linker searches these directories first, but it continues on to the rest of the search path if it needs to do. Thus, if you want the dynamic linker to resolve libc.so.6 to /pathtolib/lib/x86_64-linux-gnu/libc.so.6, then you must specify not /pathtolib but /pathtolib/lib/x86_64-linux-gnu in your rpath.
I am not aware of a link option or ELF header field that would instruct the dynamic linker to do what you seem to be asking: to modify the standard library search path by prefixing each element. If you want to do something like that, then you probably need to provide your own dynamic linker.
Alternatively, perhaps you want to construct and use a chroot environment instead of of messing with rpaths. That requires considerably more work to set up, but it would have the effect of allowing you to use a whole different set of libraries.
I'm relatively new to Linux and am having trouble trying to figure out the intricacies of .SO files and how (64-bit) shared libraries(and their versions, dependencies etc) work; and how to link them and use them in a basic C++ program??
The scenario is this: I have a shared library file(single physical file) called libfaidtz.so.3.0.0_debian6_64bit. I have installed Debian(latest version) 64-bit on VMWare. I have installed (I believe) all the basic C++ development tools use apt-get.
Now I wish to write a simple program in C++ that will LINK libfaidtz.so.3.0.0_debian6_64bit, and enable me to call two specific functions "exported" by this .so file. Unfortunately, the environment/system set up on my machine is preventing me from linking to this library successfully.
Can anyone guide me on this please?
I have included below, some pertinent details regarding the .SO file it self. The function I wish to use(from the .SO file) has the following function-prototype(and should work):
int32_t DEF_EXPORT TZ_FAID_Size(int64_t start_time,
int32_t roster_count,
int64_t * roster_from,
int64_t * roster_to,
int32_t * roster_ids,
int32_t & id_cnt);
I'm from a Windows background (Dynamic linking and DLLs-wise) and am struggling to get this .SO file liked and used in a basic C++ test program.
root#debian:/home/maitreya/lib# ldd libfaidtz.so.3.0.0_debian6_64bit
linux-vdso.so.1 => (0x00007fff667ff000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3300a6f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f33007ed000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3300461000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f330024b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3300f93000)
root#debian:/home/maitreya/lib# nm libfaidtz.so.3.0.0_debian6_64bit
0000000000208c70 d DW.ref.__gxx_personality_v0
0000000000006ebb T TZ_FAID_Process
0000000000006e04 T TZ_FAID_Size
0000000000007447 T TZ_FAID_Version
0000000000208028 a _DYNAMIC
0000000000208230 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
00000000000011ca T _Z15FetchExpiryDatePiS_S_
and so on..
If you look at some of the standard libraries installed on your system you will see that they are soft linked. For example: I have /lib/libgpm.so.2.1.0 with a soft link /lib/libgpm.so.
Try creating a soft link libfaidtz.so to your library and then link with -lfaidtz.
I am trying to invoke a C-Program which returns the value for a given keyword from a configuration file
While trying to invoke program it's displaying below error:
**Testprintenv: error while loading shared libraries: libodbc.so.1: cannot open shared object file: No such file or directory**
We have installed EasySoft previously and uninstalled back (Removed all directories).
Below dependencies are showing up on Linux machine
**
-bash-4.1$ ldd Testprintenv
linux-vdso.so.1 => (0x00007fffc0bdb000)
libodbc.so.1 => not found
libodbcinst.so.1 => not found
libc.so.6 => /lib64/libc.so.6 (0x000000397b200000)
/lib64/ld-linux-x86-64.so.2 (0x000000397ae00000)
**
When we try the same program on Solaris machine dependencies are showing up differently and executing without any error:
[Testuser]$ ldd Testprintenv
libsocket.so.1 => /lib/libsocket.so.1
libnsl.so.1 => /lib/libnsl.so.1
libc.so.1 => /lib/libc.so.1
libmp.so.2 => /lib/libmp.so.2
libmd.so.1 => /lib/libmd.so.1
libscf.so.1 => /lib/libscf.so.1
libdoor.so.1 => /lib/libdoor.so.1
libuutil.so.1 => /lib/libuutil.so.1
libgen.so.1 => /lib/libgen.so.1
libm.so.2 => /lib/libm.so.2
/platform/SUNW,SPARC-Enterprise/lib/libc_psr.so.1
Any insight why the dependency (libodbc.so.1) is only showing up on linux and how to resolve?
Thanks in advance,
Is there anyway to check the relationships between c executable and libraries other than ldd?
Any insight why the dependency (libodbc.so.1) is only showing up on
linux and how to resolve?
1) If you want to know why there is a dependency, I suggest to try finding common symbols. Unfortunatelly, you must have the libodbc library installed, because there is no way to find out from the Testprintenv binary which symbols are meant to be linked with this library.
So, do it like this:
# symbols needed by the Testprintenv binary:
nm -uD Testprintenv | tr -s " " | cut -f 3 -d" " > /tmp/symbols_needed
# symbols provided by the libodbc
nm --defined-only -D /lib/PATH_TO_YOUR_LIBRARY/libodbc.so.1 | cut -f 3 -d " " > /tmp/symbols_lib
# intersection of the two sets:
grep -w -F -f /tmp/symbols_needed /tmp/symbols_lib
The last command will list the symbols needed by Testprintenv and provided by libodbc.
2) How to resolve the issue?
first, install the library (libodbc), does it work now?
if not, make sure it is in the standard directories.
if not, add the directory where libodbc resides to the LD_PRELOAD environment variable, like: LD_PRELOAD=/home/ivan/my_lib/
Ok,
First some explanation:
You are trying to use a software that REQUIRES UNIXODBC .
By your OWN result of ldd it says:
**Testprintenv: error while loading shared libraries: libodbc.so.1: cannot open shared object file: No such file or directory**
Now about LDD the man page says:
ldd - print shared library dependencies
So this program you are trying to run DOES NEED the libodbc provided BY UNIXODBC.
You may check rpmfind here.
As Solaris is another platform it may or not use it. (as Solaris has others ways to handle what you are trying to do)
So please check the link and read the install section.
The reason your software is shared linked to UNIXODBC instead of static is
Dynamic Data Binding
This allows the user or the system administrator to easily configure an application to use any ODBC compliant data source. This is perhaps the single biggest advantage of coding an application to the ODBC API and to purchase these applications. Dyamic binding allows the end-user to pick a data source, ie an SQL Server, and use it for all data applications without having to worry about recompiling the application.
By using a non-static dependence easysoft user is able to connect to any database.
I am trying to use the Intel MKL libraries for the first time. I am using CMake to build a simple project in which MKL is used. I work in the KDevelop 4.6 environment.
The project is built and installed without errors. Linking the libraries is thus succesful. While executing within KDevelop, I get the following error:
Error while loading shared libraries: libmkl_intel_lp64.so: cannot open shared object file: No such file or directory
The CMakeLists file looks essentially as follows:
project(testmkl)
cmake_minimum_required(VERSION 2.6)
enable_language(Fortran)
set(CMAKE_C_FLAGS "-std=c99 -Wall -lpthread")
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# MKL
find_package(MKL REQUIRED)
include_directories(${MKL_INCLUDE_DIR})
find_package(M REQUIRED)
include_directories(${M_INCLUDES})
add_executable(testmkl ./main.c)
target_link_libraries(testmkl ${M_LIBRARIES} ${MKL_BLAS} ${MKL_LAPACK} ${MKL_INTEL} ${MKL_SEQUENTIAL} ${MKL_CORE})
install(TARGETS testmkl DESTINATION .)
libmkl_intel_lp64.so is found in the first folder of the LP_LIBRARY_PATH environment variable, so I wouldn't expect any error during the execution. Actually, when running the program from the command window, everything seems to work fine.
The ldd output for the executable is:
>> ldd ./testmkl
linux-vdso.so.1 => (0x00007fff951fe000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003061a00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003061200000)
libmkl_intel_lp64.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_intel_lp64.so (0x00007f6f65ef6000)
libmkl_sequential.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_sequential.so (0x00007f6f65846000)
libmkl_core.so => /opt/intel/composer_xe_2013_sp1.0.080/mkl/lib/intel64/libmkl_core.so (0x00007f6f64317000)
libc.so.6 => /lib64/libc.so.6 (0x0000003060e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003060600000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003061600000)
The linked libraries are thus correctly found. Why won't the program work in the KDevelop environment?
Any help is welcome, thanks!
First one short question: are you excuting your program from a terminal or trying to execute from KDE gui (e.g. by double-click)?
On many linux OS, now LD_LIBRARY_PATH is deprecated. LD finds the dependencies thanks to what is listed in /etc/ld.so.conf and /etc/ld.so.conf.d . You may have to add a script somewhere there to include your libraries. In fact you just have to add the path to your libraries in those scripts.
example from /etc/ld.so.conf/libc.conf:
# libc default configuration
/usr/local/lib
This may work for you.
edit:
you shoud also run ldconfig to update the LD database and/or use ldconfig -v, which does the same but with extended output
edit2: ldconfig may require root privileges to be understood by the GUI
I had the same problem and now it solved through configuration of environment variable in kdevelop.
Go to project->open configuration
Select make tab
Click setting icon in Active environment profile bar and add your environment variable:
LD_LIBRARY_PATH = /your/shared/library/path
I have a make file for a program that links to libdl.so with the following line -ldl. There are no calls to dlopen or any of the related functions. What is the effect of linking to this library in this way even though you do not use any of the functions?
You'll have to read the documentation for your linker. From info ld on my Linux/ELF/GNU Binutils system (emphasis added):
`--as-needed'
`--no-as-needed'
This option affects ELF DT_NEEDED tags for dynamic libraries
mentioned on the command line after the `--as-needed' option.
Normally the linker will add a DT_NEEDED tag for each dynamic
library mentioned on the command line, regardless of whether the
library is actually needed or not. `--as-needed' causes a
DT_NEEDED tag to only be emitted for a library that satisfies an
undefined symbol reference from a regular object file or, if the
library is not found in the DT_NEEDED lists of other libraries
linked up to that point, an undefined symbol reference from
another dynamic library. `--no-as-needed' restores the default
behaviour.
You can check yourself by running ldd on a test program. On a simple test program, I get:
linux-vdso.so.1 => (0x00007fffd8305000)
libc.so.6 => /lib/libc.so.6 (0x00007f646c669000)
/lib/ld-linux-x86-64.so.2 (0x00007f646c9ca000)
However, if I link with -ldl, I get this:
linux-vdso.so.1 => (0x00007fff644f1000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fb9b1375000)
libc.so.6 => /lib/libc.so.6 (0x00007fb9b1014000)
/lib/ld-linux-x86-64.so.2 (0x00007fb9b1579000)
Even though libdl isn't used by my program. However, if I run GCC with -Wl,--as-needed, libdl will not be linked in. According to my tests, this only works if -Wl,--as-needed is listed on the command line before -ldl.
What are the effects? It means that your binary won't run on systems without the shared library, even though you don't use it. It also means that your binary will break if you upgrade the shared library and uninstall the old one. It's not a big deal because binary compatibility is a bear anyway, but I see no reason not to turn on -Wl,--as-needed for projects in general.
I have coded a small application which uses nothing but STL. It has 8275 bytes of size without linking to any specific libraries:
linux-gate.so.1 => (0x00e1e000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x0015a000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x0044b000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00741000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00250000)
/lib/ld-linux.so.2 (0x00a75000)
Now, when I compile it and link it with boost_thread, it grows to 8290 bytes:
linux-gate.so.1 => (0x009d9000)
libboost_thread.so.1.40.0 => /usr/lib/libboost_thread.so.1.40.0 (0x00e59000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x003a3000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0x00bc5000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00f8a000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00110000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0x00bf0000)
librt.so.1 => /lib/tls/i686/cmov/librt.so.1 (0x00dd8000)
/lib/ld-linux.so.2 (0x00ba3000)
Note that there is no function call on my code to features of boost_thread. However, boost_thread is added anyway as a dependency of my application (as you can see on the output of ldd).
Linking to a shared library is different than linking a static library. The main differences were explained already by #Dietrich Epp, but there's another important detail. Shared libraries define functions void _init() and void _fini(void) which are called upon loading/unloading a shared library; if you don't define them yourself the linker will add default stubs.
Those will be called also if you link your program against a shared library, but don't reference any symbol from the library (and don't add --as-needed linker flag).
Most linkers will simply omit the unused objects from the final binary, exactly as if you hadn't linked with the library in the first place.