0

I have a library (let's call it mydll.so) that is dependent to an external application, i.e. Matlab. To dynamically load mydll.so, I have written a code like this (Ubuntu, g++ 4.8.5, qt 5.12.6):

// update LD_LIBRARY_PATH with ALL required paths (Matlab, boost, etc.)
bool res = qputenv("LD_LIBRARY_PATH", required_path.toStdString().c_str());
assert(res);

// loading the dll
QLibrary my_dll;

my_dll.setFileName(dll_path);
if (!my_dll.load())
{
   std::cout << my_dll.errorString().toStdString() << std::endl;
}

The above code fails with this message:

Cannot load library /home/user/code/test/lnx_x64/debug/mydll.so: (libMatlabDataArray.so: cannot open shared object file: No such file or directory)

It is strange because the load() function is complaining about a library from Matlab, i.e. libMatlabDataArray.so that its path is already included in LD_LIBRARY_PATH. But, if I run ldd on the same environment, I have:

user@everest:~/code$ ldd /home/user/code/test/lnx_x64/debug/mydll.so
    linux-vdso.so.1 (0x00007ffcb4da2000)
    libMatlabDataArray.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabDataArray.so (0x00007f6af95f2000)
    libMatlabEngine.so => /usr/local/MATLAB/extern/bin/glnxa64/libMatlabEngine.so (0x00007f6af93e7000)

That means the libMatlabDataArray.so can be found by ldd command and the contents of LD_LIBRARY_PATH is correct. Then what can be the reason behind this issue in my case?

Update 1: If I set the LD_LIBRARY_PATH before the application is started, everything works fine. What is the difference between setting the the LD_LIBRAARY_PATH before launching the application and inside it?

TonySalimi
  • 8,257
  • 4
  • 33
  • 62
  • 1
    What `qputenv()` returns? Besides, are you sure your process used the newly set `LD_LIBRARY_PATH` value? What if you set it *before* starting the application? – vahancho Nov 27 '20 at 16:27
  • 1
    Run your binary with `strace -o log -f /path/to/my/binary` Then `log` will show you where the library loader looked for your library. – Ross Rogers Nov 27 '20 at 16:30
  • @vahancho it returns true. Moreover, after calling `qputenv()` I added a line like `std::system("gnome-terminal");`. From the opened terminal, I saw that the value of `LD_LIBRARY_PATH` is OK and `ldd` works fine on that terminal too. – TonySalimi Nov 27 '20 at 16:31
  • @vahancho If I set LD_LIBRARY_PATH before the application, it works fine!!! What can be the issue in this case? – TonySalimi Dec 01 '20 at 17:23
  • @Gupta, when you modify the environment variable from a process, the process still used the old value. You should change the environment before starting the process. – vahancho Dec 02 '20 at 09:00
  • @vahancho You are right. It was exactly my problem. If you want, you may put this point as an answer and I will accept it. Thanks again. – TonySalimi Dec 02 '20 at 10:06

1 Answers1

2

The problem is that you change the environment variable LD_LIBRARY_PATH from within the process. However the process still uses the "old" environment variables block with old values. As a result it cannot properly find the dependent libraries and eventually fails. Therefore your approach will not work. I would propose the following solutions:

  • Set the LD_LIBRARY_PATH variable before starting the process, so that the process can take the updated block into account,
  • Try to use QCoreApplication::setLibraryPaths() function to set the library search paths.
vahancho
  • 20,808
  • 3
  • 47
  • 55