PCL install links directly to boost installation directory somehow - c++

I have a very odd problem with the installation of PCL. Basically i have set up PCL, boost, cmake, flann etc.. it all builds and compiles correctly. I copied and built the ICP example and it builds just fine.
Here is where it gets weird. When I run the application I get the following error:
ldd:FATAL: Could not load library bin.v2/libs/system/build/qcc-4.4.2/
release/threading-multi/libboost_system.so.1.48.0
So libboost_system.so.1.48.0 exists in the /usr/local/lib path and is even linked earlier by the same application, ie. if i run ldd on the application i get the following linked library information:
$ ldd iterative_closest_point
./iterative_closest_point:
libboost_system.so => /usr/local/lib/libboost_system.so.1.48.0 (0xb8200000)
libboost_filesystem.so => /usr/local/lib/libboost_filesystem.so.1.48.0 (0xb8209000)
libboost_thread.so => /usr/local/lib/libboost_thread.so.1.48.0 (0xb8225000)
OTHER BOOST
libpcl_common.so.1.7 => /usr/local/lib/libpcl_common.so.1.7.1 (0xb82ea000)
libpcl_octree.so.1.7 => /usr/local/lib/libpcl_octree.so.1.7.1 (0xb838c000)
OTHER PCL
libstdc++.so.6 => /usr/qnx650/target/qnx6/x86/lib/libstdc++.so.6.0.13 (0xb9285000)
libm.so.2 => /usr/qnx650/target/qnx6/x86/lib/libm.so.2 (0xb8774000)
libc.so.3 => /usr/lib/ldqnx.so.2 (0xb0300000)
ldd:FATAL: Could not load library bin.v2/libs/system/build/qcc-4.4.2/release/threading-multi/libboost_system.so.1.48.0
So I did some investigation into what the hell PCL is looking for, what is bin.v2? It exists in the boost install directory????
Now here is where it just gets nuts, if i run the program with an absolute path from the boost install directory ie. where the bin.v2 folder exists:
qnx:/root/boost/boost_1_48_0# /root/experiments/checkPCL/iterative_closest_point
it works!! the program outputs the desired things. So i was like alright, lets run ldd here:
qnx:/root/boost/boost_1_48_0# ldd /root/experiments/checkPCL/iterative_closest_point
and we get this:
libboost_system.so => /usr/local/lib/libboost_system.so.1.48.0 (0xb8200000)
MORE BOOST
libpcl_common.so.1.7 => /usr/local/lib/libpcl_common.so.1.7.1 (0xb82ea000)
MORE PCL
libstdc++.so.6 => /usr/qnx650/target/qnx6/x86/lib/libstdc++.so.6.0.13 (0xb9285000)
libm.so.2 => /usr/qnx650/target/qnx6/x86/lib/libm.so.2 (0xb8774000)
libc.so.3 => /usr/lib/ldqnx.so.2 (0xb0300000)
libboost_system.so.1.48.0 => /root/SMG/extern/libs/boost/boost_1_48_0/bin.v2/libs/system/build/qcc-4.4.2/release/threading-multi/libboost_system.so.1.48.0 (0xb87a7000)
libbz2.so.1.0.4 => /usr/lib/libbz2.so.1.0.4 (0xb87b0000)
libz.so.2 => /proc/boot/libz.so.2 (0xb87c2000)
The big long one is an absolute link into the boost filepath. I dont understand how PCL or ldd or anything could know about this path.
Does anyone have any ideas about how this could have happened? Also I need some solutions on how to fix it.
EDIT + ADD:
So recently, i am not sure what has changed but i have started to get the linker warning (not error):
/usr/qnx650/host/qnx6/x86/usr/bin/ntox86-ld: warning: bin.v2/libs/system/build/
qcc-4.4.2/release/threading-multi/libboost_system.so.1.48.0, needed by
/usr/local/lib/libboost_filesystem.so, not found (try using -rpath or -rpath-link)
so for whatever reason this is definitely attempting to link to bin.v2/.../... which is absolutely nuts, i have never seen this before? I have now scoured the boost install directory looking for things that might caused this. Nothing is unusual about how boost is installed.
As a further note i have made a simple example, a program that has main, includes and prints "it works", it has the following CMakeLists.txt:
find_package(PCL 1.2 REQUIRED)
find_package(Boost 1.48.0 COMPONENTS system filesystem REQUIRED)
add_executable (test test.cpp)
target_link_libraries(test
${BOOST_FILESYSTEM} #Works
${PCL_DEFINITIONS} #Works
${PCL_SEARCH_LIBRARIES} #If i add this it fails!
)
So it seems like PCL and boost are interacting badly and causing some truly crazy behavior!

This may not be of help but I have the same problem and here is what I found. That path is used by some boost libraries.
objdump -x libbost_filesystem-qcc-mt-1_55.so will show:
Dynamic Section:
NEEDED bin.v2/libs/system/build/qcc/release/threading-multi/libboost_system-qcc-mt-1_55.so.1.55.0
NEEDED libm.so.2
NEEDED libstdc++.so.6
NEEDED libc.so.3
INIT 0x00004d40
Notice the full path.
I came upon this post while looking for a solution to this problem. I'm pretty sure it's a boost build related issue though, I'm also using QNX.

If it works from the absolute directory that contains bin.v2/libs/system/build/qcc-4.4.2/release/threading-multi/ then probably you have
set LD_LIBRARY_PATH set to include . (the current working directory)
added the current work directory using ldconfig somehow (there's several ways)
This is a bad idea in general. It's especially a bad idea if you're running as root (which it seems you do) because it can be exploited as a security hole.
The real issue would still appear to be that the linker embeds the full path for libboost_system. I don't know what causes this, but perhaps
you specify the library as a concrete source (libboost_system.so.1.48.0 in stead of -lboost_system on most linkers/compilers)
it is some kind of linker option (like -rpath?)
Hope this helps

Related

How to manually disable libstdc++ in CMake for Clang

Recently I'm configuring a new project in language C and C++ using both CMake and llvm Clang with Visual Studio Code for a program where EVERY exact object or library it generates or depends needs specifying explicitly to make or link against. The program by design should feature high RAM efficency, security for the least vulnerabilities induced by the unused data segments and cross-compilation.
That being said, the provision libraries for architecture, application binary interface (aka ABIs), standard libraries functions from C and C++ standard and executable binary need manual setup for toolchain program to process in appropriate manner.
Well, the libstdc++ substitution with libc++ library is what I think a good "entry point" to kick-off, but definitely not straight forward, which you might have learned enough from documented painful practices elsewhere and think of that as a bad idea...but I'm sorry, this has become my obsession. I really appreciate your help before it drives me nuts here.
Anyway, here is a list of information about my local machine in below:
Ubuntu 20.04 # v5.13.0-40-generic kernel, SMP, x86_64 instruction-set
CMake 3.23.1, built from source
gcc-10:amd64
clang-12:amd64
libstdc++-10-dev:amd64
libc++-12-dev:amd64
Clang works fine to return from command:
jacob.nielson#ubuntu~$: clang++-12 -v -c -xc /dev/null
to keep the new project from any future unexpected and irrelevant issue as much as possible, I leave the project directory layout as simple as it could be before making a CMakeLists.txt:
To begin with, I looked up in CMake's document about either compiling (preprocessing) or linking options:
-"-nostdinc"
-"-nostdinc++"
-"-nobuiltininc"
-"-nostdlib"
-"-nolibc"
-"-nostdlib++"
-"-nodefaultlibs"
Then I come up with a few simple lines in the CMakeLists.txt:
cmake_minimum_required(VERSION 3.23.0)
project(program VERSION 0.0.1)
set(TARGET program)
add_compile_options(-std=c++17)
# I'm not sure about semantics of "-nostdinc++", "-nostdinc" and "-nobuiltininc".
# Should I add them all in case to substitute libstdc++ with libc++ or not in below?
add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nobuiltininc>)
add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc++>)
add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-nostdinc>)
# Should I add path to system headers in "-isystem" option?
# Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-isystem" where the path to directory as value follows without white-space in this example.
add_compile_options(
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-isystem/usr/include/x86_64-linux-gnu>
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-isystem-after/usr/include>
# "-cxx-isystem" option is legacy and is not appropriate for standard headers. Add path to the subdirectories where you put your own c++-only headers in your project.
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:-cxx-isystem ${...}>
)
# If C or/and C++ standard library is turned off like in above, Should I add path to libc++ headers in "-stdlib++-isystem" option?
# Attention: cmake-generator-expression does not recognize white-space separated options group to be string. It is option "-stdlib++-isystem" where the path to directory as value follows without white-space in this example.
add_compile_options($<$<COMPILE_LANG_AND_ID:CXX,Clang>:-stdlib++-isystem/usr/lib/llvm-12/include/c++/v1>)
# Replace default C++ standard with libc++.
add_link_options(
$<$<LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
)
add_executable(${TARGET} "${CMAKE_CURRENT_SOURCE_DIR}/source/${TARGET}.cpp")
target_link_libraries(${TARGET} PRIVATE
$<$<LINK_LANG_AND_ID:CXX,Clang>:c++>
$<$<LINK_LANG_AND_ID:CXX,Clang>:c++abi>
$<$<LINK_LANG_AND_ID:CXX,Clang>:unwind>
$<$<LINK_LANG_AND_ID:CXX,Clang>:ssl>
$<$<LINK_LANG_AND_ID:CXX,Clang>:crypto>
$<$<LINK_LANG_AND_ID:CXX,Clang>:pthread>
)
Next, I tried to generate "Unix Makefiles" for project:
CMake parsed successfully:
Meanwhile it generates CMakeCCompiler.cmake and CMakeCXXCompiler.cmake in ./build/CMakeFiles/3.23.1/ temporary folder, the later contains a few lines:
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/10;/usr/include/x86_64-linux-gnu/c++/10;/usr/include/c++/10/backward;/usr/local/include;/usr/lib/llvm-12/lib/clang/12.0.0/include;/usr/include/x86_64-linux-gnu;/usr/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/10;/usr/lib/x86_64-linux-gnu;/usr/lib64;/lib/x86_64-linux-gnu;/lib64;/usr/lib;/usr/lib/llvm-12/lib;/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
Note: Clang uses heuristic discovery to search headers in directories which are reported by front-end.
This is inappropriate because I just don't want either headers or libraries of libstdc++ to be implicitly used within the project.
Also, it exports compile commands into compile_commands.json as below:
/usr/bin/clang++-12 -DLIBCXXABI_USE_COMPILER_RT=YES -DLIBCXX_USE_COMPILER_RT=YES -I/data/solution/projects/program/include -std=c++17 -stdlib=libc++ -isystem /usr/include/x86_64-linux-gnu -stdlib++-isystem /usr/lib/llvm-12/include/c++/v1 -o CMakeFiles/program.dir/source/program.cpp.o -c /data/solution/projects/program/source/program.cpp
It all looks good. But when I use ldd to check:
jacob.nielson#ubuntu:/data/solution/projects/program/build/debug$ ldd program
linux-vdso.so.1 (0x00007ffee7190000)
libc++.so.1 => /lib/x86_64-linux-gnu/libc++.so.1 (0x00007f69164a5000)
libc++abi.so.1 => /lib/x86_64-linux-gnu/libc++abi.so.1 (0x00007f691646d000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f691628b000) /* LIBSTDC++ in here! */
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f691613c000) /* LIBM in here */
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f6916121000) /* gcc startup file in here! */
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6915f2f000) /* LIBC in here! */
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6915f0a000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f6915f00000)
libatomic.so.1 => /lib/x86_64-linux-gnu/libatomic.so.1 (0x00007f6915ef6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f691658d000)
It is frustrating to see all libstdc++, libc, libm or libgcc_s remain. Is there any option I missed to link them statically such like -static-libc in GNU CC or do I have to give up my ambition early at this point?
The answer to the question is hereby noted.
There is a mistake about missing definitions to instruct Clang to use compiler_rt. The problem is solved once I had add to relevant options.
As to replace libstsdc++ with libc++, one shall not forget to add the following options:
add_compile_definitions(
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:LLVM_ENABLE_RUNTIMES=libunwind>
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXX_USE_COMPILER_RT=YES>
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:LIBCXXABI_USE_COMPILER_RT=YES>
$<$<COMPILE_LANG_AND_ID:CXX,Clang>:LIBUNWIND_USE_COMPILER_RT=YES>
)
add_link_opptions(
$<$<LINK_LANG_AND_ID:CXX,Clang>:-stdlib=libc++>
$<$<LINK_LANG_AND_ID:CXX,Clang>:-rtlib=compiler-rt>
)
AFAK, definitions above help to instruct clang "not to link against default libraries", but one also has to use them in conjunction with compile option "-stdlib=libc++" and especially NO "-nostdlib" for the replace to take effect. Part of the document covers in below:
Compiler runtime
The default runtime library is target-specific. For targets where GCC
is the dominant compiler, Clang currently defaults to using libgcc_s.
On most other targets, compiler-rt is used by default.
However, it is much unclear to me what target refers to here and how comes to tell a compiler is dominant for a given target.

How to avoid 'cannot open shared object file' when using CMake?

Situation
My project uses CMake and compiles without problems on Ubuntu 16.04.
When starting the compiled application I get the message cannot
open shared object file.
All the shared object libs are available in the same non-standard
folder (and I need them there).
For some reason some can be found, but others cannot.
What I need
The reason why some shared objects can be found and others cannot be found. The project is pretty big with many CMake files. I tried to find the differences between the libs that can be loaded and the ones that can't, but without success. Any help that point me to the right place is welcome.
A solution within CMake to make it find all the shared objects.
ldd
The ldd output shows me that most shared objects can be found. Here are some examples:
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f2ed1fa0000)
libboost_filesystem.so.1.55.0 => /path/to/libs/boost/lib/libboost_filesystem.so.1.55.0 (0x00007f96af1f5000)
libboost_program_options.so.1.55.0 => /path/to/libs/boost/lib/libboost_program_options.so.1.55.0 (0x00007f96aef85000)
libboost_system.so.1.55.0 => /path/to/libs/boost/lib/libboost_system.so.1.55.0 (0x00007f96aed80000)
For some reason a few others cannot be found. For example:
libboost_iostreams.so.1.55.0 => not found
libboost_chrono.so.1.55.0 => not found
There are other non-boost libs that showing the same behavior, but for simplicity I am just showing the boost examples.
Workarounds already tried
Below are the workarounds that already work successfully. But I am really interested in the two points in the What I need section.
Copying to standard folders like /usr/lib and running ldconfig
Adding the path to LD_LIBRARY_PATH
tldr; Check that the imported library is imported as SHARED or UNKNOWN and not STATIC, and has an IMPORTED_SONAME property.
You should check how the library is being imported that you're linking.
I've analyzed a few of the config mode exported targets for static and dynamic libraries, and they are a little different in the properties they set for the target.
For example for zlib, here's the version for static libraries:
add_library(ZLIB::zlibstatic STATIC IMPORTED)
set_target_properties(ZLIB::zlibstatic PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "C"
IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libz.a"
)
However, for dynamic libraries it's:
add_library(ZLIB::zlib SHARED IMPORTED)
set_target_properties(ZLIB::zlib PROPERTIES
IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libz.so.1.2.11"
IMPORTED_SONAME_NOCONFIG "libz.so.1"
)
In a find_package module mode script, you might think you're importing a static library, when in fact the found library is a .so, so it may use the incorrect target properties. In config mode this is not likely because it's much more explicit when defining the target. Though, module mode (cmake/findXXX.cmake), you're often defining these properties as a result of FIND_PACKAGE_HANDLE_STANDARD_ARGS _LIBRARIES variable, and it's hard to tell what you're going to get. You can use libFoo.a in the search to be more explicit or playing with CMAKE_FIND_LIBRARY_SUFFIXES.

Portable way of linking libgfortran with CMAKE

One of my executables requires libgfortran.so. Typically I'd just add the -lgfortran switch to the compile line and it links automatically with g++. However, I'm trying to find the library with CMAKE using:
find_library(GFORTRAN_LIBRARY NAMES gfortran)
target_link_libraries(ncorr_test ${GFORTRAN_LIBRARY})
However, this fails to the find the library. It turns out the only way that has worked so far is if I include the entire library name like so:
find_library(GFORTRAN_LIBRARY NAMES libgfortran.so.3)
target_link_libraries(ncorr_test ${GFORTRAN_LIBRARY})
Then, it will link properly:
/usr/bin/c++ ... /usr/lib/x86_64-linux-gnu/libgfortran.so.3 ...
However, including the whole .so.3 is not very portable. Does anyone know of a better way to do this? Typically libraries I need to use are just installed in /usr/local/lib and searching for the library name without the "lib" and extension works (i.e. find_library(FFTW_LIBRARY NAMES fftw3) will find libfftw3.a in /usr/local/lib just fine).
EDIT:
find_library(GFORTRAN_LIBRARY NAMES libgfortran.so) does not work either. Only libgfortran.so.3 has worked so far.
Using locate libgfortran outputs:
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.so
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.spec
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortranbegin.a
/usr/lib/x86_64-linux-gnu/libgfortran.so.3
/usr/lib/x86_64-linux-gnu/libgfortran.so.3.0.0
/usr/local/MATLAB/R2014a/sys/os/glnxa64/libgfortran.so.3
/usr/local/MATLAB/R2014a/sys/os/glnxa64/libgfortran.so.3.0.0
/usr/share/doc/libgfortran-4.8-dev
/usr/share/doc/libgfortran3
/var/lib/dpkg/info/libgfortran-4.8-dev:amd64.list
/var/lib/dpkg/info/libgfortran-4.8-dev:amd64.md5sums
/var/lib/dpkg/info/libgfortran3:amd64.list
/var/lib/dpkg/info/libgfortran3:amd64.md5sums
/var/lib/dpkg/info/libgfortran3:amd64.postinst
/var/lib/dpkg/info/libgfortran3:amd64.postrm
/var/lib/dpkg/info/libgfortran3:amd64.shlibs
/var/lib/dpkg/info/libgfortran3:amd64.symbols
EDIT2:
For now I'll just require the user to copy libgfortran.a over to their usr\local\lib directory
Looks like you either miss dev package on your linux distribution, which should install .so link, or path where such link located is missing when cmake does lookup. Try to find libgfortran.so link, usually it is located the same place where .so.3 is, if you cannot find it install missing dev package, if you can check why that path is not included in cmake.

CMake: Linking Shared C++ Object from ExternalProject Produces Binaries with Relative Path, not Absolute

Problem: I am building an external project in CMake. The project has a Makefile that ultimately produces a shared object. I want to link against and install this object in my super project, just as if it were one of the libraries in the project. The problem is that the ExternalProject lib is getting linked into my applications and libraries with a relative path, not an absolute path which causes problems when running from any directory besides where CMake puts it.
I have created a sample SSCCE example project to demonstrate my overall setup. Feel free to peruse and compile if needed (git clone https://github.com/calebwherry/cmake-SO-question-main --recursive && cd cmake-SO-question-main && mkdir build && cd build && cmake .. && make && cd src/app/testApp && ldd testApp).
Whenever I run ldd on the executable and libs, I get output like this:
linux-vdso.so.1 => (0x00007fff8b5a2000)
libTestLib.so => /home/jwherry3/repos/cmake-superprj-main-test/build/src/lib/TestLib/libTestLib.so (0x00007f592da57000)
../../lib/libExtLib.so (0x00007f592d855000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f592d539000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f592d2b7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f592d0a0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f592cd14000)
/lib64/ld-linux-x86-64.so.2 (0x00007f592dc5a000)
I have tried all kinds of things dealing with RPATHS but can't get the ExtLib to link right. The lib that is local to the project (libTestLib.so) links just fine.
I also tried to set the LD_LIBRARY_PATH to override the relative path when I run the app but even when I do that, it still doesn't find the library. I suppose because it is relative it does not follow the normal linking order? The outcome is that the binary will not run unless I am in the directory where it resides.
I feel like I'm doing something really dumb when creating dependencies with the ExternalProject and that is my issue but I have beat my head for 3 days and haven't come up with anything.
System setup: Debian Wheezy 64-bit, CMake 3.0.2, g++-4.9.2.
Took awhile but I have finally arrived at an answer with help from the CMake Users listserv, specifically #brad-king.
The main issue is that I am not compiling my shared object correctly in my external project. Brad's answer to my question:
Thanks for the complete/simple example. The problem is that
the libExtLib.so file built by the external project does not
have DT_SONAME set by the linker. When a linker is given a
path to a shared library file that has no soname then the path
is copied into the DT_NEEDED field of the consumer since it
has no soname to use for that.
There are two solutions:
Make sure DT_SONAME gets set properly by the external build system.
Tell CMake that the imported library file has no soname:
set_property(TARGET ExtLib PROPERTY IMPORTED_NO_SONAME 1)
CMake will then link it via -lExtLib and the linker will not
store the path to the file in DT_NEEDED but only the file name.
Either of these should resolve the issue. Number 1 is cleaner.
Since I have control over the Make files in the external library, I opted for the cleaner first solution by compiling the shared object like so:
$(SHARED_TARGET): $(OBJECTS)
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $# $(LDFLAGS) -Wl,-soname,$#
I have revised my original example and made it a lot simpler: https://github.com/calebwherry/cmake-SO-question-main. I will leave it up as a reference for anyone stumbling across this post at a later date.
P.S.
There is another fix that is sub-optimal. If I hadn't done any of the above, I could have just given target_link_library the full path to the library I was linking against and not used the imported library target. I have noted this in the CMake file in the repo and commented it out. Not a great solution but does solve the issue another way.

How do I get rid of LD_LIBRARY_PATH at run-time?

I am building a C++ application that uses Intel's IPP library. This library is installed by default in /opt and requires you to set LD_LIBRARY_PATH both for compiling and for running your software (if you choose the shared library linking, which I did). I already modified my configure.ac/Makefile.am so that I do not need to set that variable when compiling, but I still can't find the shared library at run-time; how do I do that?
I'm compiling with the -Wl, -R/path/to/libdir flag using g++
Update 1:
Actually my binary program has some IPP libraries correctly linked, but just one is not:
$ ldd myprogram
linux-vdso.so.1 => (0x00007fffa93ff000)
libippacem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippacem64t.so.6.0 (0x00007f22c2fa3000)
libippsem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippsem64t.so.6.0 (0x00007f22c2d20000)
libippcoreem64t.so.6.0 => /opt/intel/ipp/6.0.2.076/em64t/sharedlib/libippcoreem64t.so.6.0 (0x00007f22c2c14000)
[...]
libiomp5.so => not found
libiomp5.so => not found
libiomp5.so => not found
Of course the library is there:
$ locate libiomp5.so
/opt/intel/ipp/6.0.2.076/em64t/sharedlib/libiomp5.so
By /path/to/lib do you mean path to the directory containing the library, or the path to the actual file?
The -R option given a directory argument is treated like -rpath by ld, which is the option you're actually wanting here. It adds the given directory to the runtime library search path. That should work, as long as you give it the directory and not filename. I'm fairly confident about that, having done it myself, and because it's one of the hints given by libtool:
Libraries have been installed in:
/path/to/library-directory
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
use the `-Wl,-rpath -Wl,LIBDIR' linker flag
have your system administrator add LIBDIR to `/etc/ld.so.conf'
(I paste this here since conceivably one of the other options could be more desirable - for example LD_RUN_PATH can save you makefile modification)
As suggested by Richard Pennington, the missing library is not used directly by my application, but it is used by the shared libraries I use. Since I cannot recompile IPP, the solution to my problem is to add -liomp5 when compiling, using the -R option for the linker. This actually adds the rpath for libiomp5.so fixing the problem!
You can check if the path to the library is being picked up from your -R flag by running the ldd command or the readelf command on your binary. The LD_LIBRARY_PATH environment variable is an override, so shouldn't be necessary normally.
You should use the -R option if possible.
If not, rename your executable and create a launch script that runs your executable, and in there set LD_LIBRARY_PATH just for that scope.
Depending on platform, you can modify ld.so.conf via /etc/ld.so.conf.d (Redhat/Fedora come to mind) which makes deploying changes to ld.so "easier" from a deployment scenario.
Besides all the useful hints posted here.. you're not trying to use a 64-bit specific library on a 32-bit system (or viceversa, depending on other conditions), are you?
bash:
export LD_LIBRARY_PATH=/path/to/lib
tcsh:
setenv LD_LIBRARY_PATH /path/to/lib
Try configuring your ldconfig through ld.so.conf so it searches your /opt/... directory by default.