README.solaris 6.3 KB

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