英语法语西班牙语

Ad


OnWorks 网站图标

metaconfig - 云端在线

通过 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器在 OnWorks 免费托管服务提供商中运行元配置

这是可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行的命令 metaconfig,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器

程序:

您的姓名


metaconfig - 一个配置脚本生成器

概要


元配置 [-dhkmostvwGMV ] [-L DIR ]

商品描述


元配置 是一个生成配置脚本的程序。 如果你不知道什么是
配置脚本是,请跳到 在线课程 本手册页的部分。 如果你想
使用方式的完整(正式)描述 元配置 及其单位,请查看
参考 部分。 以下是有识之士的快速介绍和参考
用户。

元配置 从一组操作 单位 它定义了 metaconfig 所知道的一切
可移植性。 每个单元都是独立的,不必在任何地方注册
除了包含在公共 U 目录或您的私有 U 目录中。 如果
将 dist 包(其中 metaconfig 是其中的一部分)安装在 LIB 中,然后公共 U
目录是 LIB/dist/mcon/U。 在这台机器上,LIB 目录是 /usr/share/dist。 您的
私有 U 目录(如果有)位于包的顶级目录中。
在你可以运行之前 元配置 你必须做几件事:

· 通过运行在包的顶级目录中创建一个 .package 文件 包初始化.
该程序将询问您的包裹并记住您告诉它的内容,以便
所有的 dist 程序都可以是智能的。

· 查阅词汇表(在 LIB/dist/mcon 中)并编写您的 shell 脚本和 C 程序
就元配置知道如何定义的符号而言。 你不需要告诉
metaconfig 您使用了哪些符号,因为 metaconfig 会为您计算出来。

· 生成编写 Makefile 或 shell 脚本所需的任何 .SH 脚本,这些脚本将依赖
由 Configure 定义的值。 有一个程序叫 制作SH 这会对你有所帮助
将普通脚本转换为 script.SH 模板; 一些编辑仍然需要
对生成的 .SH 文件执行以移动变量配置部分
脚本的顶部(参见由 制作SH 在您的 .SH 中
文件)。

· 在顶级目录中创建一个 MANIFEST.new 文件,列出所有文件
你的包裹。 此文件将保持私密,不会成为最终文件的一部分
分配。 (为方便起见,MANIFEST 文件将由 元配置 if
还没有 MANIFEST.new 文件。)文件名应该是每个文件的第一个字段
线。 在一些空格之后,您可以添加一个简短的评论来描述您的文件。 仅有的
源文件应该列在那里。 特殊档案 补丁级别.h (是的
由修补工具处理和维护——见 (1)) 应该是
MANIFEST.new 文件,但可能会被某些工具忽略。 根据经验,
只有 RCS 维护的文件应该列在那里, 补丁级别.h 文件正在
一个重要的例外。

· 或者,您可能希望创建一个清单文件,这将是一个导出版本
您的 MANIFEST.new。 该文件必须成为发行版的一部分,即在两者中都列出
您的 MANIFEST.new 和 MANIFEST 本身。 其中一个 元配置 单位知道这一点
文件并将强制配置执行发布检查,确保所有文件
列出了部分分布。 MANIFEST 和 MANIFEST.new 文件应该
是不同的,而不是链接。

· 将您要修改的任何 .U 文件复制到您的私有 U 目录。 任何 .U 文件
在您的私人 U 目录中将优先使用在公共 U 目录中的
目录。 例如,强制包含任何单位的一种方法是复制 End.U
文件到您的 .U 目录并添加您想要作为依赖的单元的名称
?MAKE: 行的结尾。 某些单位只能以这种方式被强制,即
Warn_*.U 和 Chk_*.U 形式的那些。 您还可以自定义某些默认值
通过将 Myinit.U 复制到包的私有 U 目录来配置变量,然后
在该单元中设置变量。

现在您已准备好运行 元配置. 这将创建一个 配置 文件,以及可选的
配置_h.SH 文件(如果您的源代码使用了 C 符号)。 生成的文件将
如有必要,自动添加到您的 MANIFEST.new 中。 不要忘记更新您的
MANIFEST 文件。

要创建新单位,请执行以下操作:

· 将一个类似的单元复制到一个新的 .U 文件中。 您选择的名称应该是
单元生成的变量,虽然这只是为了你的方便,而不是
要求。 它应该是 12 个或更少的字符,以防止文件名切割。
实际上,它应该是 10 个或更少,以便那些想要使用 RCS 的人可以拥有
一个 .U,v 结束而不切碎。 Metaconfig 使用首字母的大小写来
确定这个单元是否实际产生了任何变量,所以不要大写你的
单位名称,如果它应该产生一个 shell 变量。

· 编辑新的 .U 文件以执行您想要的操作。 第一个 ?MAKE: 行表示
依赖; 在最终列表冒号之前,该单元定义的所有变量,以及
在最后一个冒号之后是该单位所依赖的所有变量(或其他单位)。
这些列表的准确性非常重要。 如果依赖项是可选的并且
可以使用默认值,您应该在依赖项前加上“+”号。 这
除非真的需要,否则不会加载相应的单元来计算符号
由另一个单位。

· 在可能的范围内,根据定义的 shell 变量参数化您的单元
?INIT:行。 这会将变量定义向上移动到 Init.U 单元,其中
它们可以被 Myinit.U 中的定义覆盖,Myinit.U 包含在 Init.U 之后。

· 添加所需的任何 C 符号的定义作为 ?H: 行。 以开头的一行
?H:?%<: .U 文件中的 .U 文件将被添加到最终的 config.h 文件中,当且仅当
metaconfig 决定需要这个单元。 %< 代表单位名称,
如果您遵循
习俗。 始终在每个 ?H: 行上添加注释,以防变量之一
行中较早的替换开始评论而不完成它。 任何外壳
以 d_ 开头的变量可能会这样做,所以要小心。 如果省略 ?%<:,则
metaconfig 将尝试在任何之前都需要定义其定义的符号
包含在 config.h 中。

· 将词汇表定义添加为 ?S:shell 变量行和 ?C:C 行
预处理器变量。 有关示例,请参阅当前单位。 非常重要
以左对齐的符号名称开始每个条目,并以 ?C: 结束每个条目。 或者
?S:。 线。 翻译 C 预处理器符号条目的算法
config.h 注释中的词汇表取决于此。

· 确定所有你的顺序? 线条是对的。 正确的顺序是:

?RCS: 和?X: 基本上只是评论
?MAKE:元配置依赖
?Y:单元布局指令
?S:术语表外壳定义
?C:术语表 C 定义
?H: config.h 定义
?M: confmagic.h 定义
?W:想要的符号
?V:可见符号
?F:本机创建的文件
?T: 使用的临时 shell 符号
?D: 可选依赖默认值
?O:用于标记过时的单位
?LINT:metalint 提示
?INIT:shell 符号初始化

这是一个示例,用于显示行的顺序和允许的各种格式:

?RCS:$RCS-Id$
?RCS:版权信息
?RCS:$RCS-Log$
?X:
?X:一个人为的例子
?X:
?MAKE:d_one 二:三+四 五
?MAKE: -pick 添加 $@ %
?Y:默认
?S:d_one:
?S:第一个shell 符号,有条件地定义ONE。
?S:。
?S:二:
?S:第二个shell 符号,值为TWO。
?S:。
?锥体:
?C:第一个 C 符号。
?C:。
?C:二:
?C:第二个 C 符号。
?C:。
?H:#$d_one 一个 /**/
?H:#define TWO "$two"
?H:#$d_one ONE_TWO "$two"
?H:。
?M:flip:HAS_FLIP
?M:#ifndef HAS_FLIP
?M:#define 翻转(x) 翻转(x)
?米:#endif
?M:。
?W:%<:one_two
?V:p_一 p_二:p_三
?F:文件 ./ftest !tmp
?T:tmp 变量
?D:two='undef'
?LINT:改变三
?INIT:two_init='2'
:实现单元的shell代码如下
p_one='一个'
p_two='两个'
p_three=""

让我再说一遍:上面的单位定义是 一个只显示
不同的可能性。 无论如何,这样的单位没有多大用处......更多一些
此处不描述高级功能。 请参考 参考 部分了解更多
完整的信息。

· 根据需要将单元放入公共或私有U 目录。

· 重播 元配置.

· 将您的单位发送至 [电子邮件保护] (Raphael Manfredi) 包含在主副本中,
如果您认为它具有普遍意义。

为了添加要定位的新程序:

· 编辑 Loc.U,并将程序名称添加到 ?MAKE: 行(在
两个冒号)和 loclist 或 trylist(取决于程序是否
强制与否)。

· 重新运行元配置。

· 把你的单位寄给我,以包含在主副本中,如果你认为它是通用的
兴趣。

写入 .U 文件的注意事项:

* 始终使用“rm -f”,因为有些系统默认 rm 是交互式的。

* 不要使用“set -- ...”,因为“--”不适用于每个shell。 使用“设置 x ...;
转移”。

* 不要使用“unset ENV”,因为 unset 不是完全可移植的。 改为说“ENV=''”。

* 由于 Eunice 系统,总是使用 echo " "(带空格)。

* 仅使用 test 使用 -r、-w、-f 或 -d,因为它们是唯一的便携式开关。 在
特别是,避免“test -x”。

* 仅使用 V7 附带的程序,以便您知道每个人都拥有它们。

* 当你想有条件地 grep 时使用 $contains,因为不是所有的 grep 都返回一个
合理的状态。 确保使用'>/dev/null 将输出重定向到/dev/null
2>&1'。

* 使用“if test”而不是“if [...]”,因为不是每个 sh 都知道后一种结构。

* 使用 myread 脚本进行输入,以便他们可以进行 shell 转义和默认
评估。 一般形式是

案例“$grimble”在
'') dflt=452;;
*) dflt="$grimble";;
ESAC
rp='你有多少个格子?
. ./我的阅读
grimble="$ans"

* 在请求文件路径名时使用 getfile 脚本以便有可选的
~名称扩展和健全性检查。 有关完整说明,请参阅 Getfile.U 单元。

* 总是放一个

$开始

在每个生成的脚本的顶部,这些脚本将被启动或由
配置.

* 永远不要假设常见的 UNIX 主义,例如目标文件以 .o
库名以 .a。 使用 $_o$_a 变量代替(见
Unix.U)。

* 在进行编译-链接-执行测试时,总是这样写:

$cc $ccflags $ldflags try.c -o 尝试 $libs

因为有些系统要求在编译之前指定链接标志
目标(尾随链接库除外)。

* 通过使用“>&4”重定向输出,在文件描述符#4 上发布重要消息。
只有这些消息才会出现 -s 开关被赋予 配置
命令行(静默模式)。

* 总是尝试以最具体的方式确定一个特征是否存在——不要
当你可以 grep libc 时说“if bsd”。 有很多混合系统,而且
每个功能都应该独立存在或下降。

* 始终尝试以最一般的方式确定特征是否存在,以便
其他软件包可以使用您的设备。

* 如有疑问,请设置默认值并询问。 不要假设任何事情。

* 如果您认为用户是错的,请承认他可能是对的。 为了
例如,他可能在与他将要使用的系统不同的系统上运行配置
最终产品上。

Metaconfig 会在您的目录中保留以下名称,如果您使用这样的名称
可能会被破坏或产生其他不可预见的影响:

。公吨/*
配置
通缉
过时的
配置
配置_h.SH
配置文件
你/*
清单.new

此外,Configure 可能会在它运行的目录中破坏这些名称:

U/*
配置文件
配置文件

配置


以下选项被识别 元配置:

-d 开启调试模式。 除非您正在调试,否则不是很有用 元配置
本身。

-h 打印帮助信息并退出。

-k 保留临时目录,以便您可以检查所使用的工作文件
元配置 建立你的 配置 脚本。 仅在调试时有用
单位。

-m 假设有大量内存和交换空间。 这将加快符号查找
大量的时间,以内存为代价的源文件
消耗...

-o 将过时的符号映射到新符号上。 如果您还有一些,请使用此开关
源代码中的过时符号并且不想(或不能)删除
他们现在。 否则会忽略过时的符号,尽管
会给你一个警告 元配置.

-s 开启静音模式。

-t 跟踪符号被发现。

-v 打开详细模式。

-w 假设通缉文件是最新的。 这将跳过时间和内存
消耗源代码扫描阶段,寻找已知符号。 用它
只有当你知道你的源文件相对于
元配置 使用的符号。

-G 还提供了一个 GNU 配置- 生成的前端 配置
脚本,也将包含在发行版中。 这只是一个包装
周围的 配置 脚本自然,但它让人们熟悉
面对新发行版时不会丢失 GNU 工具。

-L DIR 覆盖默认库位置。 通常只对元配置有用
维护者在本地使用正在开发的单元而不是
公开可用的。 这 DIR 指定的是包含单位的那个
U 目录。

-M 允许生产一个 配置文件 文件以自动重新映射一些井 -
一些其他替代品的已知符号,例如 复制() 被重新映射
透明地 内存() 不可用时。 此选项已开启
自动时 配置文件 文件存在于顶级目录中。
如果您希望永久禁用此选项,只需删除该文件。

-V 打印版本号并退出。

在线课程


这个(长)部分是对 元配置,我们将在其中学习所有
基本。 如果您已经知道如何使用 元配置,您可以安全地跳到下一个
部分。

概述
通常,当您想要在给定的平台上编译某些源代码包时
编辑主 Makefile(假设有一个!),选择一个 C 编译器,确保你
拥有适当的库,然后启动 使 命令。 如果包裹合理
写得好,它会编译(没有警告是一个选项:-)。 就其本身而言,最后
句子是真正的表演,因为当今可用的 UNIX 平台多种多样
以及口味的多样性,这意味着包装的作者已经深入
给定一些标准的试验、猜测和混乱,很难找出正确的选择
围绕系统包括和类型。

然而,尽管他很有才华,但作者不可能知道某些系统具有
损坏的系统调用,或者某个系统结构缺少一个标准字段,或者
简单来说给定的包含文件是否存在。 我没有考虑隐含的
假设,例如返回的类型 malloc() 功能或存在
改名() 系统调用仅举几例。 但这些知识是实现真正目标所必需的
可移植性。

现在我们不要虐待自己。 使用这些信息需要更高的技能,但它可以
导致更可移植的程序,因为它是以独立于系统的方式编写的
并且仅依赖于某个假设在特定系统上是对还是错的事实,
每个假设彼此无关。 也就是说,我们不说:我们在
BSD系统或者我们在USG系统上。 反正现在也太糊涂了。 不,我们想要
对源代码说:这个系统没有 改名() 系统调用和 malloc()
返回一个 (空白 *) 计算值。

Metaconfig 是一种工具,可以让您做到这一点,另外的好处是不
如果一切顺利,必须手动编辑 Makefile。 通过跑步 元配置,你创建一个
命名的 shell 脚本 配置. 大量的努力已经投入到配置脚本
内部结构以确保它可以在 99% 的现有 shell 上运行
写作。 配置将探测目标系统,在有疑问时提出问题并
将所有答案收集在一个 shell 文件中,该文件又可用于
自动生成配置好的 Makefile 和 C 包含文件。

只有有限(但相当大)的一组符号可用于您的 shell 脚本
和 C 程序。 它们都记录在 Glossary 文件中。 您需要做的就是学习
并开始使用它们来解决可移植性和配置问题。 然后,
通过运行 元配置,将为您的包生成合适的配置脚本。

Configure 脚本由多个单元(超过 300 个)构建而成,每个单元被
负责定义少量的 shell 和/或 C 符号。 单元已组装
在最后阶段一起,尊重依赖图(一个单元可能需要结果
其他几个单位,然后放在脚本之前)。

符号
符号是最重要的东西 元配置 世界。 他们是最小的
公认的实体,通常是一个词,可以在 Configure 的末尾赋予一个值
执行。 例如,C 预处理器符号 重命名 是一个 元配置 象征着
保证被定义当且仅当 改名() 存在系统调用。 同样地,
$随机库 shell 变量将被设置为 ':' 或 'ranlib',具体取决于
打电话给 运行库 需要程序来订购库文件。 这是如何工作的
现在很重要,重要的是要了解这些符号被赋予了 生活
(即一个值)在 配置 执行。

使用符号相对简单。 在 C 源文件中,您只需使用符号
值,作为预处理器指令(例如: #ifdef 重命名) 或者,如果符号
value 是一个字符串,直接就像在 C 中使用宏一样。在 shell 文件或
Makefile,你可以直接引用一个shell 符号。

事实上,我在撒谎,因为那并不像上一段那么神奇
可以听起来。 在 C 文件中,您需要包含 Configure-produced 配置文件 文件,和
您必须将您的 shell 脚本或 Makefile 包装在一个 .SH 文件中,并且您可以引用该 shell
符号仅在该 .SH 文件的变量替换部分。 稍后会详细介绍。

来源
符号可能只出现在一组有限的源文件中,因为 元配置 只会
在寻找已知符号时扫描那些,试图找出它需要哪些单位。
您可以在 C 源文件中使用 C 符号,即带有 .c, .h, .y or .l 扩展名,以及
仅在 .SH 文件中查找 shell 符号。

为了获取符号的值,C 文件需要包含特殊的 配置文件
文件,由 配置 当 C 符号出现时。 并运行 .SH 文件
通过shell,生成一个新文件。 但是,在 .SH 文件的顶部,
特别 配置文件 文件(也通过运行产生 配置) 是来源,并且是可变的
替换适用。 实际上, 配置文件 是通过运行产生的 元配置-produced
配置_h.SH 文件,再次使用变量替换。 所以我们要看看那个
更紧密一点,因为这是整体的核心 配置 方案...

变量 换人
有一个 shell 结构叫做 点击此处 文件 它使命令能够接受输入
在脚本本身中指定。 该输入被外壳程序解释为双
引用字符串或单引号字符串取决于此处文档的形式
规格。

要指定此处的文档,请使用“<<”标记,后跟单个标识符。 从
然后,剩余的脚本行形成命令的输入,直到这里
文档单独在一行上找到。 外壳替换(包括外壳变量
替换),除非标识符被单引号括起来。 例如:

变量=“第一”
焦油=“秒”
echo "--> 第一个文档:"
猫 <
var='$var'
焦油=“$焦油”
EOM
echo "--> 这里的第二个文档:"
猫 <<'EOM'
回声 $var
回声 $tar
EOM
回声“-->结束。”

通过 shell 运行时会产生:

--> 先看这里的文档:
变量=“第一”
焦油=“秒”
--> 这里的第二个文档:
回声 $var
回声 $tar
--> 结束。

第一个 here 文档对其内容进行了解释,而第二个文档则按原样输出。
正如我们即将看到的,两者在 .SH 脚本中都很有用。

运用 .SH 脚本
.SH 脚本通常是通过运行 制造商 脚本其他现有文件,
转型 文件文件.SH. 让我们举一个例子。 这是一个小脚本
(让我们称之为 大尺寸) 打印一条消息,即 INT C中的数据类型
不幸的是,它具有硬连线的价值,因此:

#!/ bin / sh的
尺寸='4'
echo "在这台机器上,int 类型是 $intsize 字节"

让我们跑 制作SH 输入'制作SH 大尺寸'。 我们得到一个 大小 文件
看起来像这样:

案例 $CONFIG 在
'')
如果测试 -f config.sh; 然后 TOP=.;
elif 测试 -f ../config.sh; 那么 TOP=..;
elif 测试 -f ../../config.sh; 那么 TOP=../ ..;
elif 测试 -f ../../../config.sh; 那么 TOP=../../..;
elif 测试 -f ../../../../config.sh; 那么 TOP=../../../..;
其他
echo "找不到config.sh。"; 出口 1
fi
. $TOP/配置.sh
;;
ESAC
: 这会强制 SH 文件在与 SH 文件相同的目录中创建目标。
: 这是为了让 make Depend 始终知道在哪里可以找到 SH 导数。
案例“ $ 0”在
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
ESAC
echo "提取 intsize (使用变量替换)"
:文件的这一部分将对其进行变量替换。
: 从 !NO!SUBS! 移动任何需要配置子文件的东西! 部分到 !GROK!THIS!。
:保护您不想解释的任何美元符号和反引号
: 通过在前面放一个反斜杠。 您可以删除这些评论。
$spitshell >intsize <
$开始
!GROK!这个!

: 在下面的美元和反引号中不需要额外的反斜杠。
$spitshell >>intsize <<'!NO!SUBS!'
尺寸='4'
echo "在这台机器上,int 类型是 $intsize 字节"
!不!订阅!
chmod 755 整数
$eunicefix 整型

这个脚本的第一部分(在 案件 语句)正在尝试定位 配置文件
文件,以便获取它。 这 $配置 变量默认为假,当为真时
配置文件 已经被获取(如果这个文件是从
配置 本身,但我们不要在这里混淆这个问题)。

一旦 配置文件 文件已被sources,定义的所有shell符号 配置 ,那恭喜你,
放。 我们知道到达第二个 case 语句,用于更改当前目录应该
路径用于到达该程序(例如,如果我们说“sh ../scripts/intsize.SH', 我们
将首先运行 'cd ../脚本' 在继续之前)。 如果你不明白这一点,不要
担心它。

有趣的东西来了。 该脚本使用 $吐壳 变量,它不是
我们知道的一些事情......还没有。 如果您查看 Glossary 文件,您会看到
这是一个已知的变量 元配置. 如果您将此文件作为发行版的一部分
(通过将它包含在 MANIFEST.new 文件中,我们稍后会回来讨论)并运行
元配置,则 配置 脚本将为这个变量确定一个合适的值
它将被设置在 配置文件。 一样 $开始 和神秘的 $eunicefix at
结束。 在合理的制度上,相关部分 配置文件 看起来像这样:

吐壳=“猫”
开始= =#!/ bin / sh的'
eunicefix=':'

啊! 我们快到了。 现在看起来很熟悉。 我们面临着一个 命令其
输入来自一个变量插入的 here 文档,其输出被重定向到
大尺寸. 该值将是 $开始, IE '#!/ bin / sh的'。 到目前为止还好。

然后我们到达第二个 here 文档扩展,以获取脚本的剩余部分。 这个
时间,这里的文档符号被单引号包围,因此内容将是
逐字附加到 大尺寸 文件。 因此,通过运行 'sh 大小',我们得到
以下输出:

提取 intsize(使用变量替换)

通过查看生成的 intsize 文件,我们看到:

#!/ bin / sh的
尺寸='4'
echo "在这台机器上,int 类型是 $intsize 字节"

这正是我们一开始所拥有的。 到目前为止,这是一个无手术程序......
但是,多么奇妙! 确实如此(纯属巧合,相信我!),那 元配置 知道
关于 $整数 壳符号。 通过将 intsize 的初始化移动到变量 -
.SH 脚本的内插区域并使用 配置- 计算值,
并删除现在添加的无用评论 制作SH,我们得到:

案例 $CONFIG 在
'')
如果测试 -f config.sh; 然后 TOP=.;
elif 测试 -f ../config.sh; 那么 TOP=..;
elif 测试 -f ../../config.sh; 那么 TOP=../ ..;
elif 测试 -f ../../../config.sh; 那么 TOP=../../..;
elif 测试 -f ../../../../config.sh; 那么 TOP=../../../..;
其他
echo "找不到config.sh。"; 出口 1
fi
. $TOP/配置.sh
;;
ESAC
案例“ $ 0”在
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
ESAC
echo "提取 intsize (使用变量替换)"
$spitshell >intsize <
$开始
intsize='$intsize'
!GROK!这个!

$spitshell >>intsize <<'!NO!SUBS!'
echo "在这台机器上,int 类型是 $intsize 字节"
!不!订阅!
chmod 755 整数
$eunicefix 整型

当然,通过 shell 运行此脚本将再次输出相同的脚本。 但是如果
我们跑 配置 在一台机器上 INT 存储为 64 位数量, 配置文件
大尺寸 到 8 年和 大尺寸 脚本将带有正确的值并打印:

在这台机器上,int 类型是 8 个字节

哪个是正确的。 恭喜! 我们刚刚配置了一个shell脚本!!

生产 配置文件
我们现在可以看看路 配置文件 产生于 配置_h.SH。 我们知道
运行 配置 生产一个 配置文件 脚本(严格来说这是如何完成的并不是
与此处相关,但出于好奇,这是另一个此处的文档替换
配置 本身)。 这 配置_h.SH 本身是由 元配置 与此同时
配置 是,前提是您在源代码中至少使用了一个 C 符号。

让我们来看看一些随机 配置_h.SH 文件以查看实际发生的情况:

案例 $CONFIG 在
'')
如果测试 -f config.sh; 然后 TOP=.;
elif 测试 -f ../config.sh; 那么 TOP=..;
elif 测试 -f ../../config.sh; 那么 TOP=../ ..;
elif 测试 -f ../../../config.sh; 那么 TOP=../../..;
elif 测试 -f ../../../../config.sh; 那么 TOP=../../../..;
其他
echo "找不到config.sh。"; 出口 1
fi
. $TOP/配置.sh
;;
ESAC
案例“ $ 0”在
*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
ESAC
回声“提取 config.h(使用变量替换)”
sed < config.h -e 's!^#undef!/define!' -e 's!^#un-def!#undef!'
/*
* 该文件是通过运行 config_h.SH 脚本生成的,它
* 从 config.sh 获取它的值,它通常由
* 运行配置。
*
* 如有需要,请随意修改其中任何一项。 但是请注意,
* 再次运行 config.h.SH 将清除您所做的任何更改。
* 要获得更永久的更改,请编辑 config.sh 并重新运行 config.h.SH。
*/

/* 配置时间:$cf_time
* 配置者:$cf_by
* 目标系统:$myuname
*/

#ifndef_config_h_
#定义_config_h_

/* 复制:
* 如果没有 bcopy() 例程,则该符号映射到 memcpy
* 可用于复制字符串。
*/
/* 有_BCOPY:
* 如果 bcopy() 例程可用于
* 复制内存块。 你不应该在下面使用这个符号
* 正常情况下直接使用 bcopy() 代替,
* 如果 bcopy 不可用,将被映射到 memcpy()。
*/
#$d_bcopy HAS_BCOPY /**/
#ifndef HAS_BCOPY
#ifdef bcopy
#un-def bcopy
#ENDIF
#define bcopy(s,d,l) memcpy((d),(s),(l)) /* 映射到 memcpy */
#ENDIF

/* HAS_DUP2:
* 如果定义了这个符号,则表示 dup2 例程是
* 可用于复制文件描述符。
*/
#$d_dup2 HAS_DUP2 /**/

/* I_STRING:
* 如果定义了这个符号,它会向 C 程序表明它应该
* 包括(USG 系统)而不是(BSD 系统)。
*/
#$i_string I_STRING /**/

#ENDIF
!GROK!这个!

在文件的顶部,我们识别出我们已经拥有的标准 .SH 结构
详细研究过。 接下来是文件本身的提取,通过这里的文档
变量替换。 但是,这里我们不使用普通的 但是 口渴 相反,因为
我们需要即时进行一些进一步的编辑。 我们稍后会看到原因,所以让我们忘记
关于它现在。

我们现在到达前导注释,文件被标记为配置时间,
目标系统等...(那些变量来自源 配置文件 文件已经
设立者 配置)。 该评论标题后跟一个“#ifndef”保护来保护
反对多次包含此文件。 然后是文件的核心......

这有助于了解这一点 $d_*$i_* 变量设置为'定义' 要么 '未定义' 经过
配置, 取决于系统上是否存在函数或包含文件,或者
不是。 这意味着:

#$d_bcopy HAS_BCOPY /**/

行将扩展为:

#定义HAS_BCOPY /**/

如果 $d_bcopy 变量设置为 'define' 或:

#undef HAS_BCOPY /**/

如果 $d_bcopy 设置为 'undef',因为该功能不存在。 然而,这不是
什么写在 配置文件 档案因为 口渴 我们已经看到的过滤器,
这会将第二种形式转换为:

/*#定义 HAS_BCOPY /**/

这是一个方便的表格,供以后编辑 配置文件 因为你只需要删除
如果要覆盖,则以 '/*' 开头 配置的选择。 同样,您可以添加一个
'#define' 行开头的 '/*' 以避免定义特定符号。
这就是为什么每个符号定义都受尾随的“/**/”保护,以关闭前导
'/*' 打开的注释(注释不嵌套在 C 中)。

现在将 '#undef' 转换为 '/*#define' 很好,但是如果我们想真正写一个
'#undef',我们被卡住了...除非我们把它写成 '#un-def' 然后让 口渴 将其修复为“#undef”
在生产的同时 配置文件,这就是这里实际完成的。

同样的推理适用于这两行:

#$d_dup2 HAS_DUP2 /**/
#$i_string I_STRING /**/

并假设 配置文件 定义:

d_dup2='定义'
i_string='undef'

我们将进入生产 配置文件:

#定义HAS_DUP2 /**/
/*#定义I_STRING /**/

清澈如流水? 好的!

现在很明显,通过包括 配置文件 在你所有的 C 源文件中,你会得到
知道什么 配置 已经猜到你的系统了。 实际上,通过使用这些符号,您是
编写配置的 C 代码,因为 元配置 会知道你需要这些符号并且会
生成合适的 配置_h.SH 文件以及所有必要的代码 配置
为它们计算一个合适的值(通过为相关的 shell 变量赋值)。

运行 元配置
让我们专注于 元配置 编程一段时间以了解它如何使用其单位和
您的源代码以生成所有需要的配置文件。 如果你打算写新的
单位,你应该对整个方案有很好的了解。

如果没有 MANIFEST.new 文件, 元配置 将尝试使用 MANIFEST 文件,
为了方便。 到处提到MANIFEST.new,可以理解为MANIFEST
如果在您的包的根目录中找不到 MANIFEST.new 文件。

假设您的 MANIFEST.new 文件已正确设置并列出您希望的所有源文件
配置,并且您已经运行 包装 在您的根源目录中创建一个
。包装 文件,你可以运行 元配置 你会得到以下信息:

$元配置
定位单位...
从 312 个单元中提取依赖项列表...
从 MANIFEST.new 中提取文件名(*.[chyl] 和 *.SH)...
构建通缉文件...
正在扫描 .[chyl] 文件中的符号...
正在扫描 .SH 文件中的符号...
计算最优依赖图...
构建私有 make 文件...
确定可加载单位...
正在更新制作文件...
确定单元的正确顺序...
正在创建配置...
完成。

第一阶段查找 public 目录中的所有单元文件(以 .U 结尾)
首先,然后在你的私人。 如果你在你的私有 U 目录中复制了一个公共文件
(即包顶层名为 U 的目录),它将覆盖公共
版本。 一旦它拥有所有可用单元的列表,它就会解析它们并提取所有
?MAKE: 行以了解依赖项和已知的 shell 符号。 它也是
重点关注 ?H: 行以了解 C 符号以及需要使用哪些 shell 符号
计算以获得该 C 符号的正确值(因此我们有另一个级别的依赖关系
这里)。

接下来,从 MANIFEST.new 文件中提取正确的文件名和一个 通缉 文件是
内置:该文件列出了该包所需的所有 C 符号和 shell 符号。 我们
首先扫描 C 类型文件中的 C 符号,然后将依赖项传播到它们的
关联的 shell 符号(从 ?H: 行中收集)。 下一个 .SH 文件被扫描,最后
所有的 shell 符号都是已知的。

构建了一个临时 Makefile 并且 metaconfig 尝试 使 要查看的所有 shell 符号
执行了哪些命令(在第二个 ?MAKE: 行中列出),以及哪些单元是
真的需要。 不需要的可选单元被删除,第二个 Makefile 被删除
生成。 这一次,我们知道所有的单位和他们各自的订单,可选
已删除单位并为其外壳符号计算默认值。 这
配置 然后可以生成脚本,以及 配置_h.SH. 我们完成了。

公约
需要遵循适当的约定以使整个过程合理。 有一个案例
单位约定和变量命名约定。

所有单位的第一个字母都应该小写,除非它们是特殊单位。 经过
特殊的,我们的意思是它们并没有真正定义新的 shell 变量可以由
用户在他的 .SH 文件中,而是生成脚本或 shell 变量的单元
由内部使用 配置 脚本。 典型的例子是 初始化U 文件是
主变量初始化,或 我的阅读 产生 我的阅读 脚本几乎使用
无处不在 配置 当向用户提出问题时。

非特殊单位然后细分为两个不同的组:定义变量的单位
与 C 符号和定义它们自己的 shell 变量的单元相关联。 第一组
进一步分为与包含文件相关的变量(它们的名称以 i_) 以及
与其他定义相关的变量(名称以 d_)。 第二组有
代表自己的名字,例如 立方厘米 定义 $抄送 shell 变量,其值为
要使用的 C 编译器。

特殊单元有时会为自己保留一些预定义的变量并返回“结果”
在其他众所周知的变量中。 例如, 我的阅读 Myread.U 制作的脚本
期待提示 $rp, 中的默认答案 $dflt 并将用户答案放在 $ans.
这在本手册页中没有记录:您必须去查看设备本身才能
了解使用了哪些变量以及如何使用单位。

运用 词汇表
Glossary 文件由 彩妆 脚本,它提取
来自 ?S:、?C: 和 ?MAKE: 的信息行并将它们重新格式化为字母顺序
分类词汇表。 阅读术语表以了解您所使用的符号很重要
允许使用。 但是,词汇表不会告诉您如何使用它们。 通常,那是
由你决定。

有一天,您可能会编写自己的单元,并且您将足够了解 元配置
快速有效地做到这一点。 但是,永远不要忘记正确记录您的工作
?S: 和?C: 行,否则其他人将无法重用它。 记住关于
您只有词汇表和本手册页才能开始使用的时间。

结论
现在你知道了 元配置 基础知识,你应该阅读 商品描述 然后
跳到 参考 部分了解所有血腥细节,例如允许的
单元控制行(以“?”开头的行)或不同的 MAKE 命令的语法
你被允许使用。

参考


本节记录了 元配置,基本上是单位语法,特殊的
您应该了解的单位和提示文件。

总类 单位 句法
元配置单元分为两个不同的部分。 标题部分(行开始
带有“?”)和一个 shell 部分(要包含在 配置 脚本)。 这是
可以在单元内的任何地方添加 '?X:' 注释,但另一个 '?' 行(也
被称为 控制 线) 有严格的订购政策。

如果控制线太长,可以通过转义最后一个来使用延续
带反斜杠的换行符并在下一行继续(然后应缩进
按空格或制表符)。

以下是对每条控制线的正式描述。 除非说明
否则,此演示文稿的顺序是在单元内使用的顺序。

?RCS: 免费 文本
用于 RCS 注释,位于单元顶部。

?X: 任何 文本
通用注释。 可以出现在单元中的任何位置,但必须保持对齐。
对于 RCS 意见,请使用 ?RCS: 意见表。

?制作:符号 名单: 依赖 名单 [+可选]
这是第一个依赖行。 首先 符号 名单 应该列出所有符号
由该单元建造(即其值由单元的壳部分计算)。
符号应以空格分隔。 如果定义的符号仅供内部使用且
不应出现在生成的 配置文件 文件,那么它前面应该有一个
'+'(不要与后面定义的可选依赖项混淆)。 第二
列表的一部分(在中间的 ':' 之后)是单元依赖项。 它应该列出所有
所需的特殊单位,以及 shell 使用的所有符号
执行。 如果一个符号是 neded 但它的配置值并不重要,它
前面可以有一个“+”,在这种情况下,它被称为条件依赖:它的
当且仅当该符号实际上是
通缉; 否则将使用默认值。

?制作:标签 命令
初始依赖行之后可以有一个或多个命令行。 那些
当单元想要将它们加载到时将执行命令 配置。 看
有关更多信息的 make 命令的段落。 请注意,领先的 标签
字符之前需要 命令.

?Y:布局
为这个单元声明一个布局指令。 该指令可能是字符串之一
最佳, 默认 or 底部 (大小写无所谓,推荐的风格是把它们拼出来
大写)。 如果省略, 默认 假设。

仅当您希望在顶部或底部强制使用单元时才需要此指令
生成的 配置 脚本,因为单元依赖性允许它。 重要的
因此,问题可能会在一开始就被强行提出。 在同一个布局类中,单元
按字母顺序排序,d_* 和 i_* 单位有两种特殊情况,强制
分别在他们班级的顶部和底部(但这些应该属于
默认类)。

如果您在顶部强制一个单元,其依赖项需要所有其他单元
在它之前,你没有什么有趣的事情。 因此,该指令应该真正
用于增加一些不依赖于许多交互单元的优先级
其他用户可见的符号,例如与路径相关的问题。

?S:符号名称 [(过时的 符号 名单)]:
引入壳符号。 第一行命名符号,可选后跟一个
括号内的列表并给出过时的等效项。 那些过时的
符号将被重新映射到新的 符号名称 如果 -o 选项被赋予
元配置.

?S:任何 文字, 词汇表
基本上是一个描述 shell 符号的注释,它将被提取 彩妆
进入词汇表文件。

?S:。 关闭外壳符号注释。

?C:符号名称 [~ 别号] [(过时的 符号 名单)]:
引入一个新的 C 符号。 这 别号 name 是 C 符号所在的名称
被控制,即如果 别号 需要符号,然后将写入该 C 符号
,在 配置_h.SH 文件。 通常,别名只是 '%<'(代表单位名称)
还有一个 ?W: 行将 C 符号映射到 别号. 还有相关部分
?H: 行的显式保护受 '?%<' 条件的保护。 看符号
别名段落以获取更多详细信息。 该行的其余部分是可选的
过时的 符号 名单,其中列出了新的旧等价物 符号名称.

?C:任何 文字, 词汇表 配置_h.SH
基本上是描述 C 符号的注释,它将被提取 彩妆
进入词汇表文件并通过 元配置配置_h.SH 如果符号是文件
想要(或者在使用符号别名时是否需要它的别名)。

?C:。 关闭 C 符号注释。

?H:?符号:配置_h.SH 东西
这是一般的包含请求 配置_h.SH. 该行仅在写入时
守卫 符号 是真的想要。 C符号时需要这种通用形式
使用了别名。 否则,如果您使用其他“标准”形式之一,则
保护是由自动完成的 元配置 本身。

?H:#$d_var VAR "$变量"
有条件地定义 VAR C符号变成 $变量 何时设置为 '定义'。 暗示一个
'?VAR:' 守卫条件, 和 元配置 自动链接 VAR 到它的两个外壳
变量依赖(即两者 $d_var$变量 将被标记为 通缉 if VAR is
在 C 源代码中使用)。

?H:#定义 VAR [可选 文本]
始终定义 VAR C 符号到某个值。 表示一个 '?VAR:' 保护条件。
对单元本身产生自动外壳依赖性。

?H:#定义 变量(x,y,z) $变量
始终定义宏 VAR 成为 $变量 多变的。 这取决于
单位保证 $变量 持有合理的价值。 C之间的自动依赖
VAR 并建立了shell变量,整行都由一个
隐含的 '?VAR:'。

?H:#$d_var VAR
有条件地定义 VAR if $d_var 被设定为 '定义'。 表示一个 '?VAR:' 守卫
健康)状况。 生成一个自动 shell 依赖项 $d_war.

?H:#定义 VAR "$变量"
将配置的值分配给 VAR C 符号。 表示一个 '?VAR:' 保护条件。
自动生成shell依赖链接 VAR$变量.

?H:。 关闭 配置_h.SH 包含请求。

?M:C 符号: C 依赖
引入关于 C 符号的魔法定义,对于 配置文件,并定义
其余的保护符号?M:定义。 这条线默默暗示
'?W:%<:C 符号',即如果出现 C 符号,该单元将被加载到配置中
在 C 源代码中,无论是否使用魔法。 C 依赖项被激活
当使用魔法时,为了强制它们的定义 配置_h.SH。 但是,如果
魔术是 不能 使用但 C 符号出现在源代码中,而没有需要的 C
依赖,每次构建通缉文件时都会警告您,因为它可能是
便携性问题(也因为该单元无条件加载到
每当使用 C 符号时进行配置,而不管其他 ?C: 行来自
单元)。

?M:CPP 定义
定义要在 confmagic.h 中引入的魔法 cpp 映射
符号被使用。 有一个隐含的 '?符号'守在什么地方 符号 是符号名称
由前导 ?M: 行定义。

?M:。 关闭 配置文件 包含请求。

?W: 符号 名单:C 符号 名单
将 shell 符号的命运与 C 符号的命运联系起来:如果任何一个 C
列出的符号是需要的,然后所有的外壳符号都被标记为需要的。 有用的
当存在某些 C 时,强制包含一个单元(shell 符号列表设置为 '%<')
检测到符号。 外壳符号列表可以留空,以从侧面受益
内置预处理器中 C 符号位置的影响(符号为 定义
对于该预处理器(如果位于源中)。 寻找带空格的图案
在它们中,您需要在简单的引号中引用 C 符号,如 'struct
时区'。

?五:唯读 符号:读写 符号
这是一个 金属色 提示并且应该仅用于导出某些 shell 的特殊单元
变量。 中间 ':' 之前的变量以只读方式导出(更改它们
将发出警告),而其他符号可以自由阅读和更改。

?F: 创建
这条线有两个目的:它是一个 金属色 提示,也是一个占位符
未来 杰作 用。 它必须列出三种文件:临时文件是
为测试而创建,在 UU 目录中创建的私有 UU 供以后使用
仔细阅读,公共的留在包的根目录中。 暂时的
文件必须以前面的“!”列出字符(意思是“不!它们不会被重复使用
稍后!”),私有 UU 文件前面应该有一个 './'(意思是:要使用它们,比如说
。/文件,不只是 文件),公共的应该按原样命名。

?T: 临时工
另一个 金属色 暗示。 这一行列出了所有用作临时变量的 shell 变量
在本单元的外壳部分内。

?D:符号='折扣值'
用作条件依赖项的符号的初始化值。 如果没有?D:线是
找到,则使用空值代替。 这 金属色 程序会警告你,如果
符号作为条件依赖至少使用一次,并且没有适当的
?D:初始化。 即使为 null 添加这些行也是一个好习惯
初始化,因为它强调符号的可能可选性质。

?哦:任何 的话
该指令表明该单元作为一个整体已过时。 每当使用任何
它的符号被制作(或通过依赖间接使用),消息输出
屏幕(在标准错误上)。 您可以放置​​一个或多个行,在这种情况下,每行都将
打印,按顺序。

?皮棉:金属色 提示
查看 金属色 手册页,用于解释可以使用的不同提示
用过的。

?在里面:初始化
这一行指定的初始化代码将被加载到
配置 脚本提供的单位是需要的。

C 图形符号 混叠
有时无法依靠 元配置自己的默认选择 配置_h.SH
注释和 C 符号定义。 这就是混叠发挥作用的地方。 因为它比较
很难解释,我们将研究一个例子来理解底层机制。

d_const.U 单元尝试确定您的 C 编译器是否知道 常量
关键词。 如果不想,我们想将该关键字重新映射为空字符串,以便让
程序编译。 此外,我们希望在以下情况下自动触发测试 常量
用来。

以下是 d_const.U 单元的相关部分:

?MAKE:d_const: cat cc ccflags Setvar
?MAKE: -pick 添加 $@ %
?S:d_const:
?S:这个变量有条件地定义了 HASCONST 符号,它
?S:向 C 程序表明这个 C 编译器知道
?S:const 类型。
?S:。
?C:HASCONST ~ %<:
?C:这个符号,如果定义了,表示这个 C 编译器知道
?C:const 类型。 无需实际测试该符号
?C:在你的程序中。 仅使用“const”关键字将
?C:触发必要的测试。
?C:。
?H:?%<:#$d_const HASCONST /**/
?H:?%<:#ifndef HASCONST
?H:?%<:#define const
?H:?%<:#endif
?H:。
?W:%<:const
?LINT:设置d_const
?LINT:已知常量
: 检查 const 关键字
回声“”
echo '检查你的 C 编译器是否知道“const”...' >&4
/斌/猫 >const.c <<'EOCP'
主()
{
常量字符 *foo;
}
经济合作计划
if $cc -c $ccflags const.c >/dev/null 2>&1 ; 然后
val="$定义"
echo “是的,确实如此。”
其他
val="$undef"
echo “不,没有。”
fi
设置 d_const
评估 $setvar

首先我们注意到使用了 ?W: 行,它基本上说:“当
常量 关键字在 C 文件中使用。”。为了有条件地重新映射 常量 为空
串入 配置文件,我选择有条件地定义 康斯特 通过 $d_const.

然而,这带来了一个问题,因为 康斯特 符号不会用于
消息来源,只有 常量 令牌是。 而 ?H: 行定义 康斯特 隐含地
由'?HASCONST' 保护。 因此,我们必须添加显式的 '?%<' 约束来告诉
元配置 这些行应该包括在 配置_h.SH 每当 '%<' 符号
被通缉(%< 指的是单位名称,这里 d_const).

这几乎是完美的,因为 ?W: 行会想要 d_const 每当 常量 被使用,然后
?H: 行将包含在 配置_h.SH 文件。 然而,领先的评论 (?C:
行)附加到 康斯特 本身也通过 康斯特, 即它有一个隐含的
'?HASCONST' 约束。 因此需要 别名康斯特 '%<' 的符号。

单元的其余部分(外壳部分)非常简单。 它简直
尝试使用 常量 关键词。 如果可以,那么它会
定义 $d_const 通过 $设置变量 函数(由 设置变量U 单元)。 见段落
有关特殊单位的更多详细信息。

他们成为 命令
在 ?MAKE: 命令行上,您可以编写要按原样执行的 shell 命令或
特别 -挑 被困的命令 元配置 并解析以查看应该是什么
完毕。 领先的“-”只是为了防止 使 命令返回时失败
非零状态——因为我们使用 ',所以并不真正需要它使 -n' 来解决
依赖,但我建议你保留它,以防它在未来的版本中成为强制性的。
的语法 命令是:

-挑 CMD $@ 目标文件

哪里 $@ 是 Makefile 中代表当前目标的标准宏(名称
正在构建的单元,最后的 .U 扩展名被剥离)。 这 CMD 部分是
实际 元配置 要运行的命令,以及 目标文件 是另一个参数,其
解释取决于 CMD 本身。 它还删除了最终的 .U 扩展名并
通常引用一个单元文件,除非它以“./”开头,在这种情况下它引用一个
元配置 ' 中的控制文件。公吨 目录。

可用的命令有:

添加添加 目标文件配置.

添加.Config_sh
填写那部分 配置 生产 配置文件 文件。 只用过
添加变量,条件变量(来自条件依赖项)是
跳过。

add.Null 将用于初始化所有 shell 变量的部分添加为空字符串。

c_h_weed 产生 配置_h.SH 文件。 只打印必要的行。

cm_h_weed 产生 配置文件 文件。 只打印必要的行。 这个
命令仅在 -M 给定开关,或当 配置文件 文件
已经存在。

关闭.Config_sh
在一行上单独添加最后的“EOT”符号以结束此处的文档
构造产生 配置文件 文件中。

prepend 将目标的内容添加到 目标文件 如果该文件不为空。

杂草 将单位添加到 配置 命令,但进行一些额外的测试
删除'?符号' 和 '%符号' 行来自 目标文件 如果符号
不被通缉或有条件通缉。 '%' 形式只在内部使用
元配置 同时在 ' 中生成自己的 .U 文件。公吨' 目录。

擦拭 与 真的,但执行额外的宏替换。 这
可用的宏在 带电线 段落。

作为旁注, 元配置 产生一个 -条件 命令内部处理条件
依赖关系。 你不应该自己使用它,但如果你扫描它,你会看到它
产生 生成文件 ,在 。公吨 目录。

带电线
以下宏被识别 擦拭 命令并替换在包含之前
配置:

包的基本修订号,源自 。包装.

当前日期。


此包维护者的电子邮件地址,源自您的
。包装.


包的名称,源自您的 。包装 文件中。


补丁级别 元配置 程序(已弃用,以支持)。


SVN 的修订级别 元配置 程序。

版本号 元配置 程序。

这些宏主要用于识别 元配置 生成的版本
特别 配置 脚本以及它是为哪个包完成的。 电子邮件地址
维护者在主要说明中硬连线 配置 启动时打印。

最新产品 元配置 版本理解形式的更一般的语法:

<$变量>

它在配置生成时被替换为 变量 从你的
。包装 文件。 最终,旧的硬连线宏格式将消失,并且 <$baserev>
将取代在所有提供的单元中。

Special Units
以下特殊单位用于分解代码并提供更高级别
功能。 他们要么生成一个可以获取的 shell 脚本,要么生成一个 shell
可以是变量 评估'ed。 参数传递是通过众所周知的变量完成的,要么
命名或匿名,如 $1、$2 等...(可以通过 shell 轻松设置
操作员)。 什么时候 配置 执行,它创建并进入 UU 目录,所以每个
生成的脚本就在那里,不会干扰包中的文件。

以下是您应该了解的特殊单位,以及使用它们的方法。

cpsym.U
该单元生成一个名为的 shell 脚本 符号,可用于确定
列表中的任何符号是否由您拥有的 C 预处理器或 C 编译器定义
指定的。 它可以确定任何符号的状态,尽管
(属性列表)更容易确定。

西西姆
这将设置 $csym shell 变量,由内部使用 配置 检查是否一个
给定的 C 符号是否定义。 一个典型的用途是:

设置符号结果 [-fva] [上一个]
评估 $csym

这将设置 导致 如果函数 [-f]、变量 [-v] 或
数组 [-a] 已定义,否则为 'false'。 如果给定了先前的值并且 -r
开关被提供给 配置 (见 配置 附加选项 段),那么
价值被毫无疑问地重用。

完成此计算的方式取决于用户对问题的回答
配置 将询问它是否应该执行 nm 提取与否。 如果
执行了提取,该单元只需查看符号列表,否则
它执行编译链接测试,除非 -r 被给予重用先前计算的
价值,自然...

结束.U
通过将本机复制到您的私人 U 目录和附加依赖项
?MAKE:行,你可以强制一个给定的单元被加载到 配置 即使不是
否则想要。 某些单位可能只能被迫进入 配置 那样。

文件系统
本单元生成一个 shell 脚本 文件xp 这将扩展以开头的文件名
波浪线。 一个典型的用途是:

exp_name=`./filep $name`

分配扩展文件名 表达式名称.

查找博士U
本单位生产 查找hdr 用于定位头文件的脚本
$usrinc 或其他使用 cpp 功能的陌生地方。 该脚本被赋予
包含文件基本名称,如“stdio.h”或“sys/file.h”,并返回完整路径
如果找到 inlcude 文件和零状态,或空字符串和非零状态
如果找不到文件。

获取文件
这个单元会产生一些 shell 代码,为了获取文件,必须获取这些代码
命名并进行一些完整性检查。 可选地,执行 ~name 扩展。

要使用本机, $rp$dflt 必须持有问题和默认答案,其中
将按原样传递给 我的阅读 脚本(见即将发布的 我的阅读)。 该 $fn
变量控制操作,结果返回到 $ans.

要定位文件或目录,请将 'f' 或 'd' 放入 ~/. 如果出现“~”,则 ~name
允许替换。 如果出现“/”,则只接受绝对路径名,并且
~name 替换总是在返回之前扩展。 如果指定了“+”,
跳过存在性检查。 如果“n”出现在 $fn,然后用户被允许
回答“无”。

通常,除非您要求可移植性,否则 ~name 替换会在请求时发生。
但是,有时您希望绕过可移植性并强制
代换。 您可以使用“e”字母(展开)来做到这一点。

如果使用特殊的“l”(定位)类型,则 $fn 变量必须以“:”结尾,
后跟文件基名。 如果答案是目录,则文件 basename 将是
在测试文件存在之前附加。 这在定位风格的问题中很有用
喜欢这个:

dflt='~新闻/lib'
: 使用 'l' 时无需指定 'd' 或 'f'
fn='l~:active'
rp='活动文件在哪里?
. ./获取文件
活动 =“$ans”

此外,“p”(路径)字母可以与“l”结合使用来告诉
获取文件 应该接受没有“/”的答案,假设它会
在需要此值时在每个人的 PATH 中。

指定应接受的答案列表的可能性也很有用
逐字逐句,绕过所有检查。 此列表必须在括号和项目内
必须以逗号分隔,没有交错空格。 不要忘记引用
结果字符串,因为括号对外壳有意义。 例如:

dflt='/bin/安装'
fn='/fe~(install,./install)'
rp='使用哪个安装程序?'
. ./获取文件
安装 =“$ans”

会让用户只指定引用现有文件的完全限定路径,
但仍然允许特殊的“安装”和“./安装”回答原样(假设
当然有些东西会在链的后面特别处理它们,因为它们会这样做
不符合一般预期框架)。

如果问题的答案是“无”,则跳过存在性检查并
返回空字符串。 请注意,由于 获取文件 电话 我的阅读 在内部,所有
可用的功能 我的阅读 申请这里。

如果需要完全扩展的值(例如在 Makefile 中),您可以使用
$ansexp 始终正确设置的变量 获取文件 作为扩展
版本的 $ans. 当然,如果你不允许,它不会扩展 ~name
第一名 $fn 变量。

人体工程学
本单位生产 $inhdr shell 变量,由内部使用 配置 去检查
是否存在一组标题。 一个典型的用途是:

设置标题 i_header [ header2 i_header2 ... ]
评估 $inhdr

这将打印一条消息,说明是否找到了标头并设置
i_header 相应地可变。 如果指定了多个标题并且第一个
没有找到标头,我们尝试下一个,直到列表为空或找到一个。

编译器
本单位生产 $inlibc shell 变量,由内部使用 配置 去检查
是否定义了给定的 C 函数。 一个典型的用途是:

设置函数 d_func
评估 $inlibc

这将打印一条消息,说明是否找到并设置了该函数
$d_func 因此。 在内部,它使用了 $csym 常规。

位置U
这个重要的单元产生一个shell脚本 可以用来找出在哪里
在给定文件所在的目录列表中。 第一个参数指定文件
被定位,第二个参数是如果搜索失败将返回的内容,以及
重新挖掘参数是要搜索文件的目录列表。 为了
实例:

dflt=`./loc sendmail.cf X / usr / lib目录 /var/lib/发送邮件 / lib目录`

会设置 $dfltX 如果不 发送邮件.cf 在列出的目录下找到文件,
或类似的东西 /usr/lib/sendmail.cf 在某些系统上。 也可以看看 获取文件.

邮件作者
这个单元需要包含在你自己的私人 End.U 的 ?MAKE: 线上才能制作
它成 配置. 它允许用户向作者注册自己,可选
在新补丁到达时收到通知或在发布时自动接收。
你需要安装 邮件代理 要做到这一点(至少 3.0 版)。

邮件列表
这个单元需要包含在你自己的私人 End.U 的 ?MAKE: 线上才能制作
它成 配置. 它为用户提供订阅或取消订阅邮件列表的功能
正在讨论与包相关的讨论。 你需要跑 包初始化
并回答邮件列表相关问题以在您的邮件列表中设置适当的变量
。包装 在本机投入使用之前。

初始化程序
将此单位复制到您的私人 U 目录将您自己的默认值添加到某些
内部变量。 这个单位被加载到 配置 毕竟默认
初始化已经完成。

我的阅读
本单位生产 我的阅读 必须获得 shell 脚本才能执行
读。 它允许 shell 转义、默认赋值和参数评估,如
记录在 Instruct.U 单元中。 它还允许动态设置 -d 选项,
这将用于剩余的脚本执行。

要使用本机, $rp 必须持有问题和 $dflt 应该包含默认值
回答。 问题将由脚本本身打印,并返回结果
,在 $ans 变量。

这是一个典型的用法:

dflt='y'
rp='问题?
. ./我的阅读
价值="$ans"

有关更多信息,请参阅设备本身。

旧配置文件
这个单元必须是你的依赖的一部分?MAKE:当你的一些单元尝试时行
重用旧的符号值。 本单元负责获取旧答案
配置文件 或在给定平台上运行时提供有用的提示
第一次。 见 配置 提示 有关提示的更多信息的段落。

前缀U
这个单元的目的是检测安装前缀目录的变化
从以前的答案中自动重新计算合适的默认值。 它依赖于
的价值 $旧前缀 保存前一个前缀目录的变量
已更改,否则为空。 例如,如果前缀从 /选择
在/ usr /本地,那么之前的二进制安装目录就会从
/选择/斌在/ usr / local / bin目录,或者将保持不变,例如, /箱.

你需要打电话 在发出之前 评估 on $前缀,如:

设置 dflt var [目录]
评估 $prefixit

这将设置 $dflt$变量 or $前缀/目录 取决于前缀是否保留
相同与否。 如果 DIR 是字符串 没有, 中的单个空格值 $dflt 保持为-
是,即使前缀发生变化。 如果 DIR 被省略,那么 $dflt 设置为空
字符串如果前缀更改,则为 $变量 除此以外。

前缀U
thit 单元的意图类似于 Prefixit.U 的意图,即它有助于修复
默认字符串以适应前缀更改。 但是,shell变量 $前缀,
评估时,只会恢复 ~name 扩展,前缀应该使用这样的转义
机制。 将其用作:

设置 dflt
评估 $prefixup

在通过提示之前 获取文件 例如。 如果前缀没有使用 ~name
扩展,那么以上将是一个空操作 y 变量,自然。

类型定义
本单位生产 $类型定义 shell 变量,由内部使用 配置 去检查
typedef 是否存在。 一个典型的用途是:

设置 typedef val_t 默认值 [包括]
评估 $typedef

这将设置变量 的价值 默认 如果未找到 typedef
在列出的包含文件中,或 类型定义 如果找到。 如果没有包含文件
指定,单位查找 只要。 如果您指定了一些包含,则仅
那些被看着。

Unix.U
本单元的目的是通过变量定义一些最常见的 UNIX 主义
可以从命令行或通过适当的提示文件进行更改。 特别是,
$_exe, $_o$_a 设置。 所有单位应参考 $_o 而不是 .o 直。
这 '。' 是这些变量的一部分。

设置变量U
该单元产生变量,由内部使用 配置 设置一个
定义/undef 给定符号的值,当它突然改变时发出警告
从以前的值。 例如:

val="$定义"
设置 d_variable
评估 $setvar

如果上一个 $d_变量 值不为空并且 $ val 是不同的,“哇”
发出警告。

哇哦
本单位生产 脚本,当 折扣值 在变量中
谁的名字是 $变量 与之前持有的旧值不同 $是. 在
返回, $td$ tu 保持适当的价值 定义 or 未定义 变量。 看
例子在 编译器.

内建 预处理器
每个单元都包含在 配置 通过内置的预处理器运行。 预
处理器语句由“@”字符引入(“#”是外壳注释
特点)。 它的功能仅与 C 预处理器相同,但允许使用 shell 和 perl
逃脱。 以下是可用的功能:

@如果 表达
If 表达 为真,继续加载代码直到@end、@elsif 或@else。

@elsif 表达
替代选择。 如果 表达 为真,继续加载代码直到@end,
另一个@elsif 或@else。

@else 默认代码加载,如果@if 表达 是假的,没有一个
可选的@elsif 匹配。 加载直到@end。

@end 关闭@if 打开的条件加载语句。

@定义 符号
告诉预处理器 符号 从现在开始定义。

有条件的 表达 可以包含符号名称(如果需要符号,则值为 true 或
通过定义 @定义 或 shell/perl 转义。 这些原子可以使用
传统的布尔运算符 '!' 用于否定,'&&' 用于逻辑与,以及 '||' 对于逻辑
要么。

单括号内的文本是外壳测试,而双括号之间的文本是
perl 测试。 即表达式:

{ 文本 }
{{ perl的 文本 }}

被翻译成:

if 文本 >/dev/null 2>&1; 然后退出0; 否则退出1; 菲
如果(perl的 文本) {退出 0;} 否则 {退出 1;}

并且以标准方式使用退出状态来获取布尔值,即 0 为真并且
其他一切都是假的。 注意perl只能表达简单的条件,直到
可以在其中加载一些复杂的代码 元配置 并被执行。

内置的预处理器可用于微调某些单元(请参阅 d_gethname.U 查阅
复杂的例子)取决于程序或文件实际使用的符号
存在于分布中。 例如, 旧配置文件 使用如下测试:

@if {测试-d ../提示}

配置 仅当存在提示时才会包含依赖于提示的代码 提示 目录中
包的顶级目录。 请注意,测试是从 '。公吨' 目录,
因此在测试中需要'../'。

预处理器还可用于避免在符号不存在时放置无用的代码
定义。 定义多个符号的单位可以通过这种方式受到保护(因为单位是
通过在@if/@end 对中收集依赖于符号的代码,作为一个整体加载)。 为了
实例:

@if I_TIME || I_SYS_TIME || I_SYS_TIME_KERNEL
need_time_h='真'
@别的
need_time_h='false'
@结尾

将测试源代码是否使用了控制的三个符号之一
时间 or 系统/时间.h 包含并相应地定义壳符号。 那给
配置 关于来源需要什么的反馈并避免固定的缺点
冷冻单位。

通过“?W:”行,您可以获得有趣的组合。 例如, i_time.U 单元
需要知道 C 源代码是否使用了 结构 时区 类型。 所以,
该行:

?W::时区

用于定义符号的副作用 时区 对于预处理器。 这
单元代码然后可以说:

@if 时区
对于 '-DS_TIMEZONE' '' 中的 s_timezone; 做
@别的
s_timezone=''
@结尾

... 使用 s_timezone 的代码 ...

@if 时区
完成
@结尾

并有一个额外的循环尝试两个连续的值 时区 变量,但仅
如果需要的话。

过时的 符号
保留过时的符号以简化与旧符号的转换 元配置 单位。 除非
-o 开关被传递到 元配置 他们将被忽略。 然而,一个 过时的 文件将
生成,告诉您哪些文件正在使用那些过时的符号以及什么
是要使用的新符号。

过时符号的生命周期是一次完整的修订,即它们将在
发布下一个基本修订版(补丁升级当然不算数)。 因此它是
明智的做法是尽快翻译您的来源并开始使用新符号。

配置 提示
内部配置逻辑可能会做出错误的选择。 为了
例如,在某些平台上, vfork() 系统调用存在但已损坏,因此应该
不被使用。 不可能将这些知识包含在单元本身中,因为
这可能是供应商最终会解决的临时问题,或者
由新的操作系统升级引入。

不管怎样,对于那些过于系统化的小问题, 元配置
提供提示文件支持。 要使用它,您需要创建一个 提示 目录中
包的顶级目录,并在运行时拥有它 元配置. 这将加载
提示相关部分来自 旧配置文件.

以后你可以预先设置一些shell变量 配置 用于特定于操作系统的
.sh 文件。 里面有代码 旧配置文件 试图猜测哪些提示文件需要
根据系统操作系统名称、内核名称、版本计算标准名称
数字等......由于这些信息可能会迅速变化,我没有记录下来
这里。 你必须对代码进行逆向工程 旧配置文件.

当你第一次发布你的包时,你的提示文件目录应该是空的。 如果
你的包裹的用户抱怨他们有问题 配置 默认为
特定系统,您必须查看这是特定于平台的问题还是
一般的。 在前一种情况下,是时候引入一个新的提示文件了,而在
后者应修改相应的单位。

例如,众所周知,SGI 系统有一个损坏的 vfork() 系统调用,从这里开始
写作。 而对应的提示文件名是 sgi.sh. 所以你需要做的就是创建
a 提示/ sgi.sh 您在其中写入的文件:

d_vfork="$define"

这将始终重新映射 叉子 on (见 d_vfork.U)。 在 SGI 系统上运行时
第一次, 配置 将检测到有一个 提示/ sgi.sh 文件,我们正在
一台 IRIX 机器(内核名称通常是 /irix),因此它会建议 sgi 作为一个
可能的提示。 如果用户接受它,并且由于 $d_vfork 值通过修改
$设置变量 打电话,一个 哇! 将发出警告我们即将覆盖该值
由...计算 配置.

请注意,您不必提供 所有 已知的提示 旧配置文件. 如果提示文件是
遗漏,将不作为可能的选择提出。 启发式测试运行以计算
可能的提示候选是片状的。 如果您有新的值或不同的测试,请
把它们发给我...

覆写 选择
如果您创建一个 配置文件 顶级目录中的文件, 配置 会问你是否
希望加载它以覆盖默认值。 这是在创建之前完成的
配置文件 文件,因此它使您有机会修补存储在其中的值。

这与提示方法不同,因为它是一个本地文件,用户是
自由创建供他自己使用。 你不应该自己提供这样的文件,而是让
用户知道这种可能性。

配置 附加选项
配置 可以使用命令行上指定的某些选项调用脚本,以
稍微修改其行为。 以下是允许的选项:

-d 对所有答案使用默认值。

-e 继续不问过去的生产 配置文件.

-f 文件 使用指定的文件作为默认配置。 如果不使用此开关,
配置取自 配置文件,当存在时。

-h 打印帮助信息并退出。

-r 如果可能,重用 C 符号值。 这将跳过昂贵的 nm 符号
萃取。 如果第一次使用(没有以前的配置文件),
配置 将尝试编译和链接一个小程序以了解
符号的存在或不存在。

-s 静音模式。 只有打印在文件描述符 #4 上的字符串才会出现在
屏幕(这是重要的消息)。 完全关闭是不可能的
任何输出,但您可以使用 '配置 -订单 > / dev /空 2>&1' 有一个完整的
批量运行,无需输出,无需用户交互。

-D 符号=值
预定义 符号 承担指定的 折扣值. 也可以使用 '-D
符号' 这将使用默认值 'define'。

-E 在产生了一个配置问题后,在配置问题的末尾停止
配置文件. 这不会执行任何 '使 依赖' 或 .SH 文件提取。

-K 知识渊博的用户。 当您使用此选项时,您知道自己在做什么并且
因此 配置文件 文件将始终按预期处理
重新使用,即使它可能是在外星系统上生成的。 它也是
防止中止时 配置 检测到不可用的 C 编译器或错误的集合
C 标志。 此选项也可以打开更多快捷方式
未来。 此选项记录在 配置 使用信息,提醒我们
关于它的存在,但希望给出的描述足够神秘。
:-)

-O 允许通过指定的值 -D or -U 覆盖任何加载的设置
配置文件。 这不是默认行为,因为覆盖将
不会传播到从您当前正在更改的变量派生的变量。
自然,没有 -O, 只有在没有配置文件时才进行设置
加载,这是安全的,因为尚未计算导数变量......

-S 对所有 .SH 文件执行变量替换。 您可以将其与
-f 切换以传播您喜欢的任何配置。

-U 符号=
预设 符号 承担空值。 也可以使用 '-U 符号'
这将设置 符号 'undef'。

-V 打印版本号 元配置 产生了这个 配置 脚本
并退出。

运行 环境
启动后, 配置 创建一个本地 UU 目录并从那里运行。 目录
当配置结束时被删除,但这意味着您必须从一个地方运行脚本
您可以写入,即不能从只读文件系统写入。

你可以跑 配置 远程虽然,如:

../包/配置

配置本地不存在的源。 所有生成的文件都会被放入
运行脚本的目录。 由于 src.U 完成了这个魔术
单位,这是设置 $源码$rsrc 指向包源的变量。 那
路径是完整的还是相对的,取决于是否 配置 通过完整或
相对路径。

从内部 UU 子目录,你可以使用 $rsrc 访问源文件(单位
引用源文件链接提示应始终使用此机制,而不是假定
文件存在于父目录中)。 所有的 Makefile 都应该使用 $src 变量
作为指向构建目录顶部的源的指针(其中 配置 正在运行),
直接或通过 VPATH 设置。

跑步时 配置 远程,.SH 文件被提取到构建目录中,而不是
在源树中。 然而,它需要某种 使 支持编译
构建目录中的内容,而源代码位于其他地方。

运用 魔术 重新定义
通过利用 -M 切换,一些神奇的重新映射可能会发生在一个 配置文件
文件。 该文件需要包含在 配置文件当然,但毕竟
其他需要的包含文件。 即:

#include "config.h"
...
... other 夹杂物 ...
...
#include "confmagic.h"

通常情况下, 配置文件 将尝试重新映射 复制() on 内存() 如果不 复制() is
本地可用,或转换 叉子 必要时,因此使其无用
打扰了 有_VFORK 符号。

这个配置魔法记录在 Glossary 文件中。

单位 模板
有一组单元模板 元配置 源目录,旨在
被(尚未编写的)程序用于为各种类型快速生成新单元
情况。 这个未完成的项目没有文档,但我想我会提到它
在手册页中,以防您想自己做然后贡献它...

作者


拉里·沃尔[电子邮件保护]> 2.0 版。
哈兰·斯坦恩[电子邮件保护]> 用于重要的单元扩展。
拉斐尔·曼弗雷迪[电子邮件保护]>.
许多其他贡献者为 元配置 单位。 请参阅信用文件以获取列表。

使用 onworks.net 服务在线使用 metaconfig


免费服务器和工作站

下载 Windows 和 Linux 应用程序

Linux 命令

Ad