You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用GNU gettext本地化C++/CMake程序?附示例

C++程序使用GNU gettext本地化完整示例

一、代码修正(解决xgettext生成空文件问题)

xgettext是静态扫描源代码提取翻译条目,只能识别gettext("字符串字面量")的写法,原代码中传入变量name导致它无法解析,所以必须改用字符串字面量。同时需要补充gettext本地化环境的初始化代码,否则翻译不会生效:

#include <iostream>
#include <string_view>
#include <libintl.h>
#include <locale.h>

#define PACKAGE "myapp"   // 程序标识,需与后续配置一致
#define LOCALEDIR "./lang"  // 翻译文件存放目录

int main() {
    // 初始化本地化环境
    setlocale(LC_ALL, "");
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);

    // 使用字符串字面量,让xgettext能提取翻译条目
    std::string_view name = gettext("foo");
    std::cout << name << "\n";

    return 0;
}

二、生成.pot翻译模板文件

在项目根目录执行以下命令,生成包含所有待翻译条目的模板文件到lang目录:

xgettext --keyword=gettext --language=C++ --output=lang/myapp.pot main.cpp

参数说明:

  • --keyword=gettext:指定要扫描的翻译函数为gettext
  • --language=C++:按C++语法规则解析源代码
  • --output=lang/myapp.pot:指定模板文件的输出路径

执行后lang目录下会生成myapp.pot,里面包含"foo"这个待翻译条目。

三、创建/更新.po翻译文件

1. 基于模板生成新语言的翻译文件

以德语(de_DE)为例,执行命令生成对应.po文件:

msginit --input=lang/myapp.pot --output=lang/de_DE.po --locale=de_DE.UTF-8

执行过程中会提示输入"foo"的德语翻译(比如"Hallo"),完成后lang/de_DE.po就创建好了。其他语言(如fr_FR、ru_RU)重复此步骤即可。

2. 更新已有翻译文件

当源代码新增翻译条目时,用以下命令更新现有.po文件,保留已有翻译的同时合并新条目:

msgmerge --update lang/de_DE.po lang/myapp.pot

四、编译.po为二进制.mo文件

gettext运行时加载的是二进制格式的.mo文件,需将每个.po编译为对应.mo,并放到指定目录结构下:

# 创建德语翻译的目录结构(其他语言同理)
mkdir -p lang/de_DE/LC_MESSAGES
# 编译po为mo
msgfmt --output-file=lang/de_DE/LC_MESSAGES/myapp.mo lang/de_DE.po

五、CMake配置(自动化构建与翻译管理)

将本地化相关逻辑集成到CMakeLists.txt,方便一键构建和维护:

cmake_minimum_required(VERSION 3.10)
project(myapp)

# 查找系统中的gettext库
find_package(Gettext REQUIRED)

# 编译主程序
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE ${GETTEXT_LIBRARIES})
target_include_directories(myapp PRIVATE ${GETTEXT_INCLUDE_DIRS})

# 传递编译定义给代码
set(PACKAGE_NAME "myapp")
set(LOCALEDIR "${CMAKE_SOURCE_DIR}/lang")
target_compile_definitions(myapp PRIVATE 
    PACKAGE="${PACKAGE_NAME}"
    LOCALEDIR="${LOCALEDIR}"
)

# 生成pot模板的自定义目标
add_custom_target(update_pot
    COMMAND xgettext --keyword=gettext --language=C++ --output=lang/${PACKAGE_NAME}.pot main.cpp
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

# 批量编译所有语言的po为mo
set(TRANSLATIONS de_DE fr_FR ru_RU)  # 可添加更多语言
foreach(LANG ${TRANSLATIONS})
    set(PO_FILE ${CMAKE_SOURCE_DIR}/lang/${LANG}.po)
    set(MO_DIR ${CMAKE_SOURCE_DIR}/lang/${LANG}/LC_MESSAGES)
    set(MO_FILE ${MO_DIR}/${PACKAGE_NAME}.mo)
    
    add_custom_command(
        OUTPUT ${MO_FILE}
        COMMAND mkdir -p ${MO_DIR}
        COMMAND msgfmt --output-file=${MO_FILE} ${PO_FILE}
        DEPENDS ${PO_FILE}
    )
    list(APPEND MO_FILES ${MO_FILE})
endforeach()

add_custom_target(translations ALL DEPENDS ${MO_FILES})

六、运行测试

通过设置环境变量指定运行时语言,验证翻译效果:

# 测试德语环境
export LANG=de_DE.UTF-8
./myapp  # 输出德语翻译内容

# 测试法语环境
export LANG=fr_FR.UTF-8
./myapp  # 输出法语翻译内容

内容的提问来源于stack exchange,提问作者yukkute

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:01:23