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!\n"));
}
可以使用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.am
、build-aux/gitlog-to-changelog
以及AUTHORS.in
取自Virt Viewer
,可以当做模板来使用- 一般情况下我们只需要根据
configure.ac
的AC_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!
Automake使用(中级)的更多相关文章
- Automake使用(高级)
工程地址 automake语言国际化 最初工程目录结构 $ ls -l total 16 drwxrwxr-x. 2 fedora fedora 4096 May 10 10:38 build-aux ...
- Python 正则表达式入门(中级篇)
Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...
- Java 进阶 hello world! - 中级程序员之路
Java 进阶 hello world! - 中级程序员之路 Java是一种跨平台的语言,号称:"一次编写,到处运行",在世界编程语言排行榜中稳居第二名(TIOBE index). ...
- 马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)
马哥linux运维初级+中级+高级 视频教程 教学视频 全套下载(近50G)目录详情:18_02_ssl协议.openssl及创建私有CA18_03_OpenSSH服务及其相关应用09_01_磁盘及文 ...
- 第4月第1天 makefile automake
1. gnu make的函数调用是$,比如 $(subst ee,EE,feet on the street) 规则中“TARGETS”可以是空格分开的多个文件名 a all: echo $(subs ...
- codefordream 关于js中级训练
中级训练接着就紧锣密鼓的开始了. 首先是关于变量,变量的作用是给一个数据值标注名称. 注:JavaScript中变量名,函数名,参数名的命名规范:至少由字母,下划线,美元符号,数字其中的一种组成,但不 ...
- PHP笔记(PHP中级篇)
初级了解PHP的语法,中级就要学习PHP操作DateBase以及各种复杂的实现了! 文件系统处理 作用: 项目需要 长时间保存数据 服务器中文件操作 特点 都是使用系统函数完成的 基于Linux/Un ...
- 利用 autoconf 和 automake 生成 Makefile 文件
一.相关概念的介绍 什么是 Makefile?怎么书写 Makefile?竟然有工具可以自动生成 Makefile?怎么生成啊?开始的时候,我有这么多疑问,所以,必须得先把基本的概念搞个清楚. 1.M ...
- linux下使用automake工具自动生成makefile文件
linux环境下,当项目工程很大的时候,编译的过程很复杂,所以需要使用make工具,自动进行编译安装,但是手写makefile文件比较复杂,所幸在GNU的计划中,设计出了一种叫做Autoconf/Au ...
随机推荐
- DB Migrations更新数据库命令
在项目迭代的过程中,数据库结构常常需要跟随业务需求的变化做出调整,尤其在迭代的初期阶段,加一个字段减一个字段的需求更是家常便饭.在小型团队中,往往是负责开发功能模块的程序员在完成本地开发环境数据库的变 ...
- 基于GeoEvent Processor的物联网应用案例赏析
1 技术路线 下面全部应用,都採用ArcGIS for Server,结合GeoEvent产品(为一款物联网实时数据集成处理产品)开发完毕. 2 应用场景 1.1 物联网实时态势感知 1.1.1 ...
- win7下搭建nginx+php的开发环境(转)
在win7下用的是IIS做web服务器,但近来因项目需求的原因,需要在服务器遇到404错误的时候自动做转向(不是在客户端的跳转,而是在服务器收到客户端请求去某目录下读取文件返回时,如果发现目录或目录下 ...
- php+mysql 安全
Php注入攻击是现今最流行的攻击方式,依靠它强大的灵活性吸引了广大黑迷. 在上一期的<php安全与注射专题>中林.linx主要讲述了php程序的各种漏洞,也讲到了php+mysql注入的问 ...
- Map总结--HashMap/HashTable/TreeMap/WeakHashMap使用场景分析(转)
首先看下Map的框架图 1.Map概述 1.Map是键值对映射的抽象接口 2.AbstractMap实现了Map中绝大部分的函数接口,它减少了“Map实现类”的重复编码 3.SortedMap有序的“ ...
- vim中跳到第一行和最后一行
底线命令模式 :0或:1跳到文件第一行 :$跳到文件最后一行 命令模式 gg跳到第一行 shift+g跳到文件最后一行
- 转载:SPFA算法学习
转载地址:http://www.cnblogs.com/scau20110726/archive/2012/11/18/2776124.html 粗略讲讲SPFA算法的原理,SPFA算法是1994年西 ...
- Appium——api常用函数
appium常用函数介绍: 获取页面信息: 1. def get_current_activity(cls, driver): ''' 获取当前页面的activity :param drive ...
- Kbuntu16.04添加工作空间
工作空间是一个非常方便的功能,可以让开发者每次只聚焦一个屏幕,又能在各个空间中来回切换.有一种屏幕被扩展的感觉. Kbuntu默认只有一个工作空间,需要按如下方式添加: System settings ...
- RQNOJ 140 分配时间:dp
题目链接:https://www.rqnoj.cn/problem/140 题意: 小王参加的考试是几门科目的试卷放在一起考,一共给t分钟来做. 他现在已经知道第i门科目花k分钟可以拿到w[i][k] ...