May 19, 2008

以 CMake 處理專案的多國語文翻譯

三月份發表 [貓也會的 CMake] 後,陸續有網友來信指教,其中 huki 問及該如何將自由軟體界廣泛使用的 GNU gettext 整合到以 CMake 為建構系統的專案中,又該如何維護 po (原始的翻譯訊息) / gmo (為 GNU gettext 接受的編譯訊息) 檔案呢?這問題很好,但沒有一定的解法。我採用的方式類似 [GTK-Qt Theme Engine] (允許 Gtk+ 程式使用 Qt 外觀的 plugin),在這個專案的 Subversion 檔案庫中,已採用 CMake,詳情可參考 [gtk-qt-engine]。

拜 CMake 簡潔語法所賜,在 gtk-qt-engine 的 po/CMakeLists.txt 是這麼做的:
# .po to .gmo stuff
FILE(GLOB _pofiles *.po)

FOREACH(_file ${_pofiles})
        GET_FILENAME_COMPONENT(_file_we ${_file} NAME_WE)
        SET(_out "${_file_we}.gmo")
        SET(_in "${_file_we}.po")

        ADD_CUSTOM_COMMAND(
                OUTPUT ${_out}
                COMMAND ${MSGFMT_EXECUTABLE} -o ${_out} ${_in}
                DEPENDS ${_in}
        )

        INSTALL(
                FILES ${_out}
                DESTINATION share/locale/${_file_we}/LC_MESSAGES/
                RENAME gtkqtengine.mo
        )

        SET(_outputs ${_outputs} ${_out})
ENDFOREACH(_file)
原理就是將 po/ 目錄下的若干翻譯檔案掃描一次,並呼叫 GNU gettext 套件中的 msgfmt 工具進行轉換編譯的動作,這部份的定義於上一層,以下是程式列表:
# Find xgettext
FIND_PROGRAM(
        XGETTEXT_PATH
        NAMES "xgettext"
        PATHS "/usr/bin"
)
IF(${XGETTEXT_PATH} STREQUAL "XGETTEXT_PATH-NOTFOUND")
        MESSAGE(STATUS 
"xgettext not found.  You will not be able to run "
'make extract_messages' in the 'po' directory.")
ELSE(${XGETTEXT_PATH} STREQUAL "XGETTEXT_PATH-NOTFOUND")
        MESSAGE(STATUS "Found xgettext: ${XGETTEXT_PATH}")
ENDIF(${XGETTEXT_PATH} STREQUAL "XGETTEXT_PATH-NOTFOUND")
雖然囉唆一點,但是比起 autotools 那些貌似簡短但難以理解的寫法,其實 CMake 的作法既有彈性且清楚。另一個專案 [cmake-modules] 則致力於維護 CMake 的延伸模組,強化 CMake 的 FindPACKAGE 功能,可在 [線上程式碼列表] 中參考其提供的 FindMsgfmt.cmake 與 MacroGeneratePoFiles.cmake (目錄: trunk/Modules/Macros/PoFiles ),與前述程式列表相仿,只是加了簡單的包裝。
由 jserv 發表於 May 19, 2008 02:33 PM
迴響

感謝大大
這樣我的ghunter會更完整
回家再好好的把這個部份搞定

huki 發表於 May 19, 2008 06:20 PM
發表迴響









記住我的資訊?