Custom .m4 macro not working with configure.ac - fortran

I'm trying to update an arcane scientific F77 program to the modern world by making it easier to install w/ a .configure script. However, this has proved to be more difficult than advertised. The program I'm dragging kicking and screaming into the 21st century requires the SuperMongo plotting library, and I'm trying to figure out how to have Automake find the correct path for the necessary SuperMongo libraries (libplotsub.a, libdevices.a, and libutils.a) Rather than have you kind souls look at the guts of the code, I've created a skeleton github repository (https://github.com/Acetylene5/autoconf_testing).
The main program is test.f, and calls the junk.f file. Both files include the Stuff.com common block. The file junk.f calls two functions: one (dcopy) is from the LAPACK library, and the other (drawcurs) is from the SuperMongo program. The reason I did this is because this program I'm fast-forwarding out of the stone age uses both these libraries.
I found on the interwebs a LAPACK macro (ax_lapack.m4) which seems to find the LAPACK libraries on my system. I've attempted to copy this .m4 file to ax_supermongo.m4, and change the requisite names and directories. However, I am not an M4 expert, so I have no idea if this is doing what I want. I don't think it is, because if you look at the output of ./configure, it doesn't seem to find the sm_graphics file (the token supermongo routine used by ax_supermongo.m4 to the location of the SM libraries):
deen#aida44170:~/Code/FORTRAN/testing/autoconf/master> autoreconf -i
deen#aida44170:~/Code/FORTRAN/testing/autoconf/master> ./configure
configure: loading site script /usr/share/site/x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether the Fortran 77 compiler works... yes
checking for Fortran 77 compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU Fortran 77 compiler... no
checking whether /usr/local2/misc/iraf/iraf/unix/hlib/f77.sh accepts -g... yes
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking dependency style of gcc... none
checking for sgemm_... no
checking for ATL_xerbla in -latlas... no
checking for sgemm_ in -lblas... yes
checking for dgemm_ in -ldgemm... no
checking for sgemm_ in -lmkl... no
checking for sgemm_... (cached) no
checking for sgemm_ in -lcxml... no
checking for sgemm_ in -ldxml... no
checking for sgemm_ in -lscs... no
checking for sgemm_ in -lcomplib.sgimath... no
checking for sgemm_ in -lblas... (cached) yes
checking for sgemm_ in -lessl... no
checking for sgemm_ in -lblas... (cached) yes
checking build system type... x86_64-suse-linux-gnu
checking host system type... x86_64-suse-linux-gnu
checking how to get verbose linking output from /usr/local2/misc/iraf/iraf/unix/hlib/f77.sh... configure: WARNING: cannot determine how to obtain linking information from /usr/local2/misc/iraf/iraf/unix/hlib/f77.sh
checking for Fortran 77 libraries of /usr/local2/misc/iraf/iraf/unix/hlib/f77.sh...
checking for dummy main to link with Fortran 77 libraries... none
checking for Fortran 77 name-mangling scheme... lower case, underscore, extra underscore
checking for cheev_... no
checking for cheev_ in -llapack... yes
checking for sm_graphics__... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: executing depfiles commands
On my system, the Supermongo libraries reside in: /usr/local/misc/sm/sm2_4_36/lib/
Any suggestions on how to get autoconf to look into this directory, or possibly use a command-line variable to pass the directory here?
Please let me know if you need any more information.
Casey

autoconf does not try to find the libraries for you, but the configure script that it generates does. If you want that configure script to look in /usr/local/misc/sm/sm2_4_36/lib/, the mechanism you use will depend on your system, but it is very common to give an argument to the configure script of the form LDFLAGS=-L/usr/local/misc/sm/sm2_4_36/lib/. You will probably also have to add a similar -I clause to CPPFLAGS to find the header files.

Related

Issues in c++ compilation for embedded system

I have a few related questions about my issues with compilation for embedded system. My questions are not only about HOW to do something, but more about WHY, because I have solutions for my problems (but maybe there are better ones?), but have no idea why some things works in some conditions, and does not work in others. I already spent some time with this, but until yesterday I was doing things a little blindly, with trials and errors, and without knowing what I was doing. Time to stop that! Please, help.
Scenario
I want to develop an application for Xilinx’s Zynq ARM processor, on Zedboard. The app will involve multithreading, some audio manipulation, and httpserver. So I will need pthread, alsa, sndfile and microhttpd libraries. I created rootfs with yocto. In original conf.local file I added/modified these lines:
BB_NUMBER_THREADS ?= "${#oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${#oe.utils.cpu_count()}"
MACHINE ?= "zedboard-zynq7"
PACKAGE_CLASSES ?= "package_deb"
EXTRA_IMAGE_FEATURES = "debug-tweaks eclipse-debug"
IMAGE_INSTALL_append = "libgcc alsa-utils mpg123 libstdc++ sthttpd libmicrohttpd libsndfile1"
LICENSE_FLAGS_WHITELIST = "commercial_mpg123"
I also had to add some additional layers to bblayers.conf (and of course downloaded them):
meta-xilinx
meta-multimedia (from meta-openembedded)
meta-oe (from meta-openembedded)
meta-webserver (from meta-openembedded)
Lastly, I generated core-image-minimal with bitbake.
This, together with Linux kernel, and other stuff compiled separately, boots and works fine.
Problems
1. Simple app with this rootfs
It is app for Zynq, so I use XSDK, which is SDK from Xilinx, based on Eclipse. I created new Application project. In dialog window I chose Linux as platform, C++ as language, and I provided path to my unpacked rootfs (excactly the one that system boots with, via NFS). My rootfs path is /home/stas/ZedboardPetalinuxFS (it is not Petalinux, I just used to use it, and this folder name is still the same). This sets proper paths for library and headers search in rootfs.
I started with something very simple:
#include <pthread.h>
int main()
{
int i;
i = 1;
return 0;
}
I also added pthread library for linker (in Eclipse settings). Linking command at this point:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf" ./src/main.o -lpthread
At this point it compiles. But it stops, when I add sndfile library
#include <sndfile.h>
This is reasonable, because this rootfs does not have all headers. I need to add another path for searching for headers. So I added path in yocto tmp folder, that has all the headers, that was needed for building rootfs. After I add it, it compiles again successfully. But problems started, when I added sndfile library for linking. Here is linking command and error:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf" ./src/main.o -lpthread -lsndfile
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lsndfile
I looked to usr/lib to check if libsndfile.so is there, and I found only libsndfile.so.1 and ibsndfile.so.1.27. But it is also the case for pthread, and linker does not complain for that. I decided to create libsndfile.so by hand (I linked it to libsndfile.so.1). Linker stopped complaining about it, but started complaining about it’s dependencies. So I also creaded .so files for all the dependencies, and their dependencies, and added them for linking. Then it succeeded. At the end, linking command looked like this:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf" ./src/main.o -lpthread -lvorbisenc -lvorbis -logg -lFLAC -lsndfile
So here goes the first question – why I did not needed .so file for pthread, but needed it for all other libraries? Or more general – when do I need .so file, and when .so.X file is enough?
2. Simple app - another approach
After the first try, I thought I should make another image, this time more suitable for development. Luckily, in Yocto it is quite easy – I just had to modify one line:
EXTRA_IMAGE_FEATURES = "debug-tweaks eclipse-debug dev-pkgs"
dev-pkgs option adds -dev packages for all installed packages.
So now I have rootfs with all needed headers, and .so files pointing where they should.
Before compilation, I removed unnecessary Include path, leaving only the one from rootfs, and removed all the libraries, except pthread, and sndfile. But then I get new errors:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" -o "test.elf" ./src/main.o -lsndfile -lpthread
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find /lib/libpthread.so.0
makefile:48: polecenia dla obiektu 'test.elf' nie powiodły się (commands for ‘test.elf’ did not succeed)
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find /usr/lib/libpthread_nonshared.a
I spotted, that it looks for libraries in my root folder. Quick search in Google (and SO:)) told me that I should set –-sysroot variable. So I added it to Eclipse option (in Miscelenious card in Linker options) like that:
--sysroot=/home/stas/ZedboardPetalinuxFS
So now linker command looked like this:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" --sysroot=/home/stas/ZedboardPetalinuxFS -o "test.elf" ./src/main.o -lsndfile -lpthread
And all succeed! I also wrote simple example that uses pthreads, and sndfile, and it also worked. But WHY? This leads me to second question:
Why do I need --sysroot option in this case? When do I need to use this option in general? And why this time I didn't have to add all the dependencies to linking command?
3. Another idea
At this point, I had an idea, to check what will happen, if I add --sysroot option having rootfs populated with old, non development image. But this gave me new errors:
arm-linux-gnueabihf-g++ -L"/home/stas/ZedboardPetalinuxFS/usr/lib" -L"/home/stas/ZedboardPetalinuxFS/lib" --sysroot=/home/stas/ZedboardPetalinuxFS -o "test.elf" ./src/main.o -lpthread -lvorbisenc -lvorbis -logg -lFLAC -lsndfile
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find crt1.o: No such file or directory
makefile:48: polecenia dla obiektu 'test.elf' nie powiodły się
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find crti.o: No such file or directory
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lpthread
/opt/Xilinx/SDK/2016.4/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin/../lib/gcc/arm-linux-gnueabihf/5.2.1/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lm
So third question – what does this errors mean?
Thanks very much in advance!
"why I did not needed .so file for pthread, but needed it for all
other libraries?"
Actually you do need pthread.so file. You included pthread.h but didn't link with -lpthread. So it's normal you don't see any linker errors.
"when do I need .so file, and when .so.X file is enough"
When you give "-lNAME" parameter to g++, the compiler tells the linker to find libNAME.so within library search paths. Since there may exist multiple versions of the same library(libNAME.so.1, libNAME.so.1.20), *.so files link to desired actual library file. (Versioning of shared objects, ld man pages)
"Why do I need --sysroot option in this case? When do I need to use this option in general? And why this time I didn't have to add all the dependencies to linking command?"
The "dev-pkgs" in EXTRA_IMAGE_FEATURES changes your sysroot implicitly to let you link against the dev packages(yoctoproject image-features). That's why you need -sysroot option. You generally need this option when cross compiling to provide a root for standard search paths for headers and libraries. You didn't need it because you didn't have dev-pkgs image feature that changes your sysroot
"So third question – what does this errors mean?"
Even your the most basic hello world code gets linked with standard c library(if you didn't specify otherwise). libm.so, libpthread.so and crt1.o files are parts of libc library and come with libc dev package. So the linker can't see the standard library directories when it looks from your old sysroot
why I did not needed .so file for pthread, but needed it for all other libraries?
A cross compiler will normally come with a C Runtime (including pthread), typically in a directory that is part of the cross compiler installation.
The linker has built in search paths for libraries. These are in respect to the sysroot, which would by default be set to search the cross compiler's own included target C Runtime. If you added any -L options it would search those first and then move on to these pre-defined directories.
When you linked against pthread it would have found at least libpthread.a in the cross compiler's library directory.
Or more general – when do I need .so file, and when .so.X file is enough?
Shared libraries in Linux typically have a major and a minor version number. Libraries are ABI compatible between different minor versions with the same major version, but not between major versions. Sometimes there are three levels of versions but the principal is similar.
When installing libraries it is common to install the actual file with the full name, eg. libmy.so.1.2, then provide symlinks to libmy.so.1 and libmy.so.
If you are linking an application can work with any library version then you would just specify the name, eg. -lmy. In that case you would need symlinks from libmy.so to libmy.so.1.
If you required a specific version you would put -l:libmy.so.1. The ':' indicates a literal file name.
Linker scripts may affect things and may result in specific versions being selected even when you do specify the short name.
Why do I need --sysroot option in this case? When do I need to use
this option in general?
What --sysroot does is prepend the given path onto all the search directories which would normally be used to search for includes and libraries. It is most useful when cross compiling (as you are doing now) to get the compiler and the linker to search inside the target root instead of the build host's own root.
If you have specified a sysroot you probably do not need to specify include paths via -I or linker paths via -L, assuming that the files are within their normal spots inside your target root.
And why this time I didn't have to add all the dependencies to linking command?
One possible scenario is that the first time, sndfile for statically rather than dynamically linked. This would happen if your first root image had only sndfile.a in the lib dir, or elsewhere on the search path. To then satisfy the requirements of sndfile.a you would also need to link the other libs.
When linking against sndfile.so the dependencies will automatically get loaded via the dynamic linking process.
That's just a working theory at present.
So third question – what does this errors mean?
They mean it cannot find even the C runtime library to link.
As described for the first question, it was previously finding the C runtime in the pre-defined search path (relative to the predefined sysroot) which located the C runtime supplied by the cross compiler.
You disturbed this by supplying your own sysroot. It was now only searching the target root. Since this target root filesystem did not have development libs installed, there was no C runtime there to find.
You are doing several things wrong:
looks like you are not using environment variables, but calling cross-compiler directly. So, instead of compiling with arm-linux-gnueabihf-g++ ..., you should do $CXX .... The CXX is the environment variable set by the yocto script to set environment for cross compilation. Using CXX, you do not need to manually pass --sysroot
You should not link directly to pthread library with -lpthread. You should use -pthread

$OPENMP_FFLAGS not working in autoconf

I am trying to compile a fortran code with gnu-autotools. The openmp specific lines in configure.ac is:
AC_PROG_FC([gfortran])
AC_OPENMP
FCFLAGS="$OPENMP_FCFLAGS -fcheck=all"
If I compile with this, I am not getting omp related compiler options, as described in the AC_OPENMP macro in autoconf manual.
If I explicitly place -fopenmp in place of $OPENMP_FFLAGS, only then its working.
Any help please?
Autoconf typically likes testing everything for C language by default and that's why you're only getting $OPENMP_CFLAGS as a result for the AC_OPENMP command. However, Autoconf also provides mechanisms to change the programming language (and therefore the compiler also) by using the AC_LANG command (please, take a look at Autoconf / Language Choice webpage for further details and also some alternatives).
The following code has been tested using the command autoconf 2.69 and using the command: autoreconf -fiv (also using an empty Makefile.am file).
AC_INIT([omp-fortran-sample], [1.0])
AC_PROG_CC
AC_PROG_FC([gfortran])
dnl Checks for OpenMP flag for C language, stores it in $OPENMP_CFLAGS
AC_LANG(C)
AC_OPENMP
dnl Checks for OpenMP flag for Fortran language, stores it in $OPENMP_FCFLAGS
AC_LANG(Fortran)
AC_OPENMP
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
The resulting execution of the configure shows two tests for OpenMP as seen here:
checking for gcc option to support OpenMP... -fopenmp
checking for gfortran option to support OpenMP... -fopenmp
And Makefile now includes both OPENMP_CFLAGS and OPENMP_FCFLAGS definitions, among the rest, as shown below:
...
MKDIR_P = /bin/mkdir -p
OBJEXT = o
OPENMP_CFLAGS = -fopenmp
OPENMP_FCFLAGS = -fopenmp
PACKAGE = omp-fortran-sample
...

Using compiler prefix command(s) with CMake (distcc, ccache)

There are utilities which use an existing compiler by adding a command as a prefix (so instead of calling cc -c file.c you could call distcc cc -c file.c).
When using CMake the compiler command can be changed, however I ran into problems trying to use distcc, though this would likely apply to any command prefix to the compiler (ccache too).
CMake expects the compiler to be an absolute path,so setting CMAKE_C_COMPILER to /usr/bin/distcc /usr/bin/cc, gives an error:
/usr/bin/distcc /usr/bin/cc
is not a full path to an existing compiler tool.
Setting the compiler to /usr/bin/distcc andCMAKE_C_COMPILER_ARG1 or CMAKE_C_FLAGS to begin with /usr/bin/cc works in some cases, but fails with CHECK_C_SOURCE_COMPILES(checked if there was some way to support this, even prefixing CMAKE_REQUIRED_FLAGS didn't work).
The only way I found to do this is to wrap the commands in a shell script.
#!/bin/sh
exec /usr/bin/distcc /usr/bin/cc "$#"
While this works, It would be nice to be able to use compiler helpers with CMake, without having to go though shell scripts (giving some small overhead when the build system could just use a command prefix).
So my question is:
Can CMake use compiler prefix commands (such as distcc) directly?, without shell script wrappers?
Since CMake 3.4.0 there has been a CMAKE_<LANG>_COMPILER_LAUNCHER variable and corresponding target property <LANG>_COMPILER_LAUNCHER. So if your project is C-only you would do something like:
cmake -DCMAKE_C_COMPILER_LAUNCHER=ccache /path/to/source
CCACHE_PREFIX=distcc make -j`distcc -j`
If you have a C++ project, use -DCMAKE_CXX_COMPILER_LAUNCHER=ccache.
Or, make your CMakeLists.txt smart and use ccache automatically if it can be found:
#-----------------------------------------------------------------------------
# Enable ccache if not already enabled by symlink masquerading and if no other
# CMake compiler launchers are already defined
#-----------------------------------------------------------------------------
find_program(CCACHE_EXECUTABLE ccache)
mark_as_advanced(CCACHE_EXECUTABLE)
if(CCACHE_EXECUTABLE)
foreach(LANG C CXX)
if(NOT DEFINED CMAKE_${LANG}_COMPILER_LAUNCHER AND NOT CMAKE_${LANG}_COMPILER MATCHES ".*/ccache")
message(STATUS "Enabling ccache for ${LANG}")
set(CMAKE_${LANG}_COMPILER_LAUNCHER ${CCACHE_EXECUTABLE} CACHE STRING "")
endif()
endforeach()
endif()
Just as a hint: never use <LANG>_COMPILER_LAUNCHER to cross compile. If <LANG>_COMPILER_LAUNCHER is used together with distcc the absolute compiler path is sent to distcc and the host is not using the cross comping toolchain!
Instead you should use the old school method, just overwrite the compiler path:
export PATH=/usr/lib/distcc:$PATH
It took me hours to find out...

Disabling cxx support for libtool after calling AC_PROG_CXX

For my project (library), I use configure with libtool and automake to build under linux hosts. The library consists of a C API, as well as an optional C++ extension. So, since
AC_PROG_CXX must be called globally, I use automake conditionals:
*configure.ac*:
AC_PROG_CC
AC_PROG_CXX
AM_PROG_AR
LT_INIT
... some tests to figure out 'build_cxx' ...
AC_CONDITIONAL([CXX], [ test x$build_cxx = xyes ])
And inside Makefile.am
sources = files.c
if CXX then
cxx_sources = files.cpp
else
cxx_sources =
endif
sources = $sources $cxx_sources
The whole thing, however, does not work when configure is not able to locate g++ (which practically kills the extra logic for the c++ extension). After some research, I've come down to the conclusion that AC_PROG_CXX somehow tells libtool to assume that c++ support. I was also surprised to realise that if AC_PROG_CXX fails, it sets CXX to 'g++'!!!
Anyway, calling AC_PROG_CXX conditionally produces errors like 'am_fastdepCXX is never defined', which seems logical to me. The worst thing is that the error is not shown while configure is running, but it appears later in the linking phase, in to form of 'unknown libtool option -o' (ouch).
The full source code can be found here -> http://bitbucket.org/sdlu/sdlu/src
Can somebody help me?
Thanks in advance...
It's an Automake limitation, it doesn't care about the condition when choosing the linker.
One work-around is to conditionally rewrite the _LINK command, as suggested in this mailing list post:
if USE_CXX
cxx_sources = ...
else
cxx_sources =
libSDLU_la_LINK = $(LINK) $(libSDLU_la_CFLAGS) $(libSDLU_la_LDFLAGS)
endif
Another way (suggested in the same discussion) is to put the C++ sources in a utility library that is built and added conditionally, then added to the main library:
if CXX
noinst_LTLIBRARIES = libSDLUxx.la
libSDLUxx_la_SOURCES = src/cxx/SDLU_CButton.cxx \
src/cxx/SDLU_CIniHandler.cxx \
src/cxx/SDLU_CRenderer.cxx \
src/cxx/SDLU_CSprite.cxx \
src/cxx/SDLU_CTexture.cxx \
src/cxx/SDLU_CWindow.cxx
libSDLU_la_LIBADD = libSDLUxx.la
endif
Some unrelated notes
Do not put generated files (Makefile.in, configure, etc) into source control.
Add a bootstrap script that invokes the autotools to generate things.
Prefer pkg-config (i.e. PKG_CHECK_MODULES(SDL2, sdl2)) over hand-crafted autoconf macros (i.e. AM_PATH_SDL2);
Do not install autoheaders (i.e. SDLU_config.h.in). It makes your library incompatible with every autoconf-based software, as you are re-defining PACKAGE, VERSION, and all library-detection macros. See my answer in this question for examples on how to do it.
I would have the C++ API built and installed as an independent, optional library; drop the sdlu-config script altogether, then write sdluxx.pc that requires sdlu. Do not bother checking if the C++ compiler works, if the user passed --enable-cxx he knows what he's doing; I prefer to have the build fail than silently have an incomplete library.
I don't think it is a good idea to interfere in the handling of the CXX variable.
Use your own variable BUILD_CXX
AC_CONDITIONAL([BUILD_CXX], [ test x$build_cxx = xyes ])here
and
if BUILD_CXX
# ....
endif

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.