【问题标题】:Getting locale functions to work in glibc让语言环境函数在 glibc 中工作
【发布时间】:2026-01-05 20:05:01
【问题描述】:

为了获得一些性能改进,我需要对 C 标准库 (glibc) 进行一些修改。具体来说,我将编写一些依赖于语言环境的函数(在 glibc 中表现不佳)的一些特殊版本,例如 strcoll

我已经检查了来自here 的glibc 源代码到~/Desktop/glibc。然后我运行了以下命令序列而没有错误。

$ cd ~/Desktop
$ mkdir bglibc
$ cd bglibc
$ ./../glibc/configure --prefix=~/Desktop/bglibc
$ make
$ make install

至此,我已经成功编译安装glibc到~/Desktop/bglibc。然后我在 bglibc 目录中创建了以下测试程序(ct.c):

#include <stdio.h>
#include <locale.h>

int main ()
{
  char *locale = NULL;
  locale = "en_US.utf8";

  char *result = setlocale(LC_COLLATE, locale);
  if (result == NULL) {
    printf("locale not set\n");
  }   

  printf("strcoll: %d\n", strcoll("some", "string"));

  return 0;
}

然后我用这个脚本构建它:

iSYSROOT=~/Desktop/bglibc

gcc -o ct ct.c \
  --sysroot=${SYSROOT} \
  -Wl,-rpath=${SYSROOT}/lib \
  -Wl,--dynamic-linker=${SYSROOT}/lib/ld.so.1

正确构建它。然后我用这个脚本运行它:

#!/bin/sh
builddir=`dirname "$0"`
GCONV_PATH="${builddir}/iconvdata" \
exec    "${builddir}"/elf/ld-linux-x86-64.so.2 --library-path "${builddir}":"${builddir}"/*:"${builddir}"/*/*:"${builddir}"/*/*/* ${1+"$@"}

这是名称testrun.sh。为了在我之前编译的程序(ct)上运行它,我运行./testrun.sh ./ct

这成功运行程序,但是程序打印出locale not set,这意味着它无法将语言环境设置为"en_US.utf8"。因此,语言环境保持默认值 ("C"),在这种情况下,strcoll 只返回strcmp 的结果。但是,我需要此调用来运行 strcoll 代码,以便对其性能进行测试,然后对其进行调整以使其在特定语言环境下运行得更快。

我知道"en_US.utf8" 是我的系统(Ubuntu 12.04 lts)的有效语言环境,因为我看到了:

$ locale -a | grep US
en_US.utf8

我也尝试过运行这个程序,但将语言环境变量设置为其他字符串,例如 "en_US.UTF-16"、"""en_US.UTF-8" 等,但都没有成功。

我想这不是我在尝试让语言环境的东西与我的修改版 glibc 一起工作时遇到的第一个问题,但它是第一个。

有什么想法可以让语言环境功能(特别是setlocale)正常工作吗?

【问题讨论】:

  • 你试过 setLocale(LC_ALL, locale) 吗?
  • @Clocks,是的,我尝试使用 LC_ALL 代替,但它没有用。就链接而言,这主要是解释“语言环境和设置语言环境如何工作”。我了解 setlocale 函数和系统语言环境如何工作得相当好,手头的问题有点复杂。不过还是谢谢。
  • 对我来说,user2898218 的回答有效。考虑发表评论或接受他的回答。

标签: c locale glibc libc strcmp


【解决方案1】:

我的猜测:您忘记“制作”一些语言环境。试试:

$ make
$ make install
$ make localedata/install-locales

另见GNU libc make manual

安装后您可能需要配置时区和语言环境 安装……

【讨论】:

    【解决方案2】:

    尝试使用strace 找出 glibc 尝试从哪里读取语言环境。我怀疑既然你设置了前缀 glibc 试图在~/Desktop/bglibc/share/locale/ 或类似的东西中找到它们。当然 UTF-16 不适用于 8 位字符串类型...

    【讨论】:

    • 感谢您的建议。我查看了一些使用 strace 的系统调用,并且有一些与语言环境相关的调用是这样的: open("/home/username/Desktop/bglibc/lib/locale/en_US.utf8/LC_IDENTIFICATION", O_RDONLY|O_CLOEXEC ) = -1 ENOENT(没有这样的文件或目录)。所以它在一个不存在的地方寻找语言环境文件(bglib/lib 甚至不存在)。我环顾四周,似乎它们实际上位于此目录中:bglibc/share/i18n/locales。为什么它会在错误的位置寻找?看起来它应该知道正确的查看位置。
    • 我不知道,无论如何,一个简单的符号链接现在就足以测试指向正确目录时语言环境是否有效
    • 我已将符号链接添加到正确的文件,但问题仍然存在。我不知道您是否还有其他建议,但无论哪种方式都感谢您的帮助。