version node not found for symbol - linker

I've build a shared library on my desktop that uses statically linked gstreamer and gstreamer plugins (base, good, rtsp-server).
Now I'm trying to compile the library using yocto but its giving me a linker error:
version node not found for symbol _IO_do_write##GLIBC_2.17
failed to set dynamic section sizes: Bad value
The solutions I found on stack overflow did not seem to help me.
use compiler with --disable-symvers
link libc libs in different orders (-ldl -lm -lc -lpthread -ltinfo -lrt)
link libc libs statically/shared
What I find particularly odd is that the linker is looking for GLIBC_2.17 while yocto uses 2.27 and my system is using 2.24. I don't know if this matters or if it is normal (the function did not change since 2.17?).
NM -C shows the symbol in libc.a:
nm -C recipe-sysroot/usr/lib/libc.a | grep IO_do_write
U _IO_do_write
U _IO_do_write
0000000000001ba8 W _IO_do_write
So I would thinks that lib is linked incorrectly?
The linker command is a long one because of all the shared libs so I shortend it a bit (removed boost and custom libs):
aarch64-poky-linux-g++ -fPIC --sysroot=recipe-sysroot -O2 -pipe -g -feliminate-unused-debug-types -fdebug-prefix-map=recipe-root/git-r0 -fdebug-prefix-map=recipe-sysroot= -fdebug-prefix-map=recipe-sysroot-native= -fvisibility-inlines-hidden --sysroot=recipe-sysroot -Wl,-allow-multiple-definition -Wall -Wextra -Wpedantic -Wsuggest-override -Wswitch-default -Wduplicated-cond -Wshadow -Werror -ftemplate-depth=1024 -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -lc -Wl,--no-as-needed -Wl,--no-undefined -pthread -ldl -shared -Wl,-soname,rtsp_streamer.so -o rtsp_streamer.so ... custom static libs .and boost static libs ... -lpthread recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtsp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstrtpmanager.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstcoreelements.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstadder.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstapp.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudioconvert.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudiorate.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudioresample.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstaudiotestsrc.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstgio.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstpango.a recipe-sysroot/usr/lib/gstreamer-1.0/libgsttypefindfunctions.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideoconvert.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideorate.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideoscale.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideotestsrc.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvolume.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstautodetect.a recipe-sysroot/usr/lib/gstreamer-1.0/libgstvideofilter.a recipe-sysroot/usr/lib/libBrokenLocale.a recipe-sysroot/usr/lib/libBrokenLocale_pic.a recipe-sysroot/usr/lib/libanl.a recipe-sysroot/usr/lib/libanl_pic.a recipe-sysroot/usr/lib/libatomic.a recipe-sysroot/usr/lib/libatomic_ops.a recipe-sysroot/usr/lib/libatomic_ops_gpl.a ... more boost static libs ... recipe-sysroot/usr/lib/libc.a recipe-sysroot/usr/lib/libc_nonshared.a recipe-sysroot/usr/lib/libc_pic.a recipe-sysroot/usr/lib/libcidn_pic.a recipe-sysroot/usr/lib/libcrypt.a recipe-sysroot/usr/lib/libcrypt_pic.a recipe-sysroot/usr/lib/libcrypto.a recipe-sysroot/usr/lib/libdl.a recipe-sysroot/usr/lib/libdl_pic.a recipe-sysroot/usr/lib/libg.a recipe-sysroot/usr/lib/libgomp.a recipe-sysroot/usr/lib/libgstallocators-1.0.a recipe-sysroot/usr/lib/libgstaudio-1.0.a recipe-sysroot/usr/lib/libgstbase-1.0.a recipe-sysroot/usr/lib/libgstcheck-1.0.a recipe-sysroot/usr/lib/libgstcontroller-1.0.a recipe-sysroot/usr/lib/libgstfft-1.0.a recipe-sysroot/usr/lib/libgstpbutils-1.0.a recipe-sysroot/usr/lib/libgstreamer-1.0.a recipe-sysroot/usr/lib/libgstriff-1.0.a recipe-sysroot/usr/lib/libgstrtp-1.0.a recipe-sysroot/usr/lib/libgstrtsp-1.0.a recipe-sysroot/usr/lib/libgstrtspserver-1.0.a recipe-sysroot/usr/lib/libgstapp-1.0.a recipe-sysroot/usr/lib/libgstnet-1.0.a recipe-sysroot/usr/lib/libgstsdp-1.0.a recipe-sysroot/usr/lib/libgsttag-1.0.a recipe-sysroot/usr/lib/libgstvideo-1.0.a recipe-sysroot/usr/lib/libhistory.a recipe-sysroot/usr/lib/libitm.a recipe-sysroot/usr/lib/liblicensing.a recipe-sysroot/usr/lib/libm.a recipe-sysroot/usr/lib/libm_pic.a recipe-sysroot/usr/lib/libmcheck.a recipe-sysroot/usr/lib/libncurses++.a recipe-sysroot/usr/lib/libncurses++w.a recipe-sysroot/usr/lib/libnsl.a recipe-sysroot/usr/lib/libnsl_pic.a recipe-sysroot/usr/lib/libnss_compat_pic.a recipe-sysroot/usr/lib/libnss_db_pic.a recipe-sysroot/usr/lib/libnss_dns_pic.a recipe-sysroot/usr/lib/libnss_files_pic.a recipe-sysroot/usr/lib/libnss_hesiod_pic.a recipe-sysroot/usr/lib/libnss_nis_pic.a recipe-sysroot/usr/lib/libnss_nisplus_pic.a recipe-sysroot/usr/lib/libprotobuf-lite.a recipe-sysroot/usr/lib/libprotobuf.a recipe-sysroot/usr/lib/libprotoc.a recipe-sysroot/usr/lib/libpthread.a recipe-sysroot/usr/lib/libpthread_nonshared.a recipe-sysroot/usr/lib/libreadline.a recipe-sysroot/usr/lib/libresolv.a recipe-sysroot/usr/lib/libresolv_pic.a recipe-sysroot/usr/lib/librpcsvc.a recipe-sysroot/usr/lib/librt.a recipe-sysroot/usr/lib/librt_pic.a recipe-sysroot/usr/lib/libsqlite3.a recipe-sysroot/usr/lib/libssl.a recipe-sysroot/usr/lib/libssp.a recipe-sysroot/usr/lib/libssp_nonshared.a recipe-sysroot/usr/lib/libstdc++.a recipe-sysroot/usr/lib/libstdc++fs.a recipe-sysroot/usr/lib/libsupc++.a recipe-sysroot/usr/lib/libthread_db_pic.a recipe-sysroot/usr/lib/libutil.a recipe-sysroot/usr/lib/libutil_pic.a recipe-sysroot/usr/lib/libz.a recipe-sysroot/usr/lib/librt.a recipe-sysroot/usr/lib/libpthread.a recipe-sysroot/usr/lib/libm.a recipe-sysroot/usr/lib/libc.a
Does anybody know what is wrong? If more info is needed please ask. Thanks in advance!

Does anybody know what is wrong?
I suspect that you are not linking against GLIBC-2.27 from Yocto, but against some other GLIBC, though it is hard to see how that could happen.
Your first step should be to find out which libc.so.6 is actually being used. You can do so by adding -Wl,-t flag to your link line. Also add -Wl,-y,_IO_do_write while you are at it.
After you know which libc.so.6 is being used, run readelf -Ws /path/to/libc.so.6 | grep _IO_do_write to see what (if any) versioned symbols are defined in it.
I don't know if this matters or if it is normal (the function did not change since 2.17)?
Yes: that is normal -- the function didn't change its ABI since GLIBC-2.17, so that's the version that is attached to it.

I figured out what went wrong. The shared library is build using a CMAKE project and our own written FindGSTREAMER.cmake. To find gstreamer, among other things, a glob is used to find all the static libs. Because on my desktop I have gstreamer installed in its seperate location this works. With Yocto however this causes every static lib in the recipe-sysroot/usr/lib directory to be linked. Including every libc library (.a, _pic.a and .so). Apparently this causes the linker unable to resolve the symbols.
Correctly filtering the libraries needed by gstreamer fixed the problem.

Related

libtool changes the order of my linker flags in autotools?

I am trying to statically build the web server lighttpd (version 1.4.49) using musl (for x86) as my compiler and lighttpd's autotools build system. My configuration script is as follows:
CC=/home/musl-1.1.23/install/bin/musl-gcc CFLAGS="-g --static" LDFLAGS="-L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown LIGHTTPD_STATIC=yes ./configure --prefix=/home/lighttpd/install --enable-static --disable-shared --without-zlib --disable-ipv6 --without-bzip2 --without-pcre
Where I have created my own static library "wrappers" that contains the wrapped definitions for the functions specified in my LDFLAGS argument for configure. The way everything is set up I need my wrapped library to be the first library linked (even before musl's standard c library), however libtool is changing the order of my LDFLAGS argument from above to the following:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o -L/home/lighttpd-1.4.49 -lwrappers
instead of:
libtool: link: /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -L/home/lighttpd-1.4.49 -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o proc_open proc_open-proc_open.o proc_open-buffer.o
Which causes the following errors (I have only included the first few, but the rest are similar):
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `__openlog':
/home/musl-1.1.23/src/misc/syslog.c:51: undefined reference to `__wrap_socket'
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog':
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:113: undefined reference to `__wrap_send'
Its weird to me why this is happening, as everywhere else the LDFLAGS appear in the right order:
/bin/bash ../libtool --tag=CC --mode=link /home/musl-1.1.23/install/bin/musl-gcc -g --static -Wall -W -Wshadow -pedantic -module -export-dynamic -avoid-version -L/home/lighttpd -lwrappers -static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown -o mod_setenv.la -rpath /home/lighttpd/install/lib mod_setenv.lo
libtool: link: ranlib .libs/mod_scgi.a
Any help would be greatly appreciated! Thank you in advance.
LDFLAGS is not for libraries to add to the link. libtool notwithstanding, LDFLAGS is expanded too early in the link command, and this is not specific to the autotools.
In your case, libtool appears to be recognizing that error, and in the case where that matters, moving the -L and -l options where they need to be, after the object(s) being linked. (Or at least the -l options need to be there, especially for a static link, and if libtool is going to move those, then there are practical reasons for moving the -L options, too.)
Unfortunately, there is no other user-oriented Autotools variable appropriate to your stated purpose, either. Injecting extra libraries into the link is not a use case the Autotools are designed to support, and injecting them at the beginning of the link is unlikely to be feasible without hacking the autotooling.
On the third hand, you appear to be misinterpreting the problem. You claim that
I need my wrapped library to be the first library linked (even before musl's standard c library)
But this ...
/usr/local/bin/ld: /home/musl-1.1.23/install/lib/libc.a(syslog.o): in function `_vsyslog':
/usr/local/bin/ld: /home/musl-1.1.23/src/misc/syslog.c:111: undefined reference to `__wrap_send'
... tells me exactly the opposite: even calls from inside standard library functions in libc are being wrapped, so the wrapper needs to appear last, even after the standard library (which ordinarily is last, not first).* And since libwrap probably calls standard library functions itself, you may need to link libc twice. Of course, that assumes that you really want to be messing with the standard library that way, which does not seem advisable to me.
If you were performing a dynamic link then this would not be an issue: it would not be possible to wrap the internal calls of the C library in the first place. This suggests to me that the linker's --wrap option probably was not designed with static linking of the standard library in mind.
I'm not inclined to set up a testbed to verify the following, but if you really do want to wrap libc's own internal function calls, then this may work: ... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lc -lwrappers -lc" ./configure ...
LIBS is not really intended to be a user variable, and that's the potential weak point of this plan. But it is among Autoconf's standard output variables, and its contents should appear at the end of the link line. configure may prepend other libraries to LIBS, but it should not append any. The risk is that configure may clear any initial contents.
The -lc appearing before -lwrappersis the secret sauce. Normally, you do not need to specify -lc explicitly, but in this case you do, because you need to resolve some symbols in it against libwrappers, which otherwise would be linked too early. You also (probably) need to link some symbols in libwrappers against libc. It may be redundant, but explicitly linking libc again, after libwrappers, may be necessary to overcome unwanted cleverness by the linker.
If you want to avoid wrapping the internal libc self-calls, then you could try ... LDFLAGS="-static-libgcc -Wl,--wrap=socket -Wl,--wrap=bind -Wl,--wrap=listen -Wl,--wrap=accept4 -Wl,--wrap=send -Wl,--wrap=recv -Wl,--wrap=shutdown" LIBS="-L/home/lighttpd -lwrappers -Wl,--no-wrap=socket -Wl,--no-wrap=bind -Wl,--no-wrap=listen -Wl,--no-wrap=accept4 -Wl,--no-wrap=send -Wl,--no-wrap=recv -Wl,--no-wrap=shutdown" ./configure .... The idea there is to turn off wrapping for libc (only), but it's pretty speculative, because although negating long options with no- is standard GNU form, the --no-wrap option in particular is not documented.
*So libtool's reordering is not causing the issue you present. In fact, if libtool did not perform that reordering then you would have even more link errors.

Linker not able to find functions in other static libraries

I'm trying to compile fbi (Linux framebuffer imageviewer) statically, so I added -static to LDFLAGS in GNUMakefile. Without -static linking works perfectly. When enabled, I get various linking errors telling me this:
/usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/libfontconfig.a(fcxml.o): In function 'FcConfigMessage':
(.text+0x192): undefined reference to 'XML_GetCurrentLineNumber'
Now I do have the static library libfontconfig.a and the function XML_GetCurrentLineNumber it obviously doesn't find is in /usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/libxml2.a which I proofed with nm libxml2.a, according to the source code found here.
I guess I have to tell the linker in the GNUMakefile exactly what to do, but how? The object code in the ar libraries are all ARM 32-bit and I'm compiling and linking on ARM 32-bit.
GNUMakefile can be found here, I added LDFLAGS += -static --verbose -lfontconfig -lfreetype -lpng12 -ltiff.
When one builds a shared library it often links other shared libraries it needs.
Whereas static libraries cannot link other libraries, so that when linking to that static library its dependencies must also be linked explicitly.
In other words, you cannot just sprinkle in -static and expect it to still link.
Try linking in that libxml2.a and other missing libraries until it links:
LDFLAGS += -static --verbose -lfontconfig -lfreetype -lpng12 -ltiff -lxml2

How to make Scons look for libstdc++ in nonstandard directory

I'm trying to use Scons to build a simple project on a server on which I have rights to install stuff only in specific locations (and not in /usr/ ). Since I'm not happy with default compiler the server is offering me, I installed g++4.8 and verified it works just fine. But when I try to use Scons to build a simple project, while it picks up correct g++ (I can get that by checking the version), it's looking for libstdc++ in /usr/ directories instead of the directory where g++4.8 installation resides. E.g. code compiles, but upon execution fails with:
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
Again - this doesn't happen when I call the compiler myself from the terminal.
Even when I add the lib path containing libraries for g++4.8 with LIBPATH option, I get the same error.
Here's my SConscript file:
Import('env')
COMPILER_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
LINK_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
LIB_PATH = 'myfolder/gcc-4.8.2/lib64'
PROGRAM = 'main'
SRC = ['main.cpp', 'Foo.cpp']
env.Append(CPPFLAGS = COMPILER_FLAGS)
env.Append(LINKFLAGS = LINK_FLAGS)
env.Program(target = PROGRAM, source = SRC, LIBPATH = LIB_PATH)
and SConstruct is just
import os
env = Environment(ENV = os.environ)
SConscript('./SConscript', exports=['env'], duplicate=0)
Edit:
I made sure location of my compiler comes in the path before default compiler. But even if I set it explicitly with Environment(CXX=...) it's the same story. Here's the build output:
/mypath/gcc-4.8.2/bin/g++ -o Foo.o -c -Wall -fopenmp -O3 -std=c++11 Foo.cpp
/mypath/gcc-4.8.2/bin/g++ -o main.o -c -Wall -fopenmp -O3 -std=c++11 main.cpp
/mypath/gcc-4.8.2/bin/g++ -o main -Wall -fopenmp -O3 -std=c++11 main.o Foo.o -L/mypath/gcc-4.8.2/lib64
scons: done building targets.
-bash-3.2$
-bash-3.2$
-bash-3.2$ ./main
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
-bash-3.2$
Yet another edit:
ldd on both manual and scons compile reveal:
linux-vdso.so.1 => (0x00007fff513fd000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6(0x0000003e7f600000)
libm.so.6 => /lib64/libm.so.6 (0x0000003e79600000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003e7de00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003e79200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003e78e00000)
So indeed even manual compile doesn't look for the libs in the right directory (or where I installed the compiler) and the problem isn't with the scons itself, but likely that I didn't configure something right, but then I'm really puzzled as to why the executable runs fine, while it doesn't for scons.
Ok, so my problem wasn't with scons, but with me not giving explicit paths to nonstandard locations of libstdc++ and friends. SO answer over here explains this in more detail:
Linking g++ 4.8 to libstdc++
You're misinterpreting the error. GCC always knows how to find its own libraries, including libstdc++. The problem is that after you've compiled the program the runtime linker (which is not part of GCC, it's part of your OS and comes from glibc) doesn't know how to find the newer libstdc++, so it finds the default system one, which is too old.
The problem and solution are described at in the Libstdc++ FAQ, "How do I insure that the dynamically linked library will be found?", and manual, "Finding Dynamic or Shared Libraries"
This doesn't sound right.
Can you show us what you do to override the compiler?
If you are only doing the above, I don't think your compiler will be overridden with the new version.
You need to do something like
env = Environment(CC='/path/to/gcc')
Or Environment(CXX='/path/to/g++') if you want to override the c++ compiler
Or is your path on your environment setup to have the directory of the custom compiler before the standard compilers directory?
It might help to clean and then run with scons with --debug=presub which will show you the command line used to build each target.
Also your environment is a dictionary, so try printing out different keys to make sure they match what you expect:
print env['CC']
print env['CXX']

gcc static library linking vs dynamic linking

My build environment is CentOS 5. I have a third party library called libcunit. I installed it with autotools and it generates both libcunit.a and libcunit.so. I have my own application that links with a bunch of shared libraries. libcunit.a is in the current directory and libcunit.so and other shared libraries are in /usr/local/lib/. When I compile like:
gcc -o test test.c -L. libcunit.a -L/usr/local/lib -labc -lyz
I get a linkage error:
libcunit.a(Util.o): In function `CU_trim_left':
Util.c:(.text+0x346): undefined reference to `__ctype_b'
libcunit.a(Util.o): In function `CU_trim_right':
Util.c:(.text+0x3fd): undefined reference to `__ctype_b'
But when I compile with .so like:
gcc -o test test.c -L/usr/local/lib -lcunit -labc -lyz
it compiles fine and runs fine too.
Why is it giving error when linked statically with libcunit.a?
Why is it giving error when linked statically with libcunit.a
The problem is that your libcunit.a was built on an ancient Linux system, and depends on symbols which have been removed from libc (these symbols were used in glibc-2.2, and were removed from glibc-2.3 over 10 years ago). More exactly, these symbols have been hidden. They are made available for dynamic linking to old binaries (such as libcunit.so) but no new code can statically link to them (you can't create a new executable or shared library that references them).
You can observe this like so:
readelf -Ws /lib/x86_64-linux-gnu/libc.so.6 | egrep '\W__ctype_b\W'
769: 00000000003b9130 8 OBJECT GLOBAL DEFAULT 31 __ctype_b#GLIBC_2.2.5
readelf -Ws /usr/lib/x86_64-linux-gnu/libc.a | egrep '\W__ctype_b\W'
# no output
Didn't notice that the libcunit.a is actually found in your case and the problem with linakge is rather in the CUnit library itself. Employed Russian is absolutely right, and he's not talking about precompiled binary here. We understand that you've built it yourself. However, CUinit itself seems to be relying on the symbol from glibc which is not available for static linking anymore. As a result you have only 2 options:
File a report to the developers of CUnit about this and ask them to fix it;
Use dynamic linking.
Nevertheless, my recommendation about your style of static linkage still applies. -L. is in general bad practice. CUnit is a 3rd party library and should not be placed into the directory containing source files of your project. It should be rather installed in the same way as the dynamic version, i.e. like you have libcunit.so in /usr/local/lib. If you'd supply prefix to Autotools on the configure stage of CUnit, then Autotools would install everything properly. So if you want to link statically with CUnit, consider doing it in the following form:
gcc -o test test.c -L/usr/local/lib -Wl,-Bstatic -lcunit -Wl,-Bdynamic -labc -lyz

Specifying Exact Library to Link with In Automake

I am having extreme trouble cross compiling a project related to gstreamer. I am trying to link it to a library on my cross compile machine's /usr/lib
If I do the standard linker flags -L{FILESYS_DIR}/usr/lib -lGLESv2 I get pthread complaints from my cross compile toolchain. Thus, I am trying to link to this library without using the -L flag.
No matter what I do, I am getting undefined symbol glFramebuffer2D. However a quick readelf -Wc $FILESYS_DIR/usr/lib/libGLESv2.so | glFrame shows me a glFramebuffer2D symbol.
I'm pulling my hair out because no matter what flags I specify to autoconf, something called libtool throws away my link request unless I use the -L -l approach...
Edit: I had another idea, I tried -Wl, $FILESYS_DIR/usr/lib/libGLESv2.so which worked in compiling and linking but not during runtime... Obvious to me (now) because the host machine root is $FILESYS_DIR. Anyways, this is on the right approach, but I guess I need relative names.
libtool: link: arm-none-linux-gnueabi-gcc -shared .libs/libgstbla_la-gstblaoverlay.o
.libs/libgstbla_la-gstblastabilize.o .libs/libgstbla_la-gles2_utilities.o -Wl,-
rpath -Wl,/home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib -Wl,-rpath -
Wl,/home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib -L/home/z3/z3-
netra/filesys/fs/opt/gstreamer/lib /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgstbase-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgstreamer-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgstvideo-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgobject-2.0.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgmodule-2.0.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libgthread-2.0.so -lrt /home/z3/z3-netra/filesys/fs//opt/gstreamer-
0.4/lib/libglib-2.0.so -pthread -Wl,-soname -Wl,libgstbla.so -Wl,-version-script -
Wl,.libs/libgstbla.ver -o .libs/libgstbla.so
If needed, in one line as well:
libtool: link: arm-none-linux-gnueabi-gcc -shared .libs/libgstbla_la-gstblaoverlay.o .libs/libgstbla_la-gstblastabilize.o .libs/libgstbla_la-gles2_utilities.o -Wl,-rpath -Wl,/home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib -Wl,-rpath -Wl,/home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib -L/home/z3/z3-netra/filesys/fs/opt/gstreamer/lib /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgstbase-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgstreamer-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgstvideo-0.10.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgobject-2.0.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgmodule-2.0.so /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libgthread-2.0.so -lrt /home/z3/z3-netra/filesys/fs//opt/gstreamer-0.4/lib/libglib-2.0.so -pthread -Wl,-soname -Wl,libgstbla.so -Wl,-version-script -Wl,.libs/libgstbla.ver -o .libs/libgstbla.so
/usr/lib should already be on the library search path, so you shouldn't need to specify an RPATH. What you do need to do though, is to tell your (cross-)linker where to find the libraries. I think that includes transitively dependencies, such as libpthread. Do you have $FILESYS_DIR/usr/lib/libpthread.so? Does it point to /lib/libpthread.so.N? Oh wait, I see something now that I wrote it out: notice the (likely) absence of $FILESYS_DIR there: so it's possible that your linker is looking for libpthread transitively needed by libGLESv2, but not finding it, since $FILESYS_DIR/lib is not on the library include path. Add -L $FILESYS_DIR/lib to your linker flags and try again.
All, this was related to the following question: set global gcc default search paths
The problem here is related to the pthread.so (also glib.so). /usr/lib/pthread.so on a lot of systems is an ASCII script which then further links to the system's /lib/pthread.so.0 (which is a soft link). When compiling, my $(FILESYS_DIR) was correct, however the the libpthread.so there pointed to the host systems pthread.so
I made a HUGE mistake here which could have been easily avoided with correct cross compilation management. When compiling for a target system, do not use files on the target system filesystem (if it's a NFS as mine was.) Use local libraries compiled for that target system. FURTHERMORE, specify -Wl,-rpath-link=/[local location where your *.so reside]
That compiler/linker flag allows for the runtime path to be on the local system during compile and link, but maintain the standard runtime path during runtime.... Hope that made sense.

Resources