Bug #12276
closedQuoting error involving '$' characters in DT_RPATH pathnames
Description
Often it's desired to use DT_RPATH in Ruby and associated extension objects when bundling custom libraries for a Ruby application. Often absolute paths cannot be known at build-time, so the linker provides the $ORIGIN macro used to build paths relative to the object being linked (This is a platform-specific linker feature, though fairly commonly implemented. Linux/FreeBSD support it)
Somewhere in Ruby's build system something is inappropriately interpolating '$' characters in pathnames as either Makefile or shell variables. An example:
$ LDFLAGS=' -Wl,-rpath=\$$ORIGIN/../lib ' ./configure
$ make
$ readelf -d ruby|grep RPATH
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib:/usr/local/lib]
$ readelf -d .ext/x86_64-linux/strscan.so|grep RPATH
0x000000000000000f (RPATH) Library rpath: [\/../lib]
Note the differing RPATH values.
I'm able to nest escaping in the initial LDFLAGS
argument in order to pass the correct value to ruby
. However, extensions (including subsequently built rubygems) will read this path from the ruby
binary and will not have correct quoting when constructing the extension build, which will cause the wrong RPATH to be set in all extension shared objects.
There are likely all sorts of special characters which trigger quoting issues in Ruby's build system, as is common in any Bourne shell / Makefile system. I'm primarily concerned with the '$' character as it is necessary to interact with linker macros -- which in turn are necessary to produce a relocatable Ruby binary with custom library dependencies.
I've verified this against trunk.
Updated by nobu (Nobuyoshi Nakada) over 8 years ago
- Status changed from Open to Feedback
Doesn't configure --enable-load-relative
work?
Updated by eam (Evan Miller) over 8 years ago
Nobuyoshi Nakada wrote:
Doesn't
configure --enable-load-relative
work?
I believe --enable-load-relative works with the module loading process, which is slightly different from my problem. I want to ensure correct linkage of shared objects which might depend on my ruby module DSO. For example, I believe --enable-load-relative
will help me locate lib/ruby/2.0.0/x86_64-linux/openssl.so
but what I'm concerned about is the transitive linkage between openssl.so
and, say, libk5crypto.so.3
. In cases where this dependency is likewise bundled in a relocatable location.
I don't believe dlopen()
has an interface to influence the linker paths, short of reimplementing linker dependency resolution entirely. The knobs I'm aware of are the DT_RPATH/DT_RUNPATH section in ELF, LD_LIBRARY_PATH, and system-wide config files.
Updated by nobu (Nobuyoshi Nakada) almost 8 years ago
- Status changed from Feedback to Closed
Quote by single quotes.
$ LDFLAGS=" -Wl,-rpath='\$\$ORIGIN/../lib' " ./configure
$ make
$ readelf -d ruby|grep RPATH
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib:/usr/local/lib]
$ readelf -d .ext/x86_64-linux/stringio.so|grep RPATH
0x000000000000000f (RPATH) Library rpath: [$ORIGIN/../lib]