I built boost 1.57.0 in QNX 6.5.0. There is no build error. But some libraries are linked to libboost_system.so specifying relative path. I saved compilation logs. Here is linkage step for boost_thread:
"QCC_gpp" -o "bin.v2/libs/thread/build/qcc/release/threading-multi/libboost_thread.so.1.57.0" -shared "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/thread.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/pthread/once.o" "bin.v2/libs/thread/build/qcc/release/threading-multi/future.o" "bin.v2/libs/system/build/qcc/release/threading-multi/libboost_system.so.1.57.0" -lm
So, When I run ldd libboost_thread.so
, it can't find libboost_system. I think libboost_thread should be linked with -lboost_system
option. But I don't know how to do this.
Thanks.
Edit: I cannot build any program linking with boost_thread. Because, boost_thread searches boost_system in bin.v2/libs/system/build/qcc/release/threading-multi
folder. However both boost_thread and boost_system are in a library search folder. (defined with LD_LIBRARY_PATH
)
If you run objdump -p libboost_thread.so
, you'll find that the NEEDED entry for libboost_system.so contains a (relative) path. According to the ELF specification, the NEEDED entry should contain only the name of the needed library, so there seems to be a bug in the linker or in QCC.
Because if this, the system won't be able to find the file at run-time unless the current directory is the same as it was when linking took place.
The simplest work-around is to link statically to libboost_thread.a.
Another work-around that I've used myself is to create a wrapper around QCC that transforms the command line so that dependencies are given as -Wl,-L <path> -Wl,-l <name>
instead of <path>/lib<name>.so
This also requires a change to the Boost build system so that it doesn't append the version number to the end of library file names.
As Nicklas Angare wrote, the problem is the NEEDED
entry contains the relative path at build time, when it should just contain the name of the .so file.
That happens because the shared libraries given to the linker do not have a SONAME
, and that happens because the linker was not given the -h option.
From the ld documentation:
-h name
-soname=name
When creating an ELF shared object, set the internal DT_SONAME field to the specified name. When an executable is linked with a shared object which has a DT_SONAME field, then when the executable is run the dynamic linker will attempt to load the shared object specified by the DT_SONAME field rather than the using the file name given to the linker.
Why doesn't the linker get the -h option for a qcc
build? It appears to be a long-overlooked Boost bug (see Boost.org ticket, github issue)
The solution, as suggested in the above links, is to remove $(HAVE_SONAME)
from tools/build/v2/tools/qcc.jam
I think you're supposed to take the libraries from the staging area.
I usually have something similar to:
-L /home/.../boost/stage/lib/ -lboost_system
Of course replacing /home/.../boost
with your boost directory
Slightly related: with the above config, you need to make sure that the right versions of the libraries are on the loader library path (LD_LIBRARY_PATH, ldconfig).
If you want a development build that you can "just run" on the system that you built this on, you can bake the library path right into the target binary:
-Wl,-rpath -Wl,/home/.../boost/stage/lib/:/usr/lib/x86_64-linux-gnu