Project

General

Profile

Actions

Bug #12276

closed

Quoting error involving '$' characters in DT_RPATH pathnames

Added by eam (Evan Miller) about 8 years ago. Updated over 7 years ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:74911]

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) about 8 years ago

  • Status changed from Open to Feedback

Doesn't configure --enable-load-relative work?

Updated by eam (Evan Miller) about 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) over 7 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]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0