From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26591 invoked by alias); 21 Nov 2001 21:33:50 -0000 Mailing-List: contact sid-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: sid-owner@sources.redhat.com Received: (qmail 26524 invoked from network); 21 Nov 2001 21:33:48 -0000 From: Geoffrey Keating Date: Tue, 13 Nov 2001 13:24:00 -0000 Message-Id: <200111212133.fALLXlp11797@thief.cygnus.com> To: sid@sources.redhat.com Subject: patch for location-independence X-SW-Source: 2001-q4/txt/msg00022.txt.bz2 The attached patch causes SID to look at argv[0] to determine its location, so that the installed sid tree can be moved anywhere and there is no need to set SID_EXEC_PREFIX (to run the sid executable, at least). OK to commit? -- Geoff Keating ===File ~/patches/sid-relocate.patch======================== Index: sid/include/ChangeLog 2001-11-19 Geoffrey Keating * sidmiscutil.h (argv0): New variable. (make_relative_prefix): New function. (sid_file_search_path): Determine default SID_EXEC_PREFIX from argv[0]. * configure.in: Define SID_PREFIX as $prefix. * configure: Regenerate. * sidconfutil.in: Dummy SID_PREFIX declaration. Index: sid/main/dynamic/ChangeLog 2001-11-19 Geoffrey Keating * mainDynamic.cxx (sidutil::argv0): Define. Index: sid/include/configure.in =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/configure.in,v retrieving revision 1.10 diff -p -u -p -r1.10 configure.in --- configure.in 2001/03/26 19:18:38 1.10 +++ configure.in 2001/11/20 05:26:27 @@ -66,5 +66,7 @@ else fi AC_DEFINE_UNQUOTED(SID_EXEC_PREFIX,"$sid_exec_prefix",[Define to build-time exec-prefix]) +AC_DEFINE_UNQUOTED(SID_PREFIX,"$prefix",[Define to build-time prefix]) + dnl Outputs AC_OUTPUT(Makefile) Index: sid/include/sidconfutil.in =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/sidconfutil.in,v retrieving revision 1.4 diff -p -u -p -r1.4 sidconfutil.in --- sidconfutil.in 2001/03/26 19:18:38 1.4 +++ sidconfutil.in 2001/11/20 05:26:27 @@ -36,3 +36,6 @@ /* Define to build-time exec-prefix */ #undef SID_EXEC_PREFIX +/* Define to build-time prefix */ +#undef SID_PREFIX + Index: sid/include/sidmiscutil.h =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/sidmiscutil.h,v retrieving revision 1.19 diff -p -u -p -r1.19 sidmiscutil.h --- sidmiscutil.h 2001/05/25 15:12:54 1.19 +++ sidmiscutil.h 2001/11/20 05:26:27 @@ -20,10 +20,14 @@ #ifdef __CYGWIN__ #include #endif +#include namespace sidutil { + // argv[0] passed to the main program. + extern char *argv0; + // Instances of this class template function as bidirectional lookup // tables (bijections) for mapping objects to each other by value. template @@ -310,6 +314,111 @@ namespace sidutil } + /* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string + that gets to PREFIX starting with the directory portion of + PROGNAME and a relative pathname of the difference between + BIN_PREFIX and PREFIX. + + For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX + is /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, + then this function will return /red/green/blue/../omega. + + If no relative prefix can be found, return NULL. */ + + inline std::string * + make_relative_prefix (const std::string &progname, + const std::string &bin_prefix, + const std::string &prefix) + { + std::vector prog_dirs = tokenize (progname, "/"); + + /* If there is no full pathname, try to find the program by + checking in each of the directories specified in the PATH + environment variable. */ + if (prog_dirs.size() == 1) + { + char *path = getenv ("PATH"); + + if (path) + { + std::vector paths = tokenize (path, ":"); + std::vector::iterator i; + + for (i = paths.begin(); + i != paths.end(); + i++) + { + std::string s = *i; + if (s == "") + s = '.'; + if (s[s.length()-1] != '/') + s += '/'; + s += progname; + if (! access (s.c_str (), X_OK)) + break; +#ifdef HAVE_HOST_EXECUTABLE_SUFFIX + s += HOST_EXECUTABLE_SUFFIX; + if (! access (s.c_str (), X_OK)) + break; +#endif + } + + if (i == paths.end()) + return NULL; + + prog_dirs = tokenize (*i, "/"); + } + } else { + /* Remove the program name from comparison of directory names. */ + prog_dirs.pop_back (); + } + + std::vector bin_dirs = tokenize (bin_prefix, "/"); + + /* Determine if the program is installed in the standard location, and if + so, we don't need to specify relative directories. */ + if (prog_dirs == bin_dirs) + return new std::string (prefix); + + std::vector prefix_dirs = tokenize (prefix, "/"); + + /* Find how many directories are in common between bin_prefix & prefix. */ + std::vector::iterator bin_common, pfx_common; + for (bin_common = bin_dirs.begin(), pfx_common = prefix_dirs.begin(); + bin_common != bin_dirs.end() && pfx_common != prefix_dirs.end(); + bin_common++, pfx_common++) + if (*bin_common != *pfx_common) + break; + + /* If there are no common directories, there can be no relative prefix. */ + if (bin_common == bin_dirs.begin ()) + return NULL; + + std::string result = ""; + + /* Build up the pathnames in argv[0]. */ + for (std::vector::iterator i = prog_dirs.begin (); + i != prog_dirs.end (); + i++) + { + result += *i; + result += '/'; + } + + /* Now build up the ..'s. */ + for (; bin_common != bin_dirs.end (); bin_common++) + result += "../"; + + /* Put in directories to move over to prefix. */ + for (; pfx_common != prefix_dirs.end (); pfx_common++) + { + result += *pfx_common; + result += '/'; + } + + return new std::string(result); + } + // Return a vector of directory names, where the SID_LIBRARY_PATH // and SID_EXEC_PREFIX environment variables are pointing. Convert // all paths to POSIX form on Cygwin. @@ -337,14 +446,31 @@ namespace sidutil sep = conv_fn; } #endif - if (!sep) sep = SID_EXEC_PREFIX; // build-time configuration - // We really just want to get to pkgdatadir, which is $prefix/share - // Guess exec-prefix == prefix - std::string pkglibdir1 = std::string(sep) + std::string("/share"); - search_directories.push_back (pkglibdir1); - // Guess exec-prefix == prefix/H-HOST - std::string pkglibdir2 = std::string(sep) + std::string("/../share"); - search_directories.push_back (pkglibdir2); + if (sep) + { + // We really just want to get to pkgdatadir, which is $prefix/share + // Guess exec-prefix == prefix + std::string pkglibdir1 = std::string(sep) + std::string("/share"); + search_directories.push_back (pkglibdir1); + // Guess exec-prefix == prefix/H-HOST + std::string pkglibdir2 = std::string(sep) + std::string("/../share"); + search_directories.push_back (pkglibdir2); + } + else + { + // Guess from argv[0]. + std::string *path; + path = make_relative_prefix (argv0, SID_EXEC_PREFIX "/bin", + SID_PREFIX "/share"); + if (path) + { + search_directories.push_back (*path); + delete path; + } + else + // Fall back to build-time configuration. + search_directories.push_back (SID_PREFIX "/share"); + } return search_directories; } Index: sid/main/dynamic/mainDynamic.cxx =================================================================== RCS file: /cvs/cvsfiles/devo/sid/main/dynamic/mainDynamic.cxx,v retrieving revision 1.23 diff -p -u -p -r1.23 mainDynamic.cxx --- mainDynamic.cxx 2001/10/05 19:57:06 1.23 +++ mainDynamic.cxx 2001/11/20 05:26:27 @@ -35,6 +35,9 @@ static void sid_pre_run () {} static void sid_post_run () {} +namespace sidutil { + char *argv0; +} void version () @@ -68,6 +71,8 @@ main(int argc, char* argv[]) vector< pair > config_items; bool dry_run_p = false; string config_file; + + argv0 = argv[0]; if (argc == 1) { ============================================================ From mboxrd@z Thu Jan 1 00:00:00 1970 From: Geoffrey Keating To: sid@sources.redhat.com Subject: patch for location-independence Date: Wed, 21 Nov 2001 13:33:00 -0000 Message-ID: <200111212133.fALLXlp11797@thief.cygnus.com> X-SW-Source: 2001-q4/msg00039.html Message-ID: <20011121133300.45IRj--9gZ1rgj_2EJfCsvCttclZftTdvZaSAA49xhA@z> The attached patch causes SID to look at argv[0] to determine its location, so that the installed sid tree can be moved anywhere and there is no need to set SID_EXEC_PREFIX (to run the sid executable, at least). OK to commit? -- Geoff Keating ===File ~/patches/sid-relocate.patch======================== Index: sid/include/ChangeLog 2001-11-19 Geoffrey Keating * sidmiscutil.h (argv0): New variable. (make_relative_prefix): New function. (sid_file_search_path): Determine default SID_EXEC_PREFIX from argv[0]. * configure.in: Define SID_PREFIX as $prefix. * configure: Regenerate. * sidconfutil.in: Dummy SID_PREFIX declaration. Index: sid/main/dynamic/ChangeLog 2001-11-19 Geoffrey Keating * mainDynamic.cxx (sidutil::argv0): Define. Index: sid/include/configure.in =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/configure.in,v retrieving revision 1.10 diff -p -u -p -r1.10 configure.in --- configure.in 2001/03/26 19:18:38 1.10 +++ configure.in 2001/11/20 05:26:27 @@ -66,5 +66,7 @@ else fi AC_DEFINE_UNQUOTED(SID_EXEC_PREFIX,"$sid_exec_prefix",[Define to build-time exec-prefix]) +AC_DEFINE_UNQUOTED(SID_PREFIX,"$prefix",[Define to build-time prefix]) + dnl Outputs AC_OUTPUT(Makefile) Index: sid/include/sidconfutil.in =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/sidconfutil.in,v retrieving revision 1.4 diff -p -u -p -r1.4 sidconfutil.in --- sidconfutil.in 2001/03/26 19:18:38 1.4 +++ sidconfutil.in 2001/11/20 05:26:27 @@ -36,3 +36,6 @@ /* Define to build-time exec-prefix */ #undef SID_EXEC_PREFIX +/* Define to build-time prefix */ +#undef SID_PREFIX + Index: sid/include/sidmiscutil.h =================================================================== RCS file: /cvs/cvsfiles/devo/sid/include/sidmiscutil.h,v retrieving revision 1.19 diff -p -u -p -r1.19 sidmiscutil.h --- sidmiscutil.h 2001/05/25 15:12:54 1.19 +++ sidmiscutil.h 2001/11/20 05:26:27 @@ -20,10 +20,14 @@ #ifdef __CYGWIN__ #include #endif +#include namespace sidutil { + // argv[0] passed to the main program. + extern char *argv0; + // Instances of this class template function as bidirectional lookup // tables (bijections) for mapping objects to each other by value. template @@ -310,6 +314,111 @@ namespace sidutil } + /* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string + that gets to PREFIX starting with the directory portion of + PROGNAME and a relative pathname of the difference between + BIN_PREFIX and PREFIX. + + For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX + is /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, + then this function will return /red/green/blue/../omega. + + If no relative prefix can be found, return NULL. */ + + inline std::string * + make_relative_prefix (const std::string &progname, + const std::string &bin_prefix, + const std::string &prefix) + { + std::vector prog_dirs = tokenize (progname, "/"); + + /* If there is no full pathname, try to find the program by + checking in each of the directories specified in the PATH + environment variable. */ + if (prog_dirs.size() == 1) + { + char *path = getenv ("PATH"); + + if (path) + { + std::vector paths = tokenize (path, ":"); + std::vector::iterator i; + + for (i = paths.begin(); + i != paths.end(); + i++) + { + std::string s = *i; + if (s == "") + s = '.'; + if (s[s.length()-1] != '/') + s += '/'; + s += progname; + if (! access (s.c_str (), X_OK)) + break; +#ifdef HAVE_HOST_EXECUTABLE_SUFFIX + s += HOST_EXECUTABLE_SUFFIX; + if (! access (s.c_str (), X_OK)) + break; +#endif + } + + if (i == paths.end()) + return NULL; + + prog_dirs = tokenize (*i, "/"); + } + } else { + /* Remove the program name from comparison of directory names. */ + prog_dirs.pop_back (); + } + + std::vector bin_dirs = tokenize (bin_prefix, "/"); + + /* Determine if the program is installed in the standard location, and if + so, we don't need to specify relative directories. */ + if (prog_dirs == bin_dirs) + return new std::string (prefix); + + std::vector prefix_dirs = tokenize (prefix, "/"); + + /* Find how many directories are in common between bin_prefix & prefix. */ + std::vector::iterator bin_common, pfx_common; + for (bin_common = bin_dirs.begin(), pfx_common = prefix_dirs.begin(); + bin_common != bin_dirs.end() && pfx_common != prefix_dirs.end(); + bin_common++, pfx_common++) + if (*bin_common != *pfx_common) + break; + + /* If there are no common directories, there can be no relative prefix. */ + if (bin_common == bin_dirs.begin ()) + return NULL; + + std::string result = ""; + + /* Build up the pathnames in argv[0]. */ + for (std::vector::iterator i = prog_dirs.begin (); + i != prog_dirs.end (); + i++) + { + result += *i; + result += '/'; + } + + /* Now build up the ..'s. */ + for (; bin_common != bin_dirs.end (); bin_common++) + result += "../"; + + /* Put in directories to move over to prefix. */ + for (; pfx_common != prefix_dirs.end (); pfx_common++) + { + result += *pfx_common; + result += '/'; + } + + return new std::string(result); + } + // Return a vector of directory names, where the SID_LIBRARY_PATH // and SID_EXEC_PREFIX environment variables are pointing. Convert // all paths to POSIX form on Cygwin. @@ -337,14 +446,31 @@ namespace sidutil sep = conv_fn; } #endif - if (!sep) sep = SID_EXEC_PREFIX; // build-time configuration - // We really just want to get to pkgdatadir, which is $prefix/share - // Guess exec-prefix == prefix - std::string pkglibdir1 = std::string(sep) + std::string("/share"); - search_directories.push_back (pkglibdir1); - // Guess exec-prefix == prefix/H-HOST - std::string pkglibdir2 = std::string(sep) + std::string("/../share"); - search_directories.push_back (pkglibdir2); + if (sep) + { + // We really just want to get to pkgdatadir, which is $prefix/share + // Guess exec-prefix == prefix + std::string pkglibdir1 = std::string(sep) + std::string("/share"); + search_directories.push_back (pkglibdir1); + // Guess exec-prefix == prefix/H-HOST + std::string pkglibdir2 = std::string(sep) + std::string("/../share"); + search_directories.push_back (pkglibdir2); + } + else + { + // Guess from argv[0]. + std::string *path; + path = make_relative_prefix (argv0, SID_EXEC_PREFIX "/bin", + SID_PREFIX "/share"); + if (path) + { + search_directories.push_back (*path); + delete path; + } + else + // Fall back to build-time configuration. + search_directories.push_back (SID_PREFIX "/share"); + } return search_directories; } Index: sid/main/dynamic/mainDynamic.cxx =================================================================== RCS file: /cvs/cvsfiles/devo/sid/main/dynamic/mainDynamic.cxx,v retrieving revision 1.23 diff -p -u -p -r1.23 mainDynamic.cxx --- mainDynamic.cxx 2001/10/05 19:57:06 1.23 +++ mainDynamic.cxx 2001/11/20 05:26:27 @@ -35,6 +35,9 @@ static void sid_pre_run () {} static void sid_post_run () {} +namespace sidutil { + char *argv0; +} void version () @@ -68,6 +71,8 @@ main(int argc, char* argv[]) vector< pair > config_items; bool dry_run_p = false; string config_file; + + argv0 = argv[0]; if (argc == 1) { ============================================================