2

Similar to this post, I need to pass $ORIGIN/../lib to my compilation procedure. I'm doing this via

./configure "LDFLAGS=-Wl,-rpath,\$\$ORIGIN/../lib"
make

However, when I inspect the executable via objdump -x src/foo | grep PATH, I get

/home/Users/me/foo_repo/lib:/../lib

when what I want is

/home/Users/me/foo_repo/lib:$ORIGIN/../lib

So it looks like $ORIGIN is being evaluated instead of just being put into RUNPATH

How can I prevent this from happening? I've tried adding escapes to both $ but get the same result.

Throckmorton
  • 564
  • 4
  • 17

3 Answers3

3

I tried it many times and it seems that at some point it may still be resolved to empty string, since Makefiles can be run recursively. The only way I found to be reliable was to additionally define export ORIGIN='$ORIGIN' in the shell where I run configure and make, so that even if shell expands $ORIGIN it will still result in value $ORIGIN.

Note also that you need also -Wl,-z,origin to make value $ORIGIN interpreted in runtime.

raspy
  • 3,995
  • 1
  • 14
  • 18
1

It doesn't work because you need yet a third layer of quoting: because you are passing this value to the configure script via the command line you need to quote the value for the shell.

You run this:

./configure "LDFLAGS=-Wl,-rpath,\$\$ORIGIN/../lib"

The shell removes the first level of quoting before invoking configure, so the value of LDFLAGS that is put into your makefile is this:

LDFLAGS=-Wl,-rpath,$$ORIGIN/../lib

Then when make runs the linker, it will convert the escaped $$ into a single $, and make will invoke a shell and pass your link line with the option:

-Wl,-rpath,$ORIGIN/../lib

The shell will expand $ORIGIN because it looks like a shell variable, expand it to the empty string, and you get the result -Wl,-rpath,/../lib.

To get the quoting right it's often useful to work backwards. When make invokes your link line it needs to escape the $ORIGIN so the shell doesn't expand it, so you want the argument to be something like:

'-Wl,-rpath,$ORIGIN/../lib'

In order to get that, you need your LDFLAGS to be set to something like:

LDFLAGS='-Wl,-rpath,$$ORIGIN/../lib'

In order to get that, you need to escape it all from the shell when you invoke configure, including the single-quotes, something like:

./configure "LDFLAGS='-Wl,-rpath,\$\$ORIGIN/../lib'"

(note, I didn't try this)

MadScientist
  • 92,819
  • 9
  • 109
  • 136
  • This did not work for me. The `./configure` script wouldn't even run w/ the outer quotes. – Throckmorton Jun 01 '20 at 20:04
  • Don't know what "wouldn't even run" means. You have to provide an error message at least. If it literally wouldn't start then you must have a syntax error in your command line. – MadScientist Jun 01 '20 at 23:19
  • `gcc: error: '-Wl,-rpath,$$ORIGIN/../lib': No such file or directory` somewhere buried in the `config.log` output. – Throckmorton Jun 02 '20 at 00:52
  • well, the problem is that the value of the LDFLAGS variable may be used by configure wen it's testing the linker, as well as make, and they have different formats. I don't think you really need to use this option with `./configure`. Does it work if you run configure without this `LDFLAGS` setting but then pass the `LDFLAGS` setting to `make` when you run that? – MadScientist Jun 02 '20 at 05:43
  • It does not, for the same reason @raspy provided in the accepted answer. – Throckmorton Jun 06 '20 at 23:29
0

I also encountered the same problem, after several attempts, the following settings are feasible.

./configure  LDFLAGS="-Wl,-rpath=\\\$\$ORIGIN/../lib ${LDFLAGS}"
lilucpp
  • 196
  • 1
  • 10