Chromium 资源与多语言工具 grit

Tags : chromium grit grd pak

1. 关于资源

任何应用都有一些自身持有的资源,如UI上的按钮,特定的页面,或者是针对不同系统语言设置的不同字符串。这些必然需要通过一个通用的方式集成到应用当中。
Chromium,包括android webview或者同名浏览器,它的资源大致包括两个部分

  1. 图片,CSS,JS,HTML,用于浏览器本身或者辅助浏览
  2. 多国语言本地化字符串

这些资源统一以*.pak形式的文件存放于apk中(assets文件夹中)。其中
Android SystemWebView中为webviewchromium.pak
ChromiumPublicApk则为chrome_100_percent.pak与resources.pak

为了生成pak文件,我们除了需要需要打包的源文件外,还需要grd配置文件以及grit工具进行打包。

GRIT 全名为 the Google Resource and Internationalization Tool。该工具可以于chromium项目代码的src/tools/grit/该路径下找到。

使用方法如下:

Usage: grit [GLOBALOPTIONS] TOOL [args to tool]
Global options:
  -i INPUT  Specifies the INPUT file to use (a .grd file).  If this is not
            specified, GRIT will look for the environment variable GRIT_INPUT.
            If it is not present either, GRIT will try to find an input file
            named 'resource.grd' in the current working directory.
  -h MODULE Causes GRIT to use MODULE.UnsignedFingerPrint instead of
            grit.extern.FP.UnsignedFingerprint.  MODULE must be
            available somewhere in the PYTHONPATH search path.
  -v        Print more verbose runtime information.
  -x        Print extremely verbose runtime information.  Implies -v
  -p FNAME  Specifies that GRIT should profile its execution and output the
            results to the file FNAME
          
Tools:
  TOOL can be one of the following:
    build        A tool that builds RC files for compilation.
    buildinfo    Determine what files will be needed and
output by GRIT with a given input.
    count        Count the number of times a given message ID is used.
    newgrd       Create a new empty .grd file.
    rc2grd       A tool for converting .rc source files to .grd files.
    resize       Generate a file where you can resize a given dialog.
    sdiff        View differences without regard for translateable portions.
    transl2tc    Import existing translations in RC format into the TC
    unit         Use this tool to run all the unit tests for GRIT.
    xmb          Exports all translateable messages into an XMB file.
    android2grd  Converts Android string.xml files into Chrome grd files.
  For more information on how to use a particular tool, and the specific
  arguments you can send to that tool, execute 'grit help TOOL'

而grd文件则是一个标准xml文档,结构会在下面的内容里详述。

2. 打包多国语言本地化字符串资源

多国语言本地化字符串,首先我们需要准备grd文件作为配置文件。

如果你是需要新建一个grd以及一个新的打包,推荐可以使用下列命令用grit生成一个空的grd文件模板来进行设计。
$ python ./src/tools/grit/grit.py newgrd

a.grd配置文件

这里我们以android_ui_strings.grd为例

grd的基本结构如下
最外层node为

<grit current_release="1" latest_public_release="0">
...
</grit>

多国语言需要在grit的node中添加下列三类
<outputs>
<translations>
<release>

(1).outputs

outputs主要描述输出的文件,一般都为.h头文件用以描述具体id号,以及具体的资源打包文件pak文件。

<outputs>
    <output filename="grit/aw_strings.h" type="rc_header">
      <emit emit_type='prepend'></emit>
    </output>
    <output filename="aw_strings_am.pak" type="data_package" lang="am" />
    <output filename="aw_strings_ar.pak" type="data_package" lang="ar" />
...
</outputs>

无非就是两类,rc_header和data_package,其中data_package需要描述具体语言

(2).translations

translations主要定义了具体语言的翻译模板

  <translations>
    <file path="translations/aw_strings_am.xtb" lang="am" />
    <file path="translations/aw_strings_ar.xtb" lang="ar" />
...
  </translations>

这里指定了grit生成具体pak的输入文件有那些xtb文件。
这些xtb的格式都是固定的,会在下一个小节进行详细说明。

(3).release

release是描述提供的具体字符串

  <release seq="1">
    <messages fallback_to_english="true">
      <message name="IDS_AW_WEBPAGE_NOT_AVAILABLE" desc="The title of the webpage shown when the requested URL in unavailable">
        Webpage not available
      </message>
...
    </messages>
  </release>

如上述格式,其中message为具体字符串内容,包含有name和desc两个属性
name为该字符串资源的id,该id也会在之前生成的头文件中体现,一般都以IDS开头然后全大写(因为之后是要在h头文件中进行define作为宏名的)
desc则是描述下该资源是干什么用的

b. xtb文件

xtb(translationbundle)文件是提供每个语言翻译字段的具体输入源

这些文件需要和grd作为输入给grit来生成具体资源文件。

每个xtb文件结构都是一致的如下所示:

<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
<translation id="1555130319947370107">蓝色</translation>
<translation id="161042844686301425">青色</translation>
...shuxie
</translationbundle>

这里有一个问题,每一个翻译具体的id不是之前在grd的name,而是具体的hash值
我们该如何获得这个hash值呢?

现在知道的方法是使用grit的xmb工具来生成具体hash,然后再套用到这个xtb模板。
执行以下命令:
$ python ./tools/grit/grit.py -i YOUR_GRD_FILE xmb OUTPUT_XMB_FILE_PATH

其中GRD_FILE为需要翻译的grd文件路径
OUTPUT_XMB_FILE_PATH指定输出的XMB放的位置

xmb文件本身不参与到最后的打包过程,所以随便放个临时位置都行
其中找到messagebundle node中具体的每个msg

<messagebundle>
<msg desc="Accessibility label for button to select the blue color." id="1555130319947370107">
  Blue
</msg>shuxie
<msg desc="Accessibility label for button to select the cyan color." id="161042844686301425">
  Cyan
</msg>
...

我们就可以看到具体的id值了,然后按照上述xtb的模板按部就班填写id以及各个语言翻译字段即可

PS: 个人感觉应该不会需要生成XMB然后再手工填写XTB的具体transaction的message id值。
可能会存在直接输出XTB文件的工具,但是grit似乎没有提供。

c.生成翻译文件

准备好了xtb文件和grd配置文件后,就可以执行grit进行构建具体的翻译文件了

$ python ./src/tools/grit/grit.py -i ./src/ui/android/java/strings/android_ui_strings.grd build -o ~/output/

输出到output文件夹下我们就可以看到
├── values
│ └── android_ui_strings.xml
├── values-am
│ └── android_ui_strings.xml
├── values-ar
│ └── android_ui_strings.xml
....

当然我们在chromium中使用的是pak打包好的资源文件。

分析android_ui_string.grd在BUILD.gn中的build我们可以发现,多国语言本地化字符串使用了一个名为"java_strings_grd"的gn template。这一步就只是完成了grit生成xml的过程。
然后通过android_resources的gn template去完成打包的工作。

具体书写可以详细参考android_ui_string的流程。这里不再一一赘述。

3. 打包非语言资源

除了本地化字符串外,grit还提供打包其他诸如图片,css,js,html等资源的功能。

我们以system_webview_apk中实际打包的load_error.html为例说明
首先我们也需要准备一个grd配置文件
与上述本地化字符串的grd文件有区别的地方在于

  1. 没有translations element,因为不需要指定翻译语言内容
  2. release中不是message,而是一个个includes或者是structures

关于上述2中,资源文件是BMP,GIF,具体HTML这种资源时使用includes
而结构资源类似HTML模板,菜单,对话框等,则是使用structures

这里我们就是用includes,以下列方式进行书写

    <includes>
      <include name="IDR_AW_LOAD_ERROR_HTML" file="resources\load_error.html" flattenhtml="true" type="BINDATA" />
    </includes>

其中type只要进入rc文件分类的,rc文件是windows MFC的资源文件
name:和之前一样设置该资源名字,当然不能重名,以及以IDS开头并且一般全大写
file:这个资源文件路径,相对于这个grd文件

注意include这个node没有body

都准备妥当后,使用grit的gn template进行打包,一步完成

grit("generate_aw_resources") {
  source = "ui/aw_resources.grd"
  outputs = [
    "grit/aw_resources.h",
    "aw_resources.pak",
  ]
}

其他:

  1. chromium grit 用户文档
  2. chromium grit 设计概览
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容