Gurus Say That Ld_Library_Path Is Bad - What's the Alternative

rpath=$ORIGIN not having desired effect?

I'm assuming you are using gcc and binutils.

If you do

readelf -d CeeloPartyServer | grep ORIGIN

You should get back the RPATH line you found above, but you should also see some entries about flags. The following is from a library that I built.

0x000000000000000f (RPATH)              Library rpath: [$ORIGIN/../lib]
0x000000000000001e (FLAGS) ORIGIN
0x000000006ffffffb (FLAGS_1) Flags: ORIGIN

If you aren't seeing some sort of FLAGS entries, you probably haven't told the linker to mark the object as requiring origin processing. With binutils ld, you do this by passing the -z origin flag.

I'm guessing you are using gcc to drive the link though, so in that case you will need to pass flag through the compiler by adding -Wl,-z,origin to your gcc link line.

Can't link shared library with -mx32 and gcc 4.7 or gcc 4.8

-m32 is normal 32-bit mode, and yes most x86-64 GNU/Linux systems have multiarch support with 32-bit libraries that you can install if not already installed.

The -mx32 option is not what you want at all. It compiles code for the x32 ABI, which uses 32-bit addresses with 64-bit registers and instructions. The resulting code is not compatible with 32-bit processors (as it uses 64-bit instructions), but is also not compatible with 64-bit code (which will use 64-bit addresses). So everything in user-space has to be compiled with it in mind, including libc, and even the kernel needs to support x32 user-space and syscalls: https://unix.stackexchange.com/questions/121424/linux-and-x32-abi-how-to-use (i.e. just like supporting 32-bit binaries, x32 is effectively a separate architecture.)

Complicating matters further, the testing you've been doing on Windows hasn't been doing what you think at all. Passing /DWIN32 to the Visual C++ compiler only defines a macro called WIN32 (like -DWIN32 would for GCC); it doesn't make the compiler generate 32-bit binaries. 64-bit Windows executables cannot load 32-bit libraries; the libraries you've been testing with have actually been 64-bit.

If you want to unit-test 32-bit code, you'll need to test it on a fully 32-bit target architecture like -m32. x32 is not such a system. (32-bit code under a 64-bit kernel is fine, though, unless you're worried about only having 2G or 3GiB of address-space usable by user-space in your embedded system, instead of 4GiB under a 64-bit kernel.)

Trouble using boost, cannot open shared object file

liibboost_system.so.1.60.0 cannot be found in the list of directories searched by the dynamic linker. The non-default shared-object location is not stored in the binary by default. The environment variable LD_LIBRARY_PATH can be used to add directories that will be searched before the standard locations:

LD_LIBRARY_PATH=/home/vagrant/boost_1_60_0/stage/lib/ ./a.out

This will only work for the current bash environment, and there are also ways to store the path in the executable so that the environment variable is not needed.

Executable cannot find dynamically linked mkl library, but ldd does

The code is dynamically linked and has the setgid attribute. setgid with a dynamically linked executable can cause security problems and is greatly limited by GNU glibc. For example, LD_LIBRARY_PATH will be ignored. That is why the code keeps on complaining some shared library not found.

cx_Oracle does not recognize location of Oracle software installation for installation on Linux

Updated

As Petriborg suggested, setting LD_RUN_PATH at build time will include the path to the Oracle shared library files in the cx_Oracle shared library that is built during installation. This obviates the need for LD_LIBRARY_PATH as I suggested in my first answer.


For the RPMs that you are using, ORACLE_HOME should be set to /usr/lib/oracle/12.1/client. If you are using pip:

$ export ORACLE_HOME=/usr/lib/oracle/12.1/client
$ export LD_RUN_PATH=/usr/lib/oracle/12.1/client/lib:$LD_RUN_PATH
$ pip install cx_Oracle
$ python -c 'import cx_Oracle; print(cx_Oracle.version)'
5.1.3

Read this documentation for some info on installing and executing applications that use the client libraries.

Telling GCC to *not* link libgomp so it links libiomp5 instead

I think I have an answer at this point; I've had several exchanges with Intel folks, and I want to share the result. This is a mixture of some of their suggestions and what I came up with on my own:

  1. The short answer is, you can't. Gcc wants to force the use of libgomp at the linker stage. If libiomp is also linked, then both libraries will be linked. Which one will be called? I don't know.

  2. The longer answer is that on some distributions, it may be possible to change gcc's default behavior (adding libgomp whenever -fopenmp is set) by creating a custom libgomp.spec or altering the libgomp.spec installed with gcc. On my distribution (homebrew), this was not feasible; the "libgomp.spec" file is empty, and spec's for libgomp are built-in to gcc. All of those would have to be overridden. And this would have to be redone whenever gcc is updated.

  3. It may be possible on some operating systems to replace every copy and link to libgomp, to a symlink to libiomp5. The binary will then have multiple links leading to the same library, under two different names. What will happen then? I don't know.

  4. What I ended-up doing, is moving from gcc to the clang-omp implementation of llvm. It uses libiomp5 unless told otherwise. My concern about this was that part of my project uses fortran, and there's no llvm fortran compiler. It turns out, though, that even when -fopenmp is given to gfortran, so long as llvm is ultimately doing the linking it will wipe-out any references to libgomp and replace them with libiomp5. clang-omp also may have an option to select the omp library with -fopenmp=[libiomp5|libgomp], but I was not able to get this working consistently. Anyway, the clang-omp implementation of llvm 3.5 covers almost all of the openmp spec, and so far it doesn't appear that anything was lost in the switch. In fact performance improved.

  5. I did, for the record, experiment with using gfortran as an llvm frontend using dragonegg. This book was not worth the candle. Dragonegg isn't compatible with gcc 4.9 so it forces gcc 4.8. It was difficult to setup; appears that it would be difficult to maintain as versions change; the llvm folks are not sure how much support dragonegg will have moving forward; and in all events performance was inferior to just using llvm.

  6. The question that drove me here, was how to get a package with C and fortran components, that uses OpenMP, compiled against MKL, which the MKL libraries for my OS are hardlinked against iomp5 and won't accept gomp. The answer to that is that the only viable option was to move from gcc to clang-omp.

  7. This does leave the question, "is iomp5 'drop-in compatible' with gcc 4.9", as claimed on the OpenMP website. The answer is simply, "no," iomp5 and gcc 4.9 will not work with each other --- at least without substantial modifications to one's toolchain, for which no guidance or documentation is available, and it is not clear whether anyone has done this successfully.

Is it possible to link a shared library (from another shared library), without making its symbols globally visible?

In case you are ok with changing names of symbols from libC.so.2 you can use Implib.so's renaming functionality. E.g. to change all libC.so.2 symbols to have MYPREFIX_ prefix:

$ cat mycallback.c
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C"
#endif
void *mycallback() {
void *h = dlmopen(LM_ID_NEWLM, "libxyz.so", RTLD_LAZY | RTLD_DEEPBIND);
if (h)
return h;
fprintf(stderr, "dlmopen failed: %s\n", dlerror());
exit(1);
}
$ implib-gen.py --dlopen-callback=mycallback --symbol_prefix=MYPREFIX_ libC.so.2
$ ... # Link your app with libC.so.2.tramp.S, libC.so.2.init.c and mycallback.c, keep libC.so.1 unchanged

Function names in libC.so.2's header will need to be updated as well (often that's a simple s/// in vim).

Implib.so works by generating a bunch of wrappers for each symbol in problematic library (in this case libC.so.2) and forwarding calls to their actual implementation internally (via dlsym).



Related Topics



Leave a reply



Submit