LD_LIBRARY_PATH failing while trying to run Qt app
sudo
doesn't pass LD_LIBRARY_PATH
:
$ LD_LIBRARY_PATH=lib/
$ export LD_LIBRARY_PATH
$ env | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=lib/
$ sudo env | grep LD_LIBRARY_PATH
You can set it for the command run as root:
$ sudo env LD_LIBRARY_PATH=/lib env | grep LD_LIBRARY_PATH
SUDO_COMMAND=/usr/bin/env LD_LIBRARY_PATH=/lib env
LD_LIBRARY_PATH=/lib
You'll want something like
sudo env LD_LIBRARY_PATH=/lib "$INSPATH/myApp"
As always, be careful with sudo
!
QLibrary::load fails, but LD_LIBRARY_PATH just updated correctly before that, why?
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.
Why changing LD_LIBRARY_PATH has no effect in Ubuntu?
If you look at the output of your ls -al
These are soft links that you have. Your softlink libQt5MultimediaWidgets.so.5
points to libQt5MultimediaWidgets.so.5.9.2
in the same directory and the file is not there at all. So you need to either set the correct softlink path or have the file in same directory
Why Qt Creator gives No absolute path for library Error for a known library?
I am also trying to make a Basler camera work, and I had the exact same problem as you; except that the same error occured when I build from the terminal. I got the error when I attempt to execute one of the examples after building it.
For me the problem was, that I had only set paths for "GENICAM_ROOT" in .bashrc and not for "GENICAM_ROOT_V2_3" (since only "GENICAM_ROOT" was used by the accompanying makefile). Adding "GENICAM_ROOT_V2_3" solved the problem.
My .bashrc:
export PYLON_ROOT=/opt/pylon3
export GENICAM_ROOT=/opt/pylon3/genicam
export GENICAM_ROOT_V2_3=/opt/pylon3/genicam
export GENICAM_CACHE=~/tmp
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${PYLON_ROOT}/lib64
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GENICAM_ROOT}/bin/Linux64_x64
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GENICAM_ROOT}/bin/Linux64_x64/GenApi/Generic
Hope this can help someone.
Cannot load libraries when Qt application is launched from systemd
Most probably the linker directories are not known in the context of systemctl
. Try setting the environment variable LD_LIBRARY_PATH
to the relevant dirs at the start of your service script; see man ld.so
for details. Or look at other service scripts on your system to get an idea how the environment is correctly set there.
Qt application cannot find shared library at runtime
There are many possible solutions.
You can install your shared library to standard locations like /usr/lib
, /lib
or /usr/lib64
etc.
Or before running your application from console,
you can set the LD_LIBRARY_PATH
environment variable to include
the directory which contains your shared library.
See this link for details.
Why do I need to set LD_LIBRARY_PATH after installing my binary?
Why do I need to set LD_LIBRARY_PATH after installing my binary?
The simple answer is, it is a failure of the system architects and the toolchain. On Linux they are the folks who maintain Binutils and glibc. Collectively the maintainers think it is OK to compile and link against one version of a library, and then runtime link against the wrong version of the library or lose the library. They have determined it is the number one use case (q.v.). Things don't work out of the box, and you have to do something special to get into a good state.
Consider, I have some Build Scripts that build and install about 70 common Linux utilities and libraries, like cURL, Git, SSH and Wget. The scripts build the program and all of its dependencies. Sometimes I attempt to use them for security testing and evaluation, like Asan and UBsan. The idea is to run the instrumented program and libraries in /usr/local
and detect undefined behavior, memory errors, etc. Then, report the error to the project.
Trying to run instrumented builds on a Linux system is impossible. For example, once Bzip, iConv, Unicode, IDN, PRCE, and several other key libraries are built with instrumentation the system no longer functions. Programs in /usr/bin
, like /usr/bin/bash
, will load instrumented libraries in /usr/local/lib
. The programs and libraries have so many faults the programs are constantly killed. You can no longer run a script because the programs in /usr/bin
are using wrong libraries (and programs like bash
have so many faults).
And of course there are problems like yours, where programs and libraries can't find its own libraries. The web is full of the carnage due to the maintainers' decisions.
To fix the issue for the program you are building, add the following to your LDFLAGS
:
-Wl,-R,/usr/local/lib -Wl,--enable-new-dtags
-R,/usr/local/lib
tells the runtime linker to look in /usr/local/lib
for its libraries. --enable-new-dtags
tells the linker to use RUNPATH
as opposed to a RPATH
.
RUNPATH
's are overrideable with LD_LIBRARY_PATH
, while RPATH
's are not. Omitting -Wl,--enable-new-dtags
is usually a bad idea. Also see Use RPATH but not RUNPATH?.
You can also use a relative runtime path:
-Wl,-R,'$$ORIGIN/../lib' -Wl,--enable-new-dtags
-R,'$$ORIGIN/../lib'
tells the runtime linker to look in ../lib/
for its libraries. Presumably your binary is located in .../bin/
, so ../lib/
is up-and-over to the the lib/
directory.
ORIGIN-based linker paths are good when you have a filesystem layout like:
My_App
|
+-- bin
| |
| +- my_app.exe
|
+-- lib
| |
| +- my_lib.so
|
+-- share
You can move My_App
folder around the filesystem, and my_app.exe
will always be able to find its library my_lib.so
. And if the My_App
is the root directory /
, then it is a standard Linux file system used by distros (i.e., --prefix=/
). And if the My_App
is /usr/local
, then it is a standard Linux file system used by the user (i.e., --prefix=/usr/local
).
If you configure
, make
and make test
, then you can use LD_LIBRARY_PATH
to set the temporary path to the library for testing (like .../My_App/lib
). In fact, a well written make test
should do that for you during testing.
You should not have to add -Wl,-R,/usr/local/lib -Wl,--enable-new-dtags
since the program was compiled and linked against the library in /usr/local/lib
(presumably using -L<path>
and -l<lib>
). The reason you have to do it is because the maintainers keep making the same mistake over and over again. It is a complete engineering failure.
The Linux architects were warned about these path problems about 25 years ago when they were deciding what to do out of the box. There were two camps - one who wanted things to work out of the box, and one who wanted users to do something special to get things to work. The later won the debate. They chose the "let's link against the wrong library" and "let's lose the library" patterns. I wish I could find the Usenet posting where it was discussed so you could read it for yourself.
Related Topics
How to View Thread Id of a Process Which Has Opened a Socket Connection
Movdqu Instruction + Page Boundary
Python Error "Attributeerror: 'Module' Object Has No Attribute 'Sha1'"
Shuffle Output of Find with Fixed Seed
How to Install Rpy2 via Conda Using Default R Installation
"Bad Interpreter" Error Message When Trying to Run Awk Executable
Escaping the Exclamation Point in Grep
How to Sort Comma Separated Values in Bash
How Kernel Notify a User Space Program an Interrupt Occurrs
Apache Proxypass Not Loading Resources
Libcurl Ssl Error After Fork()
How to Change the Permissions in Openshift Container Platform
Using $Origin to Specify the Interpreter in Elf Binaries Isn't Working