zoukankan      html  css  js  c++  java
  • Automake使用(中级)

    工程地址

    automake语言国际化

    最初工程目录结构

    $ ls -l
    total 16
    drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 build-aux
    drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 m4
    drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 po
    drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 src
    $ ls -l src/
    total 4
    -rw-rw-r--. 1 fedora fedora 572 May 10 10:38 main.cpp
    

    源文件剖析

    $ cat main.cpp
    #include <iostream>
    #include <stdio.h>
    #include "config.h"
    #include "gettext.h"
    #define _(String) gettext (String)
    
    int main()
    {
        std::cout << PACKAGE << std::endl;
        std::cout << LOCALEDIR << std::endl;
            setlocale(LC_ALL, "");
        std::cout << "===================" << std::endl;
        std::cout << bindtextdomain(PACKAGE, LOCALEDIR) << std::endl;
        std::cout << bind_textdomain_codeset(PACKAGE, "UTF-8") << std::endl;
        std::cout << textdomain(PACKAGE) << std::endl;
    
        std::cout << _("just test gettext!") << std::endl;
        printf(_("Hello Getext!
    "));
    }
    

    可以使用PACKAGE宏

    #include "config.h"
    

    使用gettext,使用方式是用 _() 来包含需要参与翻译的字符串

    #include "gettext.h"
    #define _(String) gettext (String)
    

    LOCALEDIR/LANG/LC_MESSAGE 目录下去寻找消息域 PACKAGE.mo ,指定消息域 PACKAGE 的编码格式为 utf8 ,然后设置当前环境的消息域为 PACKAGE 。注意LINUX环境下 LOCALEDIR 尽量使用绝对路径,因为如果使用相对路径,相对的是命令执行时的路径,而不是可执行文件所在的路径,即如果可执行文件被安装在bin目录下, LOCALEDIR 并不一定是 ./../share/locale ,而且要保持 configure.ac 中定义的的 GETTEXT_PACKAGE 的值和 bindtextdomain/bind_textdomain_codeset/textdomain 所使用的消息域名保持一致

    bindtextdomain(PACKAGE, LOCALEDIR)
    bind_textdomain_codeset(PACKAGE, "UTF-8")
    textdomain(PACKAGE)
    

    将工程改造成automake

    运行autoscan

    生成configure.scan文件,然后将此文件后缀改为.ac

    $ autoscan
    $ mv configure.scan configure.ac
    $ git add configure.ac
    $ git commit -m "autoscan"
    

    修改configure.ac文件

    后面autoconf将根据此文件生成最终的configure脚本

    $ vim configure.ac
    $ git add configure.ac
    $ git commit -m "Modify configure.ac"
    $ git diff --cached 1c0b2a660b2878f23d287f3ab0b5c93b063c521c
    diff --git a/configure.ac b/configure.ac
    index efcac1b..dce09b7 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -1,13 +1,66 @@
     #                                               -*- Autoconf -*-
     # Process this file with autoconf to produce a configure script.
     
    +# autoconf版本 
     AC_PREREQ([2.69])
    -AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
    +# 初始化包信息,将会自动生成PACKAGE_NAME、PACKAGE_VERSION、PACKAGE_BUGREPORT宏
    +AC_INIT([gettext], [1.0], [fwdssg.love@163.com])
    +# 通过检测目录中必定存在的文件来判断目录是否存在
     AC_CONFIG_SRCDIR([src/main.cpp])
    +# 生成config.h文件保存configure.ac定义的宏,此文件可被源文件包含
     AC_CONFIG_HEADERS([config.h])
    +# 用来存储本地宏文件,.m4的文件都将被保存进此目录,acloacl命令会自动创建此目录
    +AC_CONFIG_MACRO_DIRS([m4])
    +# 用来存储一些辅助脚本文件
    +AC_CONFIG_AUX_DIR([build-aux])
    +# 初始化automake
    +AM_INIT_AUTOMAKE([subdir-objects -Wno-portability])
    +# 初始化gettext
    +AM_GNU_GETTEXT([external])
    +AM_GNU_GETTEXT_VERSION([0.19.6])
    +# 初始化libtool
    +IT_PROG_INTLTOOL([0.35.0])
    +
    +# 标准的平台检测脚本,将生成WIXL_ARCH和OS_WIN32宏,可在Makefile.am中使用
    +AC_MSG_CHECKING([for native Win32])
    +case "$host_os" in
    +     *mingw*|*cygwin*)
    +        os_win32=yes
    +        case "$host" in
    +            amd64*|x86_64*)
    +                WIXL_ARCH="x64"
    +            ;;
    +            *)
    +                WIXL_ARCH="x86"
    +            ;;
    +        esac
    +        AC_SUBST(WIXL_ARCH)
    +        ;;
    +     *)
    +        os_win32=no
    +        ;;
    +esac
    +AC_MSG_RESULT([$os_win32])
    +AM_CONDITIONAL([OS_WIN32],[test "$os_win32" = "yes"])
    +
    +# windows下资源生成工具检测(此项目非必须,仅做演示)
    +AS_IF([test "x$os_win32" = "xyes"], [
    +     AC_CHECK_TOOL(WINDRES, [windres])
    +
    +     if test -z "$WINDRES" ; then
    +       AC_MSG_ERROR("windres is required to compile tropolink-gtk on this platform")
    +     fi
    +])
     
     # Checks for programs.
     AC_PROG_CXX
    +# 初始化要连接的obj目录
    +AC_CONFIG_LIBOBJ_DIR([src])
    +
    +# 初始化mo文件名,也是bindtextdomain搜索时候的domainname
    +GETTEXT_PACKAGE=$PACKAGE
    +AC_SUBST(GETTEXT_PACKAGE)
    +AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],"$GETTEXT_PACKAGE", [GETTEXT package name])
     
     # Checks for libraries.
     
    @@ -18,4 +71,9 @@ AC_PROG_CXX
     # Checks for library functions.
     AC_CHECK_FUNCS([setlocale])
     
    +# 设置运行configure后需要生成的文件,需要编写对应的.in文件,即需要生成Makefile,则必须存在Makefile.in文件,它们将被config.status使用用来生成Makefile
    +AC_CONFIG_FILES([ 
    +    Makefile
    +    src/Makefile
    +])
     AC_OUTPUT
    

    运行libtoolize

    生成libtool相关辅助文件,ltmain.sh和libtool.m4等宏文件

    $ libtoolize
    $ git status
    $ git add --all
    $ git commit -m "libtoolize"
    

    运行gettextize

    生成国际化所需相关文件

    $ gettextize
    $ git status
    $ git diff configure.ac
    diff --git a/configure.ac b/configure.ac
    index dce09b7..a5b16a8 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -17,7 +17,7 @@ AC_CONFIG_AUX_DIR([build-aux])
     AM_INIT_AUTOMAKE([subdir-objects -Wno-portability])
     # 初始化gettext
     AM_GNU_GETTEXT([external])
    -AM_GNU_GETTEXT_VERSION([0.19.6])
    +AM_GNU_GETTEXT_VERSION([0.19.7])
     # 初始化libtool
     IT_PROG_INTLTOOL([0.35.0])
     
    @@ -72,7 +72,7 @@ AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],"$GETTEXT_PACKAGE", [GETTEXT package name])
     AC_CHECK_FUNCS([setlocale])
     
     # 设置运行configure后需要生成的文件,需要编写对应的.in文件,即需要生成Makefile,则必须存在Makefile.in文件,它们将被config.status使用用来生成Makefile
    -AC_CONFIG_FILES([ 
    +AC_CONFIG_FILES([  po/Makefile.in
         Makefile
         src/Makefile
     ])
    $ rm -rf configure.ac~
    $ git add --all
    $ git commit -m
    

    运行aclocal

    生成autoconf所需的宏文件aclocal.m4

    $ aclocal
    $ git status
    $ git add aclocal.m4
    $ git commit -m "aclocal.m4"
    

    运行autoconf

    根据configure.ac生成configure脚本

    $ autoconf
    $ git status
    $ git add configure
    $ git commit -m "autoconf"
    

    运行autoheader

    生成 config.h.in 文件,用于生成 config.h 文件,此文件保存了configure.ac中定义的宏,可被程序使用

    $ autoheader
    $ git status
    $ git add config.h.in
    $ git commit -m "autoheader"
    

    编写Makefile.am

    Makefile.am注解
    作用
    SUBDIRS 存在Makefile.am的子目录
    DISTCLEANFILES 执行 make distclean 要被删除的文件
    MAINTAINERCLEANFILES 执行 make maintainer-clean 要被删除的文件
    dist-hook 执行 make dist 时将被调用的命令
    EXTRA_DIST 不会被编译,但是执行 make dist 又需要被打包的文件
    bin_PROGRAMS 编译生成的可执行文件名
    XX_LDADD 需要链接一些特殊的obj或者库文件,例如由.rc生成的.o文件
    XX_CPPFLAGS -I -D 之类的编译参数
    XX_LDFLAGS -L 之类的链接参数
    _LTLIBRARIES 生成libtool库
    XX_la_LIBADD 生成libtool库需要链接的文件
    XX_LDFLAGS 生成libtool库的链接参数
    顶层目录的Makefile.am
    • Makefile.ambuild-aux/gitlog-to-changelog 以及 AUTHORS.in 取自 Virt Viewer ,可以当做模板来使用
    • 一般情况下我们只需要根据 configure.acAC_CONFIG_FILES 来修改 Makefile.am 模板的 SUBDIRS 来决定需要生成Makefile的子目录,每个Makefile.am只需要包含子目录即可,如果有嵌套目录需要生成Makefile,则在子目录的Makefile.am设置 SUBDIRS
    $ cat Makefile.am
    NULL =
    
    ACLOCAL_AMFLAGS = -I m4
    
    SUBDIRS = src po
    
    INTLTOOL_FILES =                
        intltool-extract.in            
        intltool-merge.in            
        intltool-update.in            
        $(NULL)
    
    DISTCLEANFILES =                
        intltool-extract            
        intltool-merge                
        intltool-update                
        $(NULL)
    
    EXTRA_DIST = build-aux/config.rpath                     
        $(INTLTOOL_FILES)            
        build-aux/gitlog-to-changelog        
        AUTHORS.in                
        autogen.sh                
        $(NULL)
    
    MAINTAINERCLEANFILES =                
        aclocal.m4                
        config.h.in                
        m4/intltool.m4                
        m4/libtool.m4                
        m4/ltoptions.m4                
        m4/ltsugar.m4                
        m4/ltversion.m4                
        m4/lt~obsolete.m4            
        build-aux/ar-lib            
        build-aux/compile            
        build-aux/config.guess            
        build-aux/config.rpath            
        build-aux/config.sub            
        build-aux/depcomp            
        build-aux/install-sh            
        build-aux/ltmain.sh            
        build-aux/missing            
        po/Makefile.in.in            
        $(NULL)
    
    DISTCLEAN_FILES =                
        intltool-extract            
        intltool-merge                
        intltool-update                
        $(NULL)
    
    dist-hook: gen-ChangeLog gen-AUTHORS
    
    # Generate the ChangeLog file (with all entries since the switch to git)
    # and insert it into the directory we're about to use to create a tarball.
    
    .PHONY: gen-ChangeLog gen-AUTHORS
    
    gen-ChangeLog:
        if test -d .git || test -d ../.git; then        
          $(top_srcdir)/build-aux/gitlog-to-changelog        
            > $(distdir)/cl-t;                    
          rm -f $(distdir)/ChangeLog;                
          mv $(distdir)/cl-t $(distdir)/ChangeLog;        
        fi
    
    gen-AUTHORS:
        $(AM_V_GEN)if test -d $(srcdir)/.git; then                      
           out="`cd $(srcdir) && git log --pretty=format:'%aN <%aE>' | sort -u`" && 
           perl -p -e "s/#authorslist#// and print '$$out'"            
             < $(srcdir)/AUTHORS.in > $(distdir)/AUTHORS-tmp &&        
           mv -f $(distdir)/AUTHORS-tmp $(distdir)/AUTHORS ;           
        fi
    
    $ git status
    $ git add AUTHORS.in Makefile.am build-aux/gitlog-to-changelog
    $ git commit -m "Top Makefile.am"
    
    src目录的Makefile.am
    $ cat Makefile.am
    NULL =
    
    bin_PROGRAMS = Gettext
    Gettext_LDADD =
    
    #
    #Gettext_CPPFLAGS = 
    #    -DLOCALEDIR=""./../share/locale"" 
    #    $(NULL)
    
    Gettext_CPPFLAGS = 
        -DLOCALEDIR=""$(localedir)"" 
        $(NULL)
    
    Gettext_CXXFLAGS = -ggdb3 -Wall -MMD  -fpermissive -g
    MAINTAINERCLEANFILES =
    
    COMMON_LIBS = 
        -lm                    
        $(NULL)
    
    COMMON_CPPFLAGS = 
        $(NULL)
    
    Gettext_SOURCES = 
            main.cpp                                
            gettext.h                
            $(NULL)
    
    Gettext_LDFLAGS = 
        $(COMMON_LIBS)                
        $(NULL)
    
    Gettext_CPPFLAGS += 
        $(COMMON_CPPFLAGS)             
        $(NULL)
    
    $ git status
    $ git add src/Makefile.am
    $ git commit -m 'src/Makefile.am'
    

    创建automake必要文件

    COPYING 文件可以从一些开源项目下面复制过来,其他文件使用 touch 命令生成

    $ git status
    $ git add AUTHORS COPYING NEWS README
    $ git commit -m "Necessery Files"
    

    运行automake

    生成 Makefile.in 文件

    $ automake -a
    $ git status
    $ git add INSTALL Makefile.in build-aux/compile build-aux/config.guess build-aux/config.sub build-aux/depcomp build-aux/install-sh build-aux/missing src/Makefile.in
    $ git commit -m "automake"
    

    编辑po/POTFILES.in文件

    填入需要进行国际化字符转换的源文件,即包含文件中包含 _() 的源文件

    $ vim POTFILES.in
    $ git add POTFILES.in
    $ git commit -m "Modify POTFILES.in"
    $ git diff --cached 3b7860256a9c58f68bbee285dd65d18905796247
    diff --git a/po/POTFILES.in b/po/POTFILES.in
    index 667e27c..1bc579b 100644
    --- a/po/POTFILES.in
    +++ b/po/POTFILES.in
    @@ -1 +1,3 @@
     # List of source files which contain translatable strings.
    +
    +src/main.cpp
    

    执行autogen.sh

    • autogen.sh 取自 Virt Viewer ,可以当做模板来使用
    • 根据实际情况修改 echo "Now type 'make' to compile Gettext." 即可
    $ cat autogen.sh
    #!/bin/sh
    # Run this to generate all the initial makefiles, etc.
    
    set -e
    
    srcdir=`dirname $0`
    test -z "$srcdir" && srcdir=.
    
    THEDIR=`pwd`
    cd $srcdir
    
    EXTRA_ARGS=""
    if test "x$1" = "x--system"; then
        shift
        prefix=/usr
        libdir=$prefix/lib
        sysconfdir=/etc
        localstatedir=/var
        if [ -d /usr/lib64 ]; then
            libdir=$prefix/lib64
        fi
        EXTRA_ARGS="--prefix=$prefix --sysconfdir=$sysconfdir --localstatedir=$localstatedir --libdir=$libdir"
    fi
    
    # Real ChangeLog/AUTHORS is auto-generated from GIT logs at
    # make dist time, but automake requires that it
    # exists at all times :-(
    touch ChangeLog AUTHORS
    
    mkdir -p m4
    autoreconf -vfi
    intltoolize --force
    
    cd $THEDIR
    
    if [ -z "$NOCONFIGURE" ]; then
        if test -z "$*" ; then
            echo "I am going to run ./configure with no arguments - if you wish "
            echo "to pass any to it, please specify them on the $0 command line."
        fi
        $srcdir/configure $EXTRA_ARGS "$@" && {
            echo
            echo "Now type 'make' to compile Gettext."
        }
    fi
    
    $ git add autogen.sh
    $ git commit -m "Add autogen.sh"
    

    生成po文件

    • 执行 make -C po/ update-po 生成程序对应的POT文件 gettext.pot
    • 在po目录下执行 msginit --locale zh_CN.utf8 生成对应语言的PO文件
    • 编辑PO文件完成翻译
    • 创建 LINGUAS 文件,并填入PO文件中的"Language"属性
    $ make -C po/ update-po
    $ cd po/
    $ msginit --locale zh_CN.utf8
    $ msginit --locale en_US.utf8
    $ vim zh_CN.po
    $ vim en_US.po
    $ touch LINGUAS
    $ vim LINGUAS
    $ cat LINGUAS
    zh_CN en_US
    

    运行make

    • 拷贝gettext.h文件到src目录
    $ sudo find / -name gettext.h 2>/dev/null
    $ cp /usr/share/gettext/gettext.h src/
    $ make
    

    测试Gettext

    $ LANG=en_US src/Gettext
    gettext
    /usr/local/share/locale
    ===================
    /usr/local/share/locale
    UTF-8
    gettext
    Amarican Gettext!
    Amarican Hello!
    $ LANG=zh_CN src/Gettext
    gettext
    /usr/local/share/locale
    ===================
    /usr/local/share/locale
    UTF-8
    gettext
    Chinese gettext!
    Chinese Hello!
    
  • 相关阅读:
    JavaScript 面向对象
    javascript中this的指向
    销售
    Java垃圾回收机制
    判断浏览器是否缩放
    pattern space and hold space of sed
    语言基础
    Python中PyQuery库的使用总结
    多个计数器在Vuex中的状态
    Sklearn
  • 原文地址:https://www.cnblogs.com/silvermagic/p/7665918.html
Copyright © 2011-2022 走看看