9

According to this SO question, Linux executable can't find shared library in same folder passing -Wl,-rpath,${ORIGIN} is the way to get a Linux executable to search for .sos in the same directory as the executable.

We're using cmake, so I'm adding a line of the form

target_link_options(Executable PRIVATE -Wl,-rpath=${ORIGIN})

to CMakeLists.txt. The problem with that is that cmake tries to interpret the nine character sequence ${ORIGIN} as a variable, and replaces it with nothing.

So far, I've tried:

$${ORIGIN}
\${ORIGIN}
$\{ORIGIN\}
$$\{ORIGIN\}
\$\{ORIGIN\}

none of which have worked. How can I get this done?

-- Edit --

As noted by @Tsyvarev's comment, it turns out this was an XY problem in my particular case, since cmake has facilities directly designed to manipulate rpath. Using this, I was able to get a solution.

In my case, adding the following three lines to CMakeLists.txt did the trick.

SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "$\{ORIGIN\}")

Note that part of our build process involves copying the .so to the output folder in preparation for building the final tarball artifact. So using -rpath=${ORIGIN} works for both testing in the build tree, and final installation of the executable in the Docker container.

dgnuff
  • 3,195
  • 2
  • 18
  • 32
  • 1
    CMake has special ways for specify RPATH. See [CMake RPATH handling](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling) wiki and [that SO question](https://stackoverflow.com/questions/53428219/cmake-rpath-origin-and-loader-path). – Tsyvarev Sep 12 '19 at 23:52
  • @Tsyvarev Thanks for the information, looks like I was trying to solve an XY problem. I've editied the question to be more specific about what I was asking, if you enter your comment as an answer I'll accept it. – dgnuff Sep 13 '19 at 00:10

1 Answers1

2

As you already noticed, you should use CMAKE_INSTALL_RPATH or INSTALL_RPATH. INSTALL_RPATH sets the rpath when installing a specific target. CMAKE_INSTALL_RPATH is the global variant, doing the same for all targets.

I also struggled, how to escape $ORIGIN. But, for me it works without escaping it at all:

set_target_properties(<target> PROPERTIES INSTALL_RPATH "$ORIGIN")
NelDav
  • 785
  • 2
  • 11
  • 30