From: David Garamond Date: 2004-03-21T20:48:03+09:00 Subject: Re: Can $LOAD_PATH be relative? --------------010907030102040804020800 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 1-2 weeks ago I asked the same question about a Linux binary Ruby installation that can be installed anywhere in users' home directory (without the user building Ruby himself). To accomplish this, the following is needed: 1) build Ruby with --enable-load-relative (you must patch Ruby with +- 100-line patch from Nobu; sorry I couldn't search ruby-talk.org at the moment but it's around the first week of March 2004) which will make $LOAD_PATH relative; 2) either: a) make a small wrapper for ruby executable, which makes Ruby find its shared libraries in "../lib" instead of only in /lib, /usr/lib, and other paths specified in /etc/ld.so.conf; (I'm attaching the small wrapper I wrote, which again was kindly revised by Nobu); b) build a static version of Ruby (--disable-shared in configure option), which will then depend only on basic shared libraries (like glibc). After that, you can just bundle the resulting Ruby installation. Hope that helps, -- dave --------------010907030102040804020800 Content-Type: text/plain; name="wrapper.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="wrapper.c" #include #include /* * wrapper.c * * This is a simple executable wrapper that inserts "../lib" into * LD_LIBRARY_PATH so that the executable can find shared libraries relative * to its position. Works only on Linux (or other OS which supports * /proc/self/exe). * * To use this wrapper, first compile this file using: gcc -o wrapper * wrapper.c. Then, suppose you want to wrap the Ruby executable in * /home/dave/usr/bin/ruby. Rename the original executable to * /home/dave/usr/bin/ruby.real (or with whatever suffix; see * WRAPEE_SUFIX below). Then copy the wrapper binary to * /home/dave/usr/bin/ruby. This means that when you invoke the executable, * Ruby will find its libraries in /home/dave/usr/lib/ first instead of the * usual /usr/lib/. * */ #define MAX_PATH_LENGTH 1024 #define WRAPEE_SUFFIX ".real" int main(int argc, char *argv[]) { static char binpath[MAX_PATH_LENGTH+sizeof(WRAPEE_SUFFIX)+1]; static char libpath[MAX_PATH_LENGTH+sizeof("../lib")+1]; char *p; char *env; if (readlink("/proc/self/exe", binpath, MAX_PATH_LENGTH) == -1) { fprintf(stderr, "readlink() failed: %s (maybe /proc is not " "mounted or restricted?)\n", strerror(errno)); exit(1); } strcpy(libpath, binpath); p = libpath + strlen(libpath); while (p >= libpath) { if (*p == '/') { strcpy(p, "/../lib"); break; } p--; } p = (char *)getenv("LD_LIBRARY_PATH"); if ((env = (char *)malloc(MAX_PATH_LENGTH+1+1+ (p==NULL ? 0 : strlen(p)))) == NULL) { fprintf(stderr, "malloc() failed: %s\n", strerror(errno)); exit(1); } strcat(env, "LD_LIBRARY_PATH="); if (p != NULL) { strcpy(env, p); strcat(env, ":"); } strcat(env, libpath); if (putenv(env) == -1) { fprintf(stderr, "putenv() failed: %s\n", strerror(errno)); exit(1); } strcat(binpath, ".real"); execv(binpath, argv); fprintf(stderr, "Can't execute wrapee: %s\n", strerror(errno)); exit(1); } --------------010907030102040804020800--