m4, autoconf
http://www.gnu.org/software/m4/m4.html
GNU M4 is an implementation of the traditional Unix macro processor. It is mostly SVR4 compatible although it has some extensions (for example, handling more than 9 positional parameters to macros). GNU M4 also has built-in functions for including files, running shell commands, doing arithmetic, etc.
GNU M4 is a macro processor in the sense that it copies its input to the output expanding macros as it goes. Macros are either builtin or user-defined and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running UNIX commands, doing integer arithmetic, manipulating text in various ways, recursion etc... m4 can be used either as a front-end to a compiler or as a macro processor in its own right.
M4是一个Unix宏处理器, 用于将输入赋值到模板中并展开成输出. 可以使用简单的运算和字符串操作, 主要用于编译前的预处理. 主要是因为autoconf而使用. M4存在于各种类Unix系统中, 并且已经被POSIX(Portable Operating System Interface)标准化 .
http://www.gnu.org/software/autoconf/autoconf.html
Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages. These scripts can adapt the packages to many kinds of UNIX-like systems without manual user intervention. Autoconf creates a configuration script for a package from a template file that lists the operating system features that the package can use, in the form of M4 macro calls.
Autoconf 是一个可扩展的M4宏集合, 用于产生shell脚本来自动配置软件源码. 这些脚本可以自动适配多种类Unix的操作系统. 需要与automake, libtool合用产生可移植的软件.
在软件发布时, 如果只是使用Autoconf, 涉及的文件和步骤如下
your source files --> [autoscan*] --> [configure.scan] --> configure.ac configure.ac --. | .------> autoconf* -----> configure [aclocal.m4] --+---+ | `-----> [autoheader*] --> [config.h.in] [acsite.m4] ---' Makefile.in
如果还使用了Automake, 则需要额外的一些文件:
[acinclude.m4] --. | [local macros] --+--> aclocal* --> aclocal.m4 | configure.ac ----' configure.ac --. +--> automake* --> Makefile.in Makefile.am ---'
在软件配置过程中涉及的文件:
.-------------> [config.cache] configure* ------------+-------------> config.log | [config.h.in] -. v .-> [config.h] -. +--> config.status* -+ +--> make* Makefile.in ---' `-> Makefile ---'
流程图
Autoconf 语法
Autoconf 语言与其他语言不一样, 其对待文本和代码是一样的所以需要用quotation来区分文本.
在调用宏方法时, 宏名称和括号之间不能有空格, 例如
AC_INIT ([oops], [1.0]) # 错误 AC_INIT([hello], [1.0]) # 正确
参数应当由引用符号'['和']'包围, 并使用逗号分隔. 除非被引用符号包围, 参数前的空格和换行都会被忽略, 所以对所有可能包含宏名称, 逗号, 括号, 和前置空格的参数, 都应当加上引用符号. 例如
AC_CHECK_HEADER([stdio.h], [AC_DEFINE([HAVE_STDIO_H], [1], [Define to 1 if you have <stdio.h>.])], [AC_MSG_ERROR([sorry, can't do anything for you])])
上面是安全的做法, 也可以简化为
AC_CHECK_HEADER([stdio.h], [AC_DEFINE([HAVE_STDIO_H], 1, [Define to 1 if you have <stdio.h>.])], [AC_MSG_ERROR([sorry, can't do anything for you])])
因为'1'不可能是一个宏调用. 这里 AC_MSG_ERROR 的参数必须加引用符号, 否则它的逗号就会被误认为是参数分隔符. AC_CHECK_HEADER的第二和第三个参数必须用引用符号, 因为它们包含宏调用. ‘HAVE_STDIO_H’, ‘stdio.h’, 和 ‘Define to 1 if you have <stdio.h>.’ 这三个参数不需要引用符号, 但是如果你恰巧定义了一个名称为'Define'或'stdio'的宏, 你就需要加上引用符号了. 谨慎的Autoconf用户会保留引用符号, 但是也有很多用户觉得麻烦, 写成:
AC_CHECK_HEADER(stdio.h, [AC_DEFINE(HAVE_STDIO_H, 1, [Define to 1 if you have <stdio.h>.])], [AC_MSG_ERROR([sorry, can't do anything for you])])
这是安全的, 只要你保持良好的命名规则, 不要使用‘HAVE_STDIO_H’, ‘stdio’, or ‘h’这样的名称. 虽然省略‘Define to 1 if you have <stdio.h>.’的引用符号在这里也是安全的, 但是这个做法不推荐, 因为消息字符串包含逗号的可能性很大. 下面的例子就是错误并且不安全的:
AC_CHECK_HEADER(stdio.h, AC_DEFINE(HAVE_STDIO_H, 1, Define to 1 if you have <stdio.h>.), AC_MSG_ERROR([sorry, can't do anything for you]))
In other cases, you may have to use text that also resembles a macro call. You must quote that text even when it is not passed as a macro argument. For example, these two approaches in configure.ac (quoting just the potential problems, or quoting the entire line) will protect your script in case autoconf ever adds a macro AC_DC:
echo "Hard rock was here! --[AC_DC]"
[echo "Hard rock was here! --AC_DC"]
which results in this text in configure:
echo "Hard rock was here! --AC_DC"
echo "Hard rock was here! --AC_DC"
When you use the same text in a macro argument, you must therefore have an extra quotation level (since one is stripped away by the macro substitution). In general, then, it is a good idea to use double quoting for all literal string arguments, either around just the problematic portions, or over the entire argument:
AC_MSG_WARN([[AC_DC] stinks --Iron Maiden])
AC_MSG_WARN([[AC_DC stinks --Iron Maiden]])
However, the above example triggers a warning about a possibly unexpanded macro when running autoconf, because it collides with the namespace of macros reserved for the Autoconf language. To be really safe, you can use additional escaping (either a quadrigraph, or creative shell constructs) to silence that particular warning:
echo "Hard rock was here! --AC""_DC"
AC_MSG_WARN([[AC@&t@_DC stinks --Iron Maiden]])
You are now able to understand one of the constructs of Autoconf that has been continually misunderstood... The rule of thumb is that whenever you expect macro expansion, expect quote expansion; i.e., expect one level of quotes to be lost. For instance:
AC_COMPILE_IFELSE(AC_LANG_SOURCE([char b[10];]), [],
[AC_MSG_ERROR([you lose])])
is incorrect: here, the first argument of AC_LANG_SOURCE is ‘char b[10];’ and is expanded once, which results in ‘char b10;’; and the AC_LANG_SOURCE is also expanded prior to being passed to AC_COMPILE_IFELSE. (There was an idiom common in Autoconf's past to address this issue via the M4 changequote primitive, but do not use it!) Let's take a closer look: the author meant the first argument to be understood as a literal, and therefore it must be quoted twice; likewise, the intermediate AC_LANG_SOURCE macro should be quoted once so that it is only expanded after the rest of the body of AC_COMPILE_IFELSE is in place:
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char b[10];]])], [],
[AC_MSG_ERROR([you lose])])
Voilà, you actually produce ‘char b[10];’ this time!
On the other hand, descriptions (e.g., the last parameter of AC_DEFINE or AS_HELP_STRING) are not literals—they are subject to line breaking, for example—and should not be double quoted. Even if these descriptions are short and are not actually broken, double quoting them yields weird results.
Some macros take optional arguments, which this documentation represents as [arg] (not to be confused with the quote characters). You may just leave them empty, or use ‘[]’ to make the emptiness of the argument explicit, or you may simply omit the trailing commas. The three lines below are equivalent:
AC_CHECK_HEADERS([stdio.h], [], [], [])
AC_CHECK_HEADERS([stdio.h],,,)
AC_CHECK_HEADERS([stdio.h])
It is best to put each macro call on its own line in configure.ac. Most of the macros don't add extra newlines; they rely on the newline after the macro call to terminate the commands. This approach makes the generated configure script a little easier to read by not inserting lots of blank lines. It is generally safe to set shell variables on the same line as a macro call, because the shell allows assignments without intervening newlines.
You can include comments in configure.ac files by starting them with the ‘#’. For example, it is helpful to begin configure.ac files with a line like this:
# Process this file with autoconf to produce a configure script.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
2016-10-30 grep 命令过滤配置文件中的注释和空行
2015-10-30 Linux的chattr与lsattr命令