1Special Notes for Sun Solaris 2============================= 3 4Recent versions of Solaris ship with a libintl that is mostly compatible 5with GNU gettext. Even the plural handling functions (ngettext, 6dngettext, dcngettext, ...) and output character conversion functions 7(bind_textdomain_codeset) are included. 8 9On my test system, the behavior of the Solaris version differs in one 10important point from the pure Perl version or the GNU gettext version: 11In a locale environment that is a regional variant of another locale 12(for example "fr_CA" is a regional variant of "fr"), both the pure Perl 13version from libintl-perl and the C version from GNU gettext will fall 14back to translations for the superordinate message catalog ("fr") if 15no special translation for the selected locale ("fr_CA") can be found. 16This fallback mechanism is missing in the Solaris implementation. 17 18This could be considered harmless, because Solaris users are probably 19used to this behavior. On the other hand, the pure Perl version of 20gettext in libintl-perl aims to be as compatible as possible to the 21GNU gettext implementation. Furthermore, if the pure Perl and the 22C/XS version behave differently, users may be unnecessarily confused. 23 24If you think you can live with that little inconsistence, you are not 25completely lost: Edit the toplevel Makefile.PL, in the function 26WriteMakefile(), change the value for the hash slot "DIR" from 27the value depending on "$result" to simply "['gettext_xs']". If you 28have a look at the source code of Makefile.PL, you will see that this 29has already been prepared. 30 31If you do this, the test suite will fail, because the above described 32behavior ("fr_CA" vs. "fr" ...) is checked by the tests. In this case, 33expect the following failures: 34 35Failed Test Stat Wstat Total Fail Failed List of Failed 36------------------------------------------------------------------------------- 37./tests/03bind_textdomain_codeset_xs.t 9 2 22.22% 5 9 38./tests/03dcgettext_xs.t 9 2 22.22% 3 7 39./tests/03dcngettext_xs.t 83 51 61.45% 22-31 43-83 40./tests/03dgettext_xs.t 9 2 22.22% 3 7 41./tests/03dngettext_xs.t 83 51 61.45% 22-31 43-83 42./tests/03gettext_xs.t 6 1 16.67% 3 43./tests/03ngettext_xs.t 85 51 60.00% 23-32 45-85 44 45But even if you have installed GNU gettext, you may run into this error 46when trying to compile the XS version: 47 48"gettext_xs.xs", line 32: #error: "<libintl.h> is not GNU gettext. Maybe you have to adjust your include path." 49cc: acomp failed for gettext_xs.c 50make[1]: *** [gettext_xs.o] Error 2 51make[1]: Leaving directory `/root/libintl-perl-1.15/gettext_xs' 52make: *** [subdirs] Error 2 53 54What has happened here? Have a look at the source code of <libintl.h> 55that ships with GNU gettext: 56 57/* We define an additional symbol to signal that we use the GNU 58 implementation of gettext. */ 59#define __USE_GNU_GETTEXT 1 60 61... 62 63/* We redirect the functions to those prefixed with "libintl_". This is 64 necessary, because some systems define gettext/textdomain/... in the C 65 library (namely, Solaris 2.4 and newer, and GNU libc 2.0 and newer). 66 If we used the unprefixed names, there would be cases where the 67 definition in the C library would override the one in the libintl.so 68 shared library. Recall that on ELF systems, the symbols are looked 69 up in the following order: 70 1. in the executable, 71 2. in the shared libraries specified on the link command line, in order, 72 3. in the dependencies of the shared libraries specified on the link 73 command line, 74 4. in the dlopen()ed shared libraries, in the order in which they were 75 dlopen()ed. 76 The definition in the C library would override the one in libintl.so if 77 either 78 * -lc is given on the link command line and -lintl isn't, or 79 * -lc is given on the link command line before -lintl, or 80 * libintl.so is a dependency of a dlopen()ed shared library but not 81 linked to the executable at link time. 82 Since Solaris gettext() behaves differently than GNU gettext(), this 83 would be unacceptable. 84 85 The redirection happens by default through macros in C, so that &gettext 86 is independent of the compilation unit, but through inline functions in 87 C++, in order not to interfere with the name mangling of class fields or 88 class methods called 'gettext'. */ 89 90In brief: The GNU libraries libintl.so and libintl.a prefix all functions 91with "libintl_" in order to avoid symbol name conflicts with the vanilla 92Solaris verssion. These precautions still give room to a popular 93misconfiguration: If you install GNU gettext with the default prefix 94"/usr/local", libraries will get installed in "/usr/local/lib", the 95header files - notably <libintl.h> - will get installed in 96"/usr/local/include", so far so good. Now set the environment variable 97LD_LIBRARY_PATH to "/usr/local/lib", so that the GNU version of libintl.so 98will be found by the dynamic loader at runtime. Yet, if 99"/usr/local/include" comes after "/usr/include" in your C compiler's 100include path, the above described trick does not work, the functions 101like "gettext", "dgettext" etc. will not get re-defined to "libintl_gettext", 102"libintl_dgettext" and so on. Remember, the preprocessor trick used by 103GNU gettext will change every reference to the function gettext() into 104a reference to libintl_gettext() for gettext() into a definition for 105libintl_gettext(). If your C compiler includes the "wrong" include file 106(/usr/include/libintl.h) instead of the "correct" one 107(/usr/local/include/libintl.h), your C sources will still reference 108gettext() instead of libintl_gettext(). At run-time, even if the dynamic 109loader considers the GNU version of libintl.so (in "/usr/local/lib"), it 110will not use it, because it looks for the "wrong" symbol gettext() 111instead of libintl_gettext(). 112 113Too complicated? Okay: The order for C header files for the C compiler 114(actually the preprocessor) differs from the inclusion order for 115libraries and this must lead to trouble. If you understand WHY, you 116will find a way to fix it. If not, ignore the problem: Do not 117build the problem, and be assured, that the pure Perl version is 118fast enough. It is very, very unlikely that using the pure Perl 119instead of the XS version of will be the bottleneck of any application 120you use. 121 122Life is complicated under the sun, ain't it? ;-) 123 124Guido 125 126