UTF-8的交叉编译的ncurses显示不正确

时间:2014-05-23 04:02:13

标签: python vim unicode utf-8 ncurses

我有一个嵌入式系统,带有一个vt52u(unicode)终端模拟器,它可以正确显示UTF-8字符,但我有交叉编译的程序(vim和python),当使用ncursesw时,在该终端上没有正确显示unicode字符库。

我已经完成了搜索,但网上没有任何内容似乎有帮助...

Bash shell设置了这些变量:

LANG=en_US.UTF-8
LD_LIBRARY_PATH=/mnt/sd/lib  # all libraries, cross compiled, are located here
TERM=vt52u
TERMCAP='vt52u|vt52 with UTF-8:am:eo:rs=\Ee\Eb0\Eco:is=\EE\Ee:nl=^j:sr=\Ei:bl=^g:ta=^i:ho=\EH:cr=^m:le=\ED:nd=\EC:do=\EB:up=\EA:ta=^i:nw=^m:xn:cm=\EY%+ %+ :it#8:co#75:li#24:sc=\Ej:rc=\Ek:vi=\Ef:ve=\Ee:so=\Eb0\Ec4:se=\Eb0\Eco:mh=\Eb8\Eco:mr=\Ebo\Ec0:me=\Eb0\Eco:cl=\EH\EJ:cd=\EJ:ce=\EK:km:ku=^p:kd=^n:kr=^f:kl=^b:kb=^h:'
LOCALE=

我知道unicode终端没问题,因为我可以运行以下程序让它完美地显示UTF-8字符。

#!/bin/env python
#coding=UTF-8

charset = [
0x2205, 0x2629, 0x00B2, 0x2663, 0x2666, 0x00B1, 0x221A, 0x266B,
0x2190, 0x2524, 0x2500, 0x2534, 0x253C, 0x251C, 0x2193, 0x2191,
0x00B0, 0x2665, 0x00AE, 0x2660, 0x00B7, 0x00A4, 0x00A4, 0x00A4,
0x00D7, 0x00B5, 0x2126, 0x252C, 0x250C, 0x2510, 0x2514, 0x2518
]

for i in charset:
    print unichr( i ).encode("UTF-8"),
    if i == 0x2191: print
print


bash-4.3#./testunicode
bash-4.3# ∅ ☩ ² ♣ ♦ ± √ ♫ ← ┤ ─ ┴ ┼ ├ ↓ ↑
bash-4.3# ° ♥ ® ♠ · ¤ ¤ ¤ × µ Ω ┬ ┌ ┐ └ ┘

但是当我尝试在python程序中使用curses(ncursesw)显示框绘制字符时,或者使用vim编辑UTF-8文本文件(链接到ncursesw);我最终在屏幕上打印了一个无效的unicode框,然后是〜T~B,~T~L等额外的符号,以及每个unicode字符的许多其他变体。因此,由于某种原因,ncursesw输出的UTF-8字符无效....

我知道它链接正确,并且没有冲突的ncurses库;只有ncursesw存在。

我配置了ncurses-5.9库进行编译,如下所示:

./configure --prefix=/mnt/sd --without-cxx --without-cxx-binding --without-ada --without-manpages --without-progs --without-tests --without-curses-h --with-build-cc=gcc --with-shared --without-normal --without-debug --without-profile --without-gpm --without-dlsym --without-sysmouse --build=i686-linux --host=arm-linux-gnueabi --without-pthread --enable-widec --with-fallbacks=vt52 --with-terminfo-dirs=/etc/terminfo --disable-big-core --enable-termcap --with-termpath=/Data/termcap

举个例子:以下程序在我的桌面linux~VT102上正常运行 - 但在vt52u上运行时嵌入式系统出现故障:

#!/bin/env python
# coding=UTF-8
board=[
"","",
u"   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐",
u"   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │   │",
u"   │   │ ├───→───→───→ │   │   │   │   │   │ ├───→───→───→ │   │   │" ]

board = ( i.encode("utf-8") for i in board )

import curses
import locale
locale.setlocale( locale.LC_ALL,"" )

screen = curses.initscr()
curses.noecho() # no echoing
curses.cbreak() # no keyboard buffering

# Setup the playing board screen. 
for i,s in enumerate( board ): screen.addstr( i,0,s )
screen.refresh()

import time
time.sleep(2)

# Return everything to normal
curses.echo()
curses.nocbreak()
curses.endwin()

编辑:我发现了一个可能的错误原因 - glibc,交叉编译,没有正确的路径到/ mnt / sd / share / i18n / charmap或/ mnt / sd / share / i18n / locales目录。它只有部分路径,其中Make或configure以错误的'/'为前缀,而不是目标系统的实际根路径/ mnt / sd。如果没有找到文件,glibc显然会默认返回“C”或“POSIX”语言环境并忽略环境变量。

我不确定是否必须重新编译glibc并手动编辑makefile,或者是否有办法在系统构建后手动设置路径....有任何想法吗。 ???

1 个答案:

答案 0 :(得分:0)

Ncurses依赖于标准的C库,它需要在其中包含国际化文件的目录的路径编译,否则NCURSES将自动默认返回POSIX语言环境(AKA“C”语言环境)并且不会执行UTF -8。

在构建系统上进行交叉编译,其中语言环境存储在与主机不同的位置,这会导致autoconfig脚本错误地识别目录,然后嵌入式系统将无法执行UTF-8,即使区域设置变量是设置正确......更糟糕的是,故障可能不会产生任何错误消息。

但是:如果路径错误,那么除了POSIX&之外,您将无法看到任何语言环境。 C运行时:

locale -a

使用国际化文件在构建系统上设置虚拟目录,然后重新编译标准C库是解决问题的一种方法;但它可能需要根源。

或者,有一个环境变量“I18NPATH”可以在使用gnu标准C库(glibc)时设置;它应该覆盖已编译的路径。如果嵌入式系统上的安装前缀是“/ mnt / sd”,那么从bash shell开始 - 只需执行:

export I18NPATH="/mnt/sd/share/i18n"

在任何一种情况下,一旦修正后的路径可用/安装 - 系统应该正常运行。如果没有,检查以确保实际上已为国家charmap和UTF-8的组合生成了语言环境(使用“locale -a”列出所有内容)。

如果它不存在,可以使用“localedef”实用程序非常简单地创建它。例如:要创建一个支持UTF-8的美国英语语言环境,只需执行以下操作:

localedef -i en_US -c -f UTF-8 en_US.UTF-8

然后,确保设置和导出区域设置变量:

export LOCALE=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8

然后运行没有参数的语言环境应该将所有变量显示为en_US.UTF-8 ......从那时起一切都会正常工作。