linux程序处理po多语言的两种脚本配置方式
1.在configure.ac里面配置ALL_LINGUAS,然后调用AM_GLIB_GNU_GETTEXT
2.在po目录下面放置LINGUAS文件,由gettextize来生成并处理
1.在configure.ac里面配置ALL_LINGUAS,然后调用AM_GLIB_GNU_GETTEXT
2.在po目录下面放置LINGUAS文件,由gettextize来生成并处理
stamp-po是表示po文件是否有更新,有更新,则重新编译一次
gettextize在各种场合都可以使用,用于支持多语言开发
glib-gettextize运行后,会修改po/Makefile.in.in文件,导致后续都必须运行glib-gettextize
gettextize会生成m4目录以及config.rpath一些脚本,如果po/Makefile.in.in不存在时,会生成这个文件
glib-gettextize会修改po/Makefile.in.in文件
aclocal会生成大量脚本,生成aclocal.m4等,在没有m4目录时同时修改configure.ac,在其中增加
输出po/Makefile.in(此时configure.ac不能有po/Makefile.in的输出,否则会报错)
xfce4 dev tools实际上基本是封装了一些autoconf的宏函数
比如XDT_I18N:
AC_DEFUN([XDT_I18N],
[
dnl Substitute GETTEXT_PACKAGE variable
GETTEXT_PACKAGE=m4_default([$2], [AC_PACKAGE_TARNAME()])
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [Name of default gettext domain])
AC_SUBST([GETTEXT_PACKAGE])
dnl gettext and stuff
ALL_LINGUAS="$1"AM_GLIB_GNU_GETTEXT()
dnl This is required on some Linux systems
AC_CHECK_FUNC([bind_textdomain_codeset])
dnl Determine where toinstalllocale files
AC_MSG_CHECKING([forlocales directory])
AC_ARG_WITH([locales-dir],
[
AC_HELP_STRING([--with-locales-dir=DIR], [Install locales into DIR])
], [localedir=$withval],
[if test x"$CATOBJEXT" = x".mo"; thenlocaledir=$libdir/localeelselocaledir=$datadir/localefi])
AC_MSG_RESULT([$localedir])
AC_SUBST([localedir])
dnl Determine additional xgettext flags
AC_MSG_CHECKING([foradditional xgettext flags])if test x"$XGETTEXT_ARGS" = x""; thenXGETTEXT_ARGS="--keyword=Q_ --from-code=UTF-8";elseXGETTEXT_ARGS="$XGETTEXT_ARGS --keyword=Q_ --from-code=UTF-8";fiAC_SUBST([XGETTEXT_ARGS])
AC_MSG_RESULT([$XGETTEXT_ARGS])
])
主要内容就在前面五行的实现:
GETTEXT_PACKAGE=m4_default([$2], [AC_PACKAGE_TARNAME()])
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [Name of default gettext domain])
AC_SUBST([GETTEXT_PACKAGE])
ALL_LINGUAS="$1"AM_GLIB_GNU_GETTEXT()
定义了GETTEXT_PACKAGE宏,然后将参数1传递给ALL_LINGUAS
而XDT_CHECK_PACKAGE的实现也很简单,基本上就是封装PKG_CONFIG
AC_DEFUN([XDT_CHECK_PACKAGE],
[
XDT_PROG_PKG_CONFIG()
AC_MSG_CHECKING([for $2 >= $3])if $PKG_CONFIG "--atleast-version=$3" "$2" >/dev/null 2>&1; then$1_VERSION=`$PKG_CONFIG --modversion "$2"`
AC_MSG_RESULT([$$1_VERSION])
AC_MSG_CHECKING([$1_CFLAGS])
$1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
AC_MSG_RESULT([$$1_CFLAGS])
AC_MSG_CHECKING([$1_LIBS])
$1_LIBS=`$PKG_CONFIG --libs "$2"`
AC_MSG_RESULT([$$1_LIBS])
$1_REQUIRED_VERSION=$3AC_SUBST([$1_VERSION])
AC_SUBST([$1_CFLAGS])
AC_SUBST([$1_LIBS])
AC_SUBST([$1_REQUIRED_VERSION])
ifelse([$4], , , [$4])elif $PKG_CONFIG --exists "$2" >/dev/null 2>&1; thenxdt_cv_version=`$PKG_CONFIG --modversion "$2"`
AC_MSG_RESULT([found, but $xdt_cv_version])
ifelse([$5], ,
[echo "*** The required package $2 was found on your system," echo "*** but the installed version ($xdt_cv_version) is too old." echo "*** Please upgrade $2 to atleast version $3, or adjust" echo "*** the PKG_CONFIG_PATH environment variable if you installed" echo "*** the new version of the package in a nonstandard prefix so" echo "*** pkg-config is able to find it."exit1], [$5])elseAC_MSG_RESULT([not found])
ifelse([$5], ,
[echo "*** The required package $2 was not found on your system." echo "*** Please install $2 (atleast version $3) or adjust" echo "*** the PKG_CONFIG_PATH environment variable if you" echo "*** installed the package in a nonstandard prefix so that" echo "*** pkg-config is able to find it."exit1], [$5])fi])
XDT_PROG_PKG_CONFIG检测系统中是否存在PKG_CONFIG,如果
存在,则通过pkg-config来配置CFLAGS/LIBS等4个变量
由于systemd合并udev之后,咱们就不能再用udev的规则来挂接移动硬盘了
所以决定利用dbus的机制来规避systemd对于cgroup控制导致的挂接移动硬盘问题
开发一个简单的dbus服务器,其功能很简单,接收从客户端过来的命令参数,然后调用system()来执行
这当然是有安全问题的,但在自己的机器使用,谁管呢
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dbus/dbus.h> #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-bindings.h> #include <glib-object.h> #include "dbus_exec_cmd.h" #include "simple_exec_glue.h" /* Generate the GObject boilerplate */ G_DEFINE_TYPE(DbusExecCmd, dbus_exec_cmd, G_TYPE_OBJECT) GQuark simple_exec_error (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("simple_exec_error"); return quark; } /* Class init */ static void dbus_exec_cmd_class_init (DbusExecCmdClass *dbus_exec_cmd_class) { dbus_g_object_type_install_info (G_OBJECT_CLASS_TYPE (dbus_exec_cmd_class), &dbus_glib_simple_exec_object_info); } /* Instance init */ static void dbus_exec_cmd_init (DbusExecCmd *dbus_exec_cmd) { } gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error) { int status; g_print ("[Simple Dbus Exec]Start to execute: %s\n", cmd_str); status = system(cmd_str); if (0 != status) { /* We have an error, set the gerror */ g_set_error (error, simple_exec_error(), 1, "[Simple Dbus Exec]fail to execute command:%s\n", cmd_str); g_warning("[Simple Dbus Exec]fail to execute: %s, error: %d\n", cmd_str, status); return FALSE; } if(WIFEXITED(status)) { g_warning("normal termination, exit status = %d\n", WEXITSTATUS(status)); //鍙栧緱cmdstring鎵ц缁撴灉 } else if(WIFSIGNALED(status)) { g_warning("abnormal termination,signal number =%d\n", WTERMSIG(status)); //濡傛灉cmdstring琚俊鍙蜂腑鏂紝鍙栧緱淇″彿鍊? } else if(WIFSTOPPED(status)) { g_warning("process stopped, signal number =%d\n", WSTOPSIG(status)); //濡傛灉cmdstring琚俊鍙锋殏鍋滄墽琛岋紝鍙栧緱淇″彿鍊? } g_print ("[Simple Dbus Exec]Finish to execute command\n"); return TRUE; } static void die (const char *prefix, GError *error) { g_error("%s: %s", prefix, error->message); g_error_free (error); exit(1); } #define SIMPLE_EXEC_SERVICE_NAME "org.dbus_exec_cmd.simple_exec" int main (int argc, char **argv) { GMainLoop *loop; DBusGConnection *connection; GError *error = NULL; GObject *obj; DBusGProxy *driver_proxy; guint32 request_name_ret; g_type_init (); if (!g_thread_supported ()) g_thread_init (NULL); dbus_g_thread_init (); loop = g_main_loop_new (NULL, FALSE); g_print ("[Simple Dbus Exec]Launching Simple Exec Object\n"); /* Obtain a connection to the session bus */ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); if (connection == NULL) { die ("[Simple Dbus Exec]Failed to open connection to bus", error); } obj = g_object_new (DBUS_EXEC_CMD_TYPE, NULL); dbus_g_connection_register_g_object (connection, "/org/dbus_exec_cmd/simple_exec", obj); driver_proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); if (!org_freedesktop_DBus_request_name (driver_proxy, SIMPLE_EXEC_SERVICE_NAME, 0, &request_name_ret, &error)) { die ("[Simple Dbus Exec]Failed to get name", error); } if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { g_error ("[Simple Dbus Exec]Got result code %u from requesting name", request_name_ret); exit (1); } g_print ("[Simple Dbus Exec]GLib service has name: [%s]\n", SIMPLE_EXEC_SERVICE_NAME); g_print ("[Simple Dbus Exec]GLib service entering main loop\n"); g_main_loop_run (loop); g_print ("[Simple Dbus Exec]Successfully completed %s\n", argv[0]); return 0; }
#include <glib-object.h> typedef struct DbusExecCmd DbusExecCmd; typedef struct DbusExecCmdClass DbusExecCmdClass; GType dbus_exec_cmd_get_type (void); struct DbusExecCmd { GObject parent; }; struct DbusExecCmdClass { GObjectClass parent; }; #define DBUS_EXEC_CMD_TYPE (dbus_exec_cmd_get_type ()) #define DBUS_EXEC_CMD(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), DBUS_EXEC_CMD_TYPE, DbusExecCmd)) #define DBUS_EXEC_CMD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass)) #define IS_DBUS_EXEC_CMD(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), DBUS_EXEC_CMD_TYPE)) #define IS_DBUS_EXEC_CMD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DBUS_EXEC_CMD_TYPE)) #define DBUS_EXEC_CMD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DBUS_EXEC_CMD_TYPE, DbusExecCmdClass)) typedef enum { ECHO_ERROR_GENERIC } DbusExecCmdError; gboolean simple_exec_command(DbusExecCmd *exec_cmd, const char* cmd_str, GError **error);
<?xml version="1.0" encoding="UTF-8" ?> <node name="/org/dbus_exec_cmd/simple_exec"> <interface name='org.dbus_exec_cmd.simple_exec'> <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="simple"/> <method name='exec_command'> <arg type='s' name='cmd_str' direction='in' /> </method> </interface> </node>
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy user="root"> <allow own="org.dbus_exec_cmd.simple_exec"/> </policy> <!-- Allow anyone to invoke methods --> <policy user="root"> <allow send_destination="org.dbus_exec_cmd.simple_exec"/> <allow receive_sender="org.dbus_exec_cmd.simple_exec"/> </policy> </busconfig>
[D-BUS Service] Name=org.dbus_exec_cmd.simple_exec Exec=@bindir@/simple_exec User=root