Posted inExperience / Information Technology / Thank You Sir May I Have Another

RPATH Notes

Ubuntu Logo

Few things are more frustrating when first developing your own libraries than RPATH. There have been numerous hacks over the years. Gnu even gave us libtool because POSIX dlopen() just kinda sucked.

Hey, for the end user, dlopen() mostly works. It finds dynamically linked libraries in the system standard search paths, all is well with the world. For the developer working on dynamically linked libraries or worse yet, plugins that use dynamically linked libraries from the same build, it is crawling naked across broken glass.

There is a not bad explanation in this question. Yes, I was asking the question. You might want to read it now.

Most of you nave seen my posts on CopperSpice and know I currently have LsCs as a fork. The fork will be disconnected from CopperSpice as soon as I finish my cleanup experiments. Product will also be branded LsX at that time as well. Current working branch is 0.2.1 but that is subject to change.

.conf Never Worked

One of the more insidious problems was the fact qt.conf never worked. Believe me, I fought this unwinnable battle both times I worked on the IPOS project for different Publicis Groupe agencies. We didn’t have things like flatpak then. I had to build a .deb that would install (and cleanly un-install) a captive user account for one of those Explore This Computer applications you see running in big box stores.

Take a look at the current list of entries for qt.conf

Admittedly the Plugins entry has limited success, but Libraries is a complete farce.

What Happens When You Run An Executable?

dlopen() bites you in the ass.

First, dlopen() operates differently on every OS family. Linux distros mostly work the same, but Mac and QNX are different. I would expect WindRiver and other “Linux-like” RTOS implementations to be different as well. Here is where you really need to take a moment and read the previously linked discussion.

Your ELF

Assuming you haven’t statically linked Gnu libtool and had an init() procedure pre-load every one of your custom library files pointed to by the Libraries entry, dlopen() will follow the above mentioned search paths. the first search path with be RPATH or RUNPATH baked into your ELF.

For those who just want a command to scrape

readelf -d simple-text-editor | grep -E 'RPATH|RUNPATH'

Substitute the path to your executable (or .so) for simple-text-editor.

For CMake users this gets filled in via one line

set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

Official documentation for INSTALL_RPATH is here. Gitlab has an excellent wiki on all the ways you can shoot yourself in the foot with RPATH.

LD_LIBRARY_PATH

In order to really use this you have to export it inside of a shell script then run your executable as the next step in the script. LD_LIBRARY_PATH is only read at initial program load. The C startup code that got linked with your executable (or .so) checks the contents of this variable at startup only. No matter what language you thought you were working with, the OS specific startup code linked into your program as in C and looked for this. You cannot change the content of this from within your program and have anything different happen.

Why?

Someone thought this was more secure. On Windows you can dynamically change the PATH environment variable because each and every invocation of library loading evaluates the current PATH value, but on Linux you are hosed.

The OS is using dlopen(), period. But you can force use of libtool. With libtool you have the following:

The lt_dlopen() family of calls will use the search path you create here.

First Open is dlopen No Matter What

The initial loading of simple-text-editor used dlopen() to get standard C and C++ startup code from the OS. No way around it. Adding insult to injury, if you call a function you wish to test in your local library that happens to be in the system libraries at this point, you might well be screwed. Once loaded, rarely re-loaded.

When it comes to 800-pound-gorrilla frameworks like Qt and its derivatives, this means the “core” library gets loaded before you have a chance to change things. That means, if it exists on the system search paths, you will get a different version than the one you built in your local library. Those who are lucky won’t have any Qt libraries installed anywhere else on their system so they will just get a dump from not being able to find the library. Everyone else will slam head against keyboard relentlessly wondering why the library they just built isn’t being used.

This may well screw you for all library modules. Keep in mind there can/should/will be an RPATH backed into the core library load. Anything it chooses to load will be based on those values.

That Brings Us to Plugins

Yes, it should find your just build plugins, but what RPATH got baked into your ELF? If it is empty, hello /etc/ld.so.cache. With a miss there it looks at /lib, then /usr/lib.

Please note that many Linux distros tell ldconfig to also look at /usr/local/lib when building /etc/ld.so.cache. Most also configure the compilers to look in /usr/local/include. I bring this up because a great many developers rely on /usr/local entries being first in the search paths, or at least ahead of /lib and /usr/lib. They build and install here to avoid RPATH hassles.

If you don’t force the RPATH and RUNPATH entries blank in your ELF though (see previous wiki link) you just shot yourself in the left foot instead of the right.

Roland Hughes started his IT career in the early 1980s. He quickly became a consultant and president of Logikal Solutions, a software consulting firm specializing in OpenVMS application and C++/Qt touchscreen/embedded Linux development. Early in his career he became involved in what is now called cross platform development. Given the dearth of useful books on the subject he ventured into the world of professional author in 1995 writing the first of the "Zinc It!" book series for John Gordon Burke Publisher, Inc.

A decade later he released a massive (nearly 800 pages) tome "The Minimum You Need to Know to Be an OpenVMS Application Developer" which tried to encapsulate the essential skills gained over what was nearly a 20 year career at that point. From there "The Minimum You Need to Know" book series was born.

Three years later he wrote his first novel "Infinite Exposure" which got much notice from people involved in the banking and financial security worlds. Some of the attacks predicted in that book have since come to pass. While it was not originally intended to be a trilogy, it became the first book of "The Earth That Was" trilogy:
Infinite Exposure
Lesedi - The Greatest Lie Ever Told
John Smith - Last Known Survivor of the Microsoft Wars

When he is not consulting Roland Hughes posts about technology and sometimes politics on his blog. He also has regularly scheduled Sunday posts appearing on the Interesting Authors blog.