This is the mail archive of the
sid@sources.redhat.com
mailing list for the SID project.
patch for location-independence
- From: Geoffrey Keating <geoffk at cygnus dot com>
- To: sid at sources dot redhat dot com
- Date: Wed, 21 Nov 2001 13:33:47 -0800
- Subject: patch for location-independence
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 <geoffk@redhat.com>
===File ~/patches/sid-relocate.patch========================
Index: sid/include/ChangeLog
2001-11-19 Geoffrey Keating <geoffk@redhat.com>
* 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 <geoffk@redhat.com>
* 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 <sys/cygwin.h>
#endif
+#include <unistd.h>
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 <class Obj1, class Obj2>
@@ -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<std::string> 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<std::string> paths = tokenize (path, ":");
+ std::vector<std::string>::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<std::string> 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<std::string> prefix_dirs = tokenize (prefix, "/");
+
+ /* Find how many directories are in common between bin_prefix & prefix. */
+ std::vector<std::string>::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<std::string>::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<bool,string> > config_items;
bool dry_run_p = false;
string config_file;
+
+ argv0 = argv[0];
if (argc == 1)
{
============================================================