Hi, LOCALEDIR seams a build-time constant, which is an absolute path. But
* When releasing gcc binaries as a tarball, users can put it at any dir. * For "Canadian" build, the dir layout on the build machine might be different from the host machine. For such cases, gcc most likely can not find the gcc.mo. The patch tries to search relative dir "../share/locale" from gcc. Although it can not cover all cases, I think it can cover most cases. Bootstrap and no make check regression on X86-64. OK for trunk? Thanks! -Zhenqiang ChangeLog: 2014-07-07 Zhenqiang Chen <zhenqiang.c...@linaro.org> * gcc.c (main): Call gcc_init_libintl_program. * intl.c (gcc_init_libintl): Likewise. (gcc_init_libintl_program): New function. * intl.h (gcc_init_libintl_program): New prototype. diff --git a/gcc/gcc.c b/gcc/gcc.c index 6cd08ea..0addc0c5 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -6409,7 +6409,7 @@ main (int argc, char **argv) /* Unlock the stdio streams. */ unlock_std_streams (); - gcc_init_libintl (); + gcc_init_libintl_program (argv[0]); diagnostic_initialize (global_dc, 0); diff --git a/gcc/intl.c b/gcc/intl.c index 2509c1a..6d1a45c 100644 --- a/gcc/intl.c +++ b/gcc/intl.c @@ -48,6 +48,14 @@ bool locale_utf8 = false; void gcc_init_libintl (void) { + gcc_init_libintl_program ("gcc"); +} + +#define LIBINTL_RELATIVE_DIR "../share/locale" + +void +gcc_init_libintl_program (const char * program_name) +{ #ifdef HAVE_LC_MESSAGES setlocale (LC_CTYPE, ""); setlocale (LC_MESSAGES, ""); @@ -55,7 +63,32 @@ gcc_init_libintl (void) setlocale (LC_ALL, ""); #endif - (void) bindtextdomain ("gcc", LOCALEDIR); + if (!access (LOCALEDIR, X_OK)) + { + /* If LOCALEDIR exists, use LOCALEDIR. */ + (void) bindtextdomain ("gcc", LOCALEDIR); + } + else + { + /* Try relative dir, i.e. .../bin/../share/locale. */ + int len1, len2; + char *prefix_dir, *locale_dir; + prefix_dir = make_relative_prefix (program_name, ".", "."); + len1 = strlen (prefix_dir); + len2 = strlen (LIBINTL_RELATIVE_DIR); + locale_dir = (char*) xmalloc (len1 + len2 + 1); + if (locale_dir != NULL) + { + strcpy (locale_dir, prefix_dir); + strcpy (locale_dir + len1, LIBINTL_RELATIVE_DIR); + (void) bindtextdomain ("gcc", locale_dir); + } + else + (void) bindtextdomain ("gcc", LOCALEDIR); + + free (prefix_dir); + } + (void) textdomain ("gcc"); /* Opening quotation mark. */ diff --git a/gcc/intl.h b/gcc/intl.h index 91e7440..84b9d58 100644 --- a/gcc/intl.h +++ b/gcc/intl.h @@ -30,6 +30,7 @@ #include <libintl.h> extern void gcc_init_libintl (void); extern size_t gcc_gettext_width (const char *); +extern void gcc_init_libintl_program (const char *); #else /* Stubs. */ # undef textdomain @@ -41,6 +42,7 @@ extern size_t gcc_gettext_width (const char *); # define ngettext(singular,plural,n) fake_ngettext (singular, plural, n) # define gcc_init_libintl() /* nothing */ # define gcc_gettext_width(s) strlen (s) +# define gcc_init_libintl_program (s) /* Nothing. */ extern const char *fake_ngettext (const char *singular, const char *plural, unsigned long int n);