------- Additional Comments From jason_gouger at mentor dot com 2005-09-20 02:17 ------- (In reply to comment #0) > looking at gcc.c it looks like the problem is coming from the following line: > gcc_libexec_prefix = make_relative_prefix > (gcc_exec_prefix, > standard_exec_prefix, > standard_libexec_prefix); > > The problem is that make_relative_prefix is expecting a program name as first > argument. But the gcc_exec_prefix is a directory. So that's why /my_prefix/ is > removed when computing gcc_libexec_prefix...
I think there are more issues than that incorrect argument. From what I could see was that even though make_relative_path expects a program name the return path discards it which may be okay. I am not sure on the original intent but preserving the common suffixes on arg2 and arg3 and then reapplying to the result seems to fix or at least work around the problem. >From make-relative-prefix.c : For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta}, @var{prefix} is @code{/alpha/beta/gamma/omega/}, and @var{progname} is @code{/red/green/blue/gcc}, then this function will return @code{/red/green/blue/../../omega/}. progname = /red/green/blue/gcc bin_prefix = /alpha/beta/gamma/gcc/delta prefix = /alpha/beta/gamma/omega/ returns = /red/green/blue/../../omega/ In this case : progname = <NEW_PATH>/gcc-Y.Y.Y/lib/gcc (gcc_exec_prefix) bin_prefix = <COMPILE_PATH>/gcc-X.X.X/lib/gcc (standard_exec_prefix) prefix = <COMPILE_PATH>/gcc-X.X.X/libexec/gcc (standard_libexec_prefix) returns = <NEW_PATH>/gcc-Y.Y.Y/lib/../../libexec/gcc 1. make bin_prefix relative to prefix <COMPILE_PATH>/gcc-X.X.X/lib/gcc/../../libexec/gcc 2. Replace the program path '<NEW_PATH>/gcc-X.X.X/lib' (dropped prg name gcc) <NEW_PATH>/gcc-Y.Y.Y/lib/../../libexec/gcc So the ../.. is caused by the fact in step one make_relative_path needed to go up two directories. If we strip the common suffixes of bin_prefix and prefix and then reappend we will get the desired result. common_suffix=/gcc progname = <NEW_PATH>/gcc-Y.Y.Y/lib/gcc (gcc_exec_prefix) bin_prefix = <COMPILE_PATH>/gcc-X.X.X/lib (standard_exec_prefix w/out common suffix) prefix = <COMPILE_PATH>/gcc-X.X.X/libexec (standard_libexec_prefix w/out common suffix) returns = <NEW_PATH>/gcc-Y.Y.Y/lib/../libexec/gcc 1. make bin_prefix relative to prefix <COMPILE_PATH>/gcc-X.X.X/lib/../libexec 2. Replace the program path '<NEW_PATH>/gcc-X.X.X/lib' (dropped prg name gcc) <NEW_PATH>/gcc-Y.Y.Y/lib/../libexec 3. Reappend common suffix <NEW_PATH>/gcc-Y.Y.Y/lib/../libexec/gcc > Besides this I think that since 3.4.x series GCC_EXEC_PREFIX is quite useless > indeed it is quite hard to redefine the location where cc1 is found This worked properly in gcc 3.4.3 and prior releases. To reproduce the problem install to a non-standard location. Remove (rename) the build area. Rename the non-standard location to another non-standard name and set the GCC_EXEC_PREFIX. In 3.4.3 this worked... Here is a patch file against gcc 4.0.1 (gcc/gcc.c) which implements the algorithm mentioned above. 3232,3235c else { /* Find common ending of stanard_exec_prefix and standard_libexec_prefix. // Essentially we are stripping /gcc/ for later use... This is required // because make_relative path will just add ..'s for these directories. // This is not the intention as the make_relative_path given three // paths "progname", "bin_prefix", and "prefix"; returns the path that // is in the same position relative to "progname's" directory as "prefix" // is relative to "bin_prefix". So we can achieve the desired result by // stripping this common suffix and concat'ing the result */ const char *exec_ptr = standard_exec_prefix + strlen (standard_exec_prefix); const char *libexec_ptr = standard_libexec_prefix + strlen (standard_libexec_prefix); char *exec_buf; char *libexec_buf; char *gccexec_buf; int exec_len; int libexec_len; while (exec_ptr > standard_exec_prefix && libexec_ptr > standard_libexec_prefix && *exec_ptr == *libexec_ptr ) { --exec_ptr; --libexec_ptr; } if (exec_ptr > standard_exec_prefix) ++exec_ptr; exec_len = exec_ptr - standard_exec_prefix; exec_buf = xmalloc(exec_len + 1); strncpy(exec_buf, standard_exec_prefix, exec_len); exec_buf[exec_len] = '\0'; if (libexec_ptr > standard_libexec_prefix) ++libexec_ptr; libexec_len = libexec_ptr - standard_libexec_prefix; libexec_buf = xmalloc(libexec_len + 1); strncpy(libexec_buf, standard_libexec_prefix, libexec_len); libexec_buf[libexec_len] = '\0'; /* NOTE: make_relative_path really takes a program name as the // first argument. However, even though it is a directory // it just needs to be stripped. */ gccexec_buf = make_relative_prefix (gcc_exec_prefix, exec_buf, libexec_buf); free(exec_buf); free(libexec_buf); if (gccexec_buf) { gcc_libexec_prefix = concat(gccexec_buf, exec_ptr, NULL); free(gccexec_buf); } else gcc_libexec_prefix = 0; } . w -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21553