2保持自由软件的自由¶
本章讨论了如何确保GNU软件避免法律困难和其他相关问题。
2.1参考专有程序¶
在任何情况下,都不要在你在GNU上的工作!(或任何其他专有程序。)
如果你模糊地记得Unix程序的内部结构,这并不绝对意味着你不能模仿它,但是尽量按照不同的路线组织内部模仿,因为这可能会使Unix版本的详细信息与你的结果不相关,也不相似。
例如,Unix实用程序通常优化为最小化记忆使用;如果你改为追求速度,你的程序将非常不同。您可以将整个输入文件保存在内存中并扫描它而不是使用stdio。使用更智能的算法发现更多比Unix程序更新。消除使用临时文件。做它在一个过程中完成,而不是在两个过程中(我们是在汇编程序中完成的)。
或者,相反,强调简单而不是速度。对于一些人应用程序,今天计算机的速度使算法变得更简单足够。
或者追求普遍性。例如,Unix程序通常具有静态表或固定大小的字符串,用于任意限制;使用取而代之的是动态分配。确保您的程序处理NUL和输入文件中的其他有趣字符。添加编程语言并用该语言编写程序的一部分。
或者将程序的某些部分转换为独立可用的库。或者使用简单的垃圾收集器,而不是在释放内存,或使用新的GNU工具,如obstack。
2.2接受出资¶
如果您正在使用的程序受自由软件的版权保护基础,然后当其他人发送给您一段代码以添加到程序,我们需要法律文件来使用它-正如我们要求你那样最初签署文件。每个做出不平凡的事的人对项目的贡献必须按顺序签署某种法律文件我们对该计划拥有明确的所有权;主要作者本身并不是够了。
因此,在添加其他人的任何贡献之前,请告诉我们,这样我们可以安排拿到文件。然后等我们告诉你在您实际使用贡献。
这在发布程序之前和之后都适用。如果您收到了用于修复错误的差异,并且它们进行了重大更改,我们这一改变需要法律文件。
这也适用于注释和文档文件。对于版权法律、评论和准则只是文字。版权适用于文本,所以我们需要各种法律文件。
我们知道要求法律文件是令人沮丧的;令人沮丧的是我们也是。但如果你不等待,你就会陷入困境例如,如果贡献者的雇主不签署免责声明怎么办?您可能需要再次取出该代码!
你不需要在这里或那里更改几行,因为就版权而言,它们并不重要。此外,你不需要如果你从建议中得到的只是一些想法,而不是实际的代码您使用的。例如,如果有人向您发送了一个实现,但你为同一个想法编写不同的实现,你不需要拿到文件。
最糟糕的是你忘了告诉我们另一个贡献者。有朝一日,我们在法庭上可能会非常尴尬结果。
我们为GNU包的维护者提供了更详细的建议。如果你已达到维护GNU程序的阶段(无论是否发布是否),请查看:请参阅法律事项在里面GNU维护人员信息。
2.3商标¶
请不要在GNU软件中包含任何商标确认文件包或文档。
商标承认是这样和那样的声明so-and-so的商标。GNU项目不反对商标的想法,但这些承认感觉像是磕头,而且对它们没有法律要求,所以我们不使用它们。
对于其他人的商标,法律要求是避免以读者可能合理理解的方式使用它们命名或标记我们自己的程序或活动。例如,由于我们确信,“Objective C”是(或至少是)一个商标我们提供了一个“Objective C语言的编译器”而不是“Objective C编译器”。后者的意思是前者的简短说法,但没有明确说明关系,因此可能会被误解为使用“客观C”作为编译器的标签,而不是语言的标签。
请不要在中使用“win”作为Microsoft Windows的缩写GNU软件或文档。在黑客术语中,呼叫“胜利”是一种赞扬。你可以自由表扬如果您愿意,可以单独使用Microsoft Windows,但请不要在GNU包。请完整填写“Windows”,或将其缩写为“w.”参见系统类型之间的可移植性。
3通用程序设计¶
本章讨论了您应该考虑的一些问题在设计程序时考虑。
3.1使用哪种语言¶
当你想使用一种编译速度很高的语言时速度,最好的语言是C。C++也可以,但请不要大量使用模板。如果你编译Java,那么它也是。
当不需要最高效率时,通常使用其他语言在自由软件社区中,如Lisp、Scheme、Python、Ruby和Java也可以。由GNU Guile实施的Scheme发挥了GNU系统中的特殊角色:它是扩展用C/C++编写的程序,也是一种很好的语言应用范围。GNU组件使用Guile和Scheme的数量越多,更多的用户能够扩展和组合它们(请参见Emacs公司论文在里面GNU Guile参考手册).
许多程序设计为可扩展的:它们包括一个解释器对于一种比C语言更高级的语言,通常程序的大部分也是用那种语言写的。Emacs的编辑率先做到了这一点技术。
GNU软件的标准可扩展性解释器是Guile(https://www.gnu.org/software/guile/),它实现语言方案(Lisp的一种特别简洁的方言)。Guile还包括GTK+/GNOME的绑定,使其适用于在Guile中编写现代GUI功能。我们不拒绝节目用其他“脚本语言”编写,如Perl和Python,但使用Guile是实现GNU系统。
3.2与其他实现的兼容性¶
除了偶尔的例外,GNU的实用程序和库应该与Berkeley Unix中的向上兼容,并且向上兼容如果标准C规定其行为,如果POSIX指定,则与POSIX向上兼容他们的行为。
当这些标准发生冲突时,提供兼容性很有用模式。
标准C和POSIX禁止多种扩展。感觉无论如何都可以自由进行扩展,并包括--美国国家标准协会’,‘--posix公司',或'--相容的'选项将其关闭。然而,如果扩展有很大的机会打破任何真实的程序或脚本,则它不是真正的向上兼容。所以你应该尝试重新设计其接口,使其向上兼容。
如果环境变量POSIXLY_CORRECT公司
已定义(即使是定义为null值)。请让您的程序认识到这一点变量(如适用)。
当功能仅由用户使用时(不由程序或命令使用文件),并且在Unix中做得很差,可以随意替换它与完全不同和更好的东西。(例如,不及物动词
替换为Emacs。)但提供兼容的功能。(有一个免费的不及物动词
克隆,所以我们提供它。)
欢迎使用其他有用的功能,无论他们有任何先例。
3.3使用非标准特征¶
许多已经存在的GNU设施支持许多方便的可比Unix设施的扩展。是否使用这些实现程序的扩展是一个难题。
一方面,使用扩展可以使程序更干净。另一方面,人们将无法构建程序除非其他GNU工具可用。这可能会导致在较少种类的机器上工作的程序。
通过一些扩展,很容易提供这两种选择。例如,可以使用“关键字”定义函数内联
并将其定义为一个宏,以扩展为内联
或没有,取决于编译器。
一般来说,如果可以的话,最好不要使用扩展直接不用它们,但如果它们是一个很大的进步。
这个规则的一个例外是大型的既定程序(例如Emacs),可在多种系统上运行。在中使用GNU扩展这样的程序会让许多用户不高兴,所以我们不会这样做。
另一个例外是用于编译的程序:必须使用其他编译器编译的任何内容,以便引导GNU编译工具。如果这些需要GNU编译器,那么没有人可以在没有安装它们的情况下编译它们已经。在某些情况下,这会非常麻烦。
3.4标准C和预标准C¶
1989年标准C已经足够广泛,现在可以使用它程序中的功能。有一个例外:永远不要使用标准C的“三角图”特征。
标准C的1999版和2011版不完全受支持在所有平台上。如果您的目标是支持编译GCC以外的编译器,您不应该要求这些C程序中的功能。使用这些功能是可以的编译器支持它们时有条件地。
如果您的程序只打算用GCC编译,那么您可以如果GCC支持这些功能,则在它们提供大量功能时使用它们利益。
然而,在大多数程序中很容易支持预标准编译器,所以,如果你知道怎么做,请放心。
支持预设标准C,而不是在中编写函数定义标准原型形式,
以这样的预设风格编写定义,
并使用单独的声明指定参数原型:
无论如何,您需要在头文件中使用这样的声明,以获得好处调用函数的所有文件中的原型。还有一次你有声明,通常写下预标准样式的函数定义。
此技术不适用于小于的整数类型整数
。如果你认为一个参数的类型比整数
,声明为整数
而不是。
在一些特殊情况下,这种技术很难使用。对于例如,如果函数参数需要保存系统类型开发(_t)
,你遇到麻烦了,因为开发(_t)
短于整数
在某些机器上;但你不能使用整数
相反,因为开发(_t)
宽度大于整数
在一些机器上。那里没有一种类型可以在非标准的所有机器上安全使用定义。支持非标准C并通过此类参数是检查开发(_t)
使用Autoconf并选择相应的参数类型。这可能不值得费事。
为了支持不识别原型,您可能希望使用这样的预处理器宏:
/*声明通用外部函数的原型*/#如果定义了(__STDC__)||定义了(WINDOWSNT)#定义P_(原型)原型#其他#定义P_(原型)()#结尾
3.5有条件编译¶
当支持构建您的我们喜欢使用的程序如果(…)
条件编译,与前一种情况一样,编译器能够执行更广泛的操作检查所有可能的代码路径。
例如,请写
而不是:
#如果定义为HAS_FOO...#其他...#结尾
像GCC这样的现代编译器将在中生成完全相同的代码这两种情况下,我们一直在使用类似的技术,并取得了良好的成功在几个项目中。当然,前一种方法假设HAS_FOO公司
定义为0或1。
虽然这不是解决所有可移植性问题的灵丹妙药,并且并不总是合适的,遵循此策略会节省GCC开发人员每年要花费数小时甚至数天的时间。
对于类似函数的宏,如可逆_CC_模式
在里面GCC不能简单用于如果(…)
语句,有简单的解决方法。只需引入另一个宏HAS_REVERSIBLE_CC_模式
如以下示例所示:
#ifdef可逆_CC_MODE#定义HAS_REVERSIBLE_CC_MODE 1#其他#定义HAS_REVERSIBLE_CC_MODE 0#结尾
4所有程序的程序行为¶
本章描述了编写健壮代码的惯例软件。它还描述了错误消息的通用标准命令行界面,以及库的行为方式。
4.1非GNU标准¶
GNU项目将其他组织发布的标准视为建议,而不是命令。我们考虑这些标准,但我们没有“服从”他们。在开发GNU程序时,您应该实现当它构成GNU系统时,外部标准的规范从客观的角度来看,总体上更好。如果没有,你就不应该这样做。
在大多数情况下,遵循已发布的标准便于用户——这意味着他们的程序或脚本将更有效便携。例如,GCC几乎实现了该标准规定的标准C。C程序开发人员会如果没有,那就不开心。GNU实用程序大多遵循POSIX.2规范;shell脚本编写者和用户将如果我们的程序不兼容,我们会很不高兴。
但我们并没有严格遵循这些规范是我们决定不遵循的具体要点,以便让GNU系统更好地为用户服务。
例如,标准C表示,几乎所有对C的扩展都是禁止。真傻!GCC实现了许多扩展,其中一些后来被采纳为标准的一部分。如果你想要这些构造以根据标准“要求”给出错误消息,必须指定“--学究式的',它的实现只是为了我们可以说“GCC是标准的100%实现”,而不是因为有任何理由实际使用它。
POSIX.2规定“数据流'和'杜'必须按输出大小默认单位为512字节。用户需要的单位是1k,所以这是我们默认的做法。如果你想要这种荒谬的行为POSIX“必需”时,必须设置环境变量‘POSIXLY_CORRECT公司”(最初将被命名‘POSIX_ME_硬度’).
GNU实用程序也偏离了POSIX.2规范的字母当它们支持长名称的命令行选项和混合时带有普通参数的选项。与POSIX在实践中从来都不是问题,它非常有用。
特别是,不要拒绝新功能或删除旧功能,仅仅因为标准说它是“禁止的”或“不推荐的”。
4.2编写健壮程序¶
避免对长度或数量的任意限制任何数据结构,包括文件名、行、文件和符号,通过分配所有数据结构都是动态的。在大多数Unix实用程序中,“长线被自动截断”。这在GNU实用程序中是不可接受的。
读取文件的实用程序不应删除NUL字符或任何其他字符非打印字符。程序应能与多字节一起正常工作字符编码,如UTF-8。您可以使用libiconv来处理一系列编码。
检查每个系统调用是否返回错误,除非您知道自己愿意忽略错误。包括系统错误文本(来自斯特雷罗
,或同等)英寸每一个错误消息由于系统调用失败以及文件名如果有,以及实用程序的名称。只是“无法打开foo.c”或“stat failed”是不够的。
检查每次呼叫malloc公司
或重新分配
看看它是否返回无效的
.检查重新分配
即使您正在制作块体较小;在将块大小四舍五入为2的系统中,重新分配
如果你要求更少的空间,可能会得到不同的块。
你必须预料到自由的
更改释放。任何你想从街区取的东西,你必须在打电话自由的
。
如果malloc公司
在非交互式程序中失败,这是致命的错误。在交互式程序中(从用户),最好中止命令并返回命令读卡器循环。这允许用户终止其他进程以释放虚拟内存,然后重试该命令。
使用获取opt_long
解码参数,除非参数语法使这变得不合理。
当在程序执行期间写入静态存储时,请使用显式C代码来初始化它。这样,重新启动程序(无需重新加载)或其一部分将重新初始化变量。为不会被更改。
尽量避免使用低级接口来模糊Unix数据结构(例如作为文件目录、utmp或内核内存布局),因为不太可能兼容工作。如果你需要找到所有文件在目录中,使用读目录
或其他高级接口。GNU兼容支持这些功能。
首选的信号处理设施是BSD变体信号
和POSIX信号作用
功能;这个替代USG信号
接口是一种低劣的设计。
如今,使用POSIX信号函数可能是最简单的方法使程序可移植。如果您使用信号
,然后在GNU/Linux上运行GNU libc版本1的系统,您应该包括bsd/信号。小时而不是信号。小时,以便获得BSD行为。是否支持系统取决于您信号
只有美国政府的行为,或者放弃。
在检测到“不可能”情况的错误检查中,只需中止即可。打印任何消息通常都没有意义。这些检查指示存在错误。无论谁想要修复这些错误,都会读取源代码并运行调试器。所以解释一下这个问题源代码中的注释。相关数据将以变量表示很容易用调试器检查,所以移动它们没有意义其他地方。
不要将错误计数用作程序的退出状态。那不行,因为退出状态值限制为8位(0到255)。一次运行程序可能有256个错误;如果尝试返回256作为退出状态,则父进程将看到0作为状态,并且显示程序已成功。
如果创建临时文件,请检查TMPDIR公司
环境变量;如果定义了该变量,请使用指定的目录而不是/临时管理计划。
此外,请注意,当在全球可写目录中创建临时文件。在C中,您可以通过以下方式创建临时文件来避免此问题:
fd=打开(文件名,O_WRONLY|O_CREAT|O_EXCL,0600);
或使用mkstemps公司
来自Gnulib的函数(参见mkstemps公司在里面格努利布).
在bash中,使用集合-C
(长名称夜蛾
)为了避免这种情况问题。此外建立临时文件
实用程序是更通用的从shell脚本创建临时文件的解决方案(参见mktemp调用在里面GNU内核).
4.3图书馆行为¶
尝试使库函数可重入。如果他们需要动态存储分配,除了的malloc公司
自身。
以下是库的某些名称约定,以避免命名冲突。
为库选择一个长度超过两个字符的名称前缀。所有外部函数和变量名称都应该以前缀。此外,在任何给定的库成员。这通常意味着将每一个放在一个单独的源文件。
如果总是使用两个外部符号,则会出现例外情况这样,任何合理的程序都无法在没有其他;然后它们可以放在同一个文件中。
未记录用户入口点的外部符号名称应以“”开头_’. “_'应该是后跟库的选定名称前缀,以防止与其他库冲突。这些可以放在相同的文件中用户入口点(如果您愿意)。
静态函数和变量可以随意使用,也无需使用符合任何命名约定。
编译器发出的错误消息应如下所示:
如果要提及列号,请使用以下格式之一:
源文件以下为:行号以下为:柱以下为:消息
源文件以下为:行号。柱以下为:消息
行号应该从文件开头的1开始,并且列号应该从行首的1开始。(这两种约定都是为了兼容而选择的。)计算列号,假定空格和所有ASCII打印字符宽度相等,并假设tab每8列停止一次。对于非ASCII字符,在UTF-8语言环境;GNU libc和GNU gnulib提供了合适的wc宽度
功能。
错误消息还可以给出起始和结束位置错误的文本。有几种格式,您可以避免重复的行号等冗余信息。以下是可能的格式:
源文件以下为:第1行。第1列-第2行。第2列以下为:消息
源文件以下为:第1行。第1列-第2列以下为:消息
源文件以下为:第1行-第2行以下为:消息
当错误传播到多个文件时,可以使用以下格式:
文件1以下为:第1行。第1列-文件2以下为:第2行。第2列以下为:消息
来自其他非交互式程序的错误消息应如下所示:
当有合适的源文件时,或如下所示:
当没有相关的源文件时。
如果要提及列编号,请使用以下格式:
程序以下为:源文件以下为:行号以下为:柱以下为:消息
在交互式程序中(从终端),最好不要在错误中包含程序名消息。指示正在运行哪个程序的位置位于提示或屏幕布局。(当同一程序运行时来自终端以外的源的输入,它不是交互式的,并且最好使用非交互式样式打印错误消息。)
字符串消息当它跟在程序名和/或文件名后面,因为这不是句子的开头。(该句在概念上从行首。)此外,它不应以句点结束。
来自交互式程序的错误消息以及其他消息,如用法信息,应以大写字母开头。但他们不应该以句点结束。
4.5接口通用标准¶
请不要使实用程序的行为依赖于用于调用它。有时使用不同的名称,这不应该改变它的功能。因此,如果您制作foo公司链接到最小二乘法,程序应表现为无论使用哪个名称来调用它,都是相同的。
相反,使用运行时选项或编译开关或两者都可以在替代行为中进行选择。您还可以构建两个版本使用不同的默认行为,并安装它们用两个不同的名字。
同样,请不要使命令行程序的行为取决于作为标准输出的输出设备类型或标准输入。设备独立性是系统设计;不要仅仅为了拯救某人而妥协不时键入一个选项。(错误消息语法的变化当使用终端是可以的,因为这是一个附带问题,人们不依赖。)
如果您认为当输出到终端,当输出是文件或管道,则通常最好将默认行为设置为这对于终端的输出很有用,并且可以选择其他行为。您还可以构建两个不同版本的具有不同名称的程序。
对于在某些情况下输出为二进制数据。将这样的输出发送到终端是无用的,可以引起麻烦。如果这样的程序通常将其输出发送到stdout,在这种情况下,它应该检测输出是终端和而是给出一条错误消息。这个-(f)
选项应覆盖这个异常,因此允许输出到终端。
兼容性要求某些程序依赖于输出类型设备。如果最小二乘法
或第页
没有这样做以所有用户期望的方式。在某些情况下,我们补充程序的首选替代版本不依赖于输出设备类型。例如,我们提供了一个目录
程序很多喜欢最小二乘法
除了它的默认输出格式总是多列格式。
4.6查找程序的可执行文件和相关文件¶
程序可能需要找到启动时使用的可执行文件,因此重新启动同一程序。可能需要找到相关的文件,无论是源文件还是由构建构建的文件它在运行时使用。
找到它们的方法是从查看argv[0](argv[0)
。
如果该字符串包含斜杠,则按照惯例为可执行文件及其目录部分是包含可执行文件。这是找不到程序的情况通过路径
,这通常意味着它是建造的,但不是安装,并从构建目录运行。程序可以使用argv[0](argv[0)
文件名以重新启动自身,并可以在其关联文件的目录部分。如果该文件名不是绝对值,则它相对于程序已启动。
如果argv[0](argv[0)
不包含斜杠,它是一个命令名可执行文件是通过找到的路径
。程序应搜索目录中的名称路径
,口译。作为程序启动时的当前工作目录。
如果此过程找到可执行文件,我们将其命名为在中找到调用目录.程序应检查以便在该目录中存在它所需要的关联文件。
如果程序的可执行文件通常构建在主构建目录,并且主构建目录包含关联的文件(可能包括子目录),程序应该查看调用目录的父目录,检查关联的主构建目录应包含的文件和子目录。
如果调用目录不包含所需内容,但可执行文件名是一个符号链接,程序应该尝试使用链接目标的包含目录作为调用目录。
如果这个过程没有找到一个调用目录有效-正常情况下,通过找到已安装程序的情况路径
-程序应该在程序的makefile安装它们的目录。请参见安装目录的变量。
在中提供有效信息argv[0](argv[0)
是惯例,不是放心。启动其他项目的良好项目,如贝壳,遵循惯例;您的代码也应该遵循它,当启动其他程序。但始终可以启动编程并在中给出无意义的值argv[0](argv[0)
。
因此,任何需要知道其位置的程序可执行文件或其他关联文件的可执行文件应提供用户环境变量来显式指定这些位置。
不要给予特殊特权,例如设置用户标识符
位,指向将启发式搜索关联文件的程序或者在以这种方式调用它们自己的可执行文件时。限制这一点以硬编码方式查找关联文件的程序的权限安装位置,例如/用户使用程序和/等。
请参见Bourne Shell变量在里面Bash参考手册,有关的详细信息路径
。
4.7图形界面标准¶
当您编写提供图形用户界面的程序时,请使用GTK+工具包使其与X Window系统配合使用或GNUstep工具包,除非功能特别需要一些替代方法(例如,“在控制台模式”)。
此外,请提供命令行界面来控制功能。(在许多情况下,图形用户界面可以是调用命令行程序的单独程序。)这是这样就可以从脚本中完成相同的工作。
还请考虑提供一个D总线接口以供其他运行程序,例如在GNOME中。(GNOME用于使用CORBA但这正逐步被淘汰。)此外,考虑提供一个库接口(供C使用),可能还提供一个键盘驱动的控制台界面(供用户从控制台使用模式)。一旦您完成了提供功能和图形界面,这些不会有太多额外的工作。
请使您的程序与访问技术互操作,例如屏幕阅读器(请参阅https://www.gnu.org/accessibility/accessability.html). 这应该是如果使用GTK+,则为自动。
4.8命令行接口标准¶
遵循POSIX指南对于程序的命令行选项。最简单的方法是使用获得选择权
来解析它们。注意,GNU版本的获得选择权
通常允许参数中的任何选项,除非特殊参数'--'被使用。这不是POSIX指定;它是一个GNU扩展。
请定义与单字母Unix样式选项。我们希望让GNU拥有更多用户这样很友好。使用GNU功能很容易做到这一点获取opt_long
。
长名称选项的优点之一是可以每个程序的一致性。例如,用户应该能够期望任何具有“verbose”选项的GNU程序拼写准确'--冗长的’. 要实现这种一致性,请看选择选项名称时的常用长选项名称表用于您的程序(请参见长期权表).
将文件名作为普通参数提供给仅为输入文件;可以使用选项指定任何输出文件(最好是'-o个'或'--输出’). 即使您允许输出文件名作为兼容性的普通参数,尝试提供选项作为另一种指定方法。这将导致更大的一致性在GNU实用程序中,用户需要记住的特性更少。
所有程序都应支持两个标准选项:--版本’和'--帮助’. CGI程序应该接受这些命令行选项,如果作为路径信息
; 例如,访问'http://example.org/p.cgi/-help
'在浏览器中应该输出与调用相同的信息'p.cgi—帮助'来自命令行。
4.8.2--帮助¶
标准--帮助
选项应输出简要文档如何在标准输出上调用程序,然后退出成功。一旦发生此情况,应忽略其他选项和参数则程序不应执行其正常功能。
接近'结尾--帮助'选项的输出,请放置行提供错误报告的电子邮件地址,即程序包的主页(通常为“https://www.gnu.org/software网站/包装
'),以及使用GNU程序的帮助的通用页面。格式应如下所示:
将错误报告给:邮寄地址
包装主页:<https://www.gnu.org/software网站/包装/>使用GNU软件的一般帮助:<https://www.gnu.org/gethelp/>
可以提及其他适当的邮件列表和网页。
4.9动态插件接口标准¶
保持免费程序自由的另一个方面是令人鼓舞的免费插件的开发,阻碍了专有插件。许多GNU程序不会有任何类似的插件,但那些有插件的插件应该遵循这些实践。
首先,通用插件体系结构设计应紧密结合插件到原始代码,这样插件和基础程序是一个扩展程序的一部分。例如,对于GCC,插件接收并修改GCC的内部数据结构,等等用基本GCC清楚地形成一个扩展程序。
其次,您应该要求插件开发人员确认插件是根据适当的许可证发布的。这应该是通过简单的程序性检查来实施。对于GCC,同样适用于例如,插件必须定义全局符号插件_is_GPL_兼容
,从而断言插件是根据GPL兼容许可证发布(请参阅插件在里面GCC内部构件).
通过将此检查添加到程序中,您不会创建新的法律要求。GPL本身要求插件是自由软件,许可兼容。只要你遵守了上面的第一条规则为了使插件与您的原始程序紧密相连,GPL和AGPL已经要求在兼容的许可证。插件中的符号定义或任何等效项在您的程序中工作得最好,这会让任何可能分发专有插件以合法保护自己。如果是一个案例关于这件事,我们可以把这个符号作为证据插件开发人员知道许可证有这个要求。
4.10长期期权表¶
下面是GNU程序使用的长选项表。确实如此不完整,但我们的目标是列出新程序可能的所有选项希望与兼容。如果使用表中没有的名称,请发送bug-standards@gnu.org他们的列表,以及他们的意思,所以我们可以更新表格。
- ‘出票后’
‘-N个中的'焦油
。
- ‘全部的’
‘-一个中的'杜
,最小二乘法
,纳米
,stty公司
,uname公司
,和展开
。
- ‘所有文本’
‘-一个中的'差异
。
- ‘几乎所有’
‘-A类中的'最小二乘法
。
- ‘追加’
‘-一个中的'etags公司
,球座
,时间
;‘-第页中的'焦油
。
- ‘档案文件’
‘-一个中的'内容提供商
。
- ‘档案名称’
‘-n个中的'沙尔
。
- ‘arg长度’
‘-我中的'4米
。
- ‘ascii公司’
‘-一个中的'差异
。
- ‘分配’
‘-v(v)中的'目瞪口呆
。
- ‘假设-新’
‘-W公司中的'制作
。
- ‘假设’
‘-o个中的'制作
。
- ‘自动检查’
‘-一个中的'重新编码
。
- ‘自动分页器’
‘-一个中的'wdiff公司
。
- ‘自动参考’
‘-A类中的'聚四氟乙烯
。
- ‘避免带’
‘-n个中的'wdiff公司
。
- ‘背景’
对于服务器程序,请在后台运行。
- ‘后拱’
‘-B中的'插件
。
- ‘基名’
‘-(f)中的'沙尔
。
- ‘批处理’
用于GDB。
- ‘波特’
用于GDB。
- ‘之前’
‘-b条中的'战术通信
。
- ‘二元的’
‘-b条中的'备份文件
和差异
。
- ‘每码比特数’
‘-b条中的'沙尔
。
- ‘块状尺寸’
用于备份文件
和焦油
。
- ‘阻碍’
‘-b条中的'头
和尾
。
- ‘防弹衣’
‘-b条中的'聚四氟乙烯
。
- ‘简明的’
用于各种程序中,以缩短输出。
- ‘字节’
‘-c(c)中的'头
,分裂
、和尾
。
- ‘c(c)
++
’
‘-C类中的'etags公司
。
- ‘连锁’
‘-A类中的'焦油
。
- ‘光盘’
在各种程序中用于指定要使用的目录。
- ‘变化’
‘-c(c)中的'文件名
和大杂烩
。
- ‘分类’
‘-F类中的'最小二乘法
。
- ‘冒号’
‘-c(c)中的'重新编码
。
- ‘命令’
‘-c(c)中的'苏
;‘-x个'在GDB中。
- ‘比较’
‘-d日中的'焦油
。
- ‘兼容性’
用于目瞪口呆
。
- ‘压缩’
‘-Z轴中的'焦油
和沙尔
。
- ‘连接’
‘-A类中的'焦油
。
- ‘确认’
‘-w个中的'焦油
。
- ‘上下文’
用于差异
。
- ‘版权所有’
‘-W左拷贝中的'目瞪口呆
。
- ‘版权’
‘-C类中的'聚四氟乙烯
,重新编码
、和wdiff公司
;‘-W版权所有中的'目瞪口呆
。
- ‘核心’
用于GDB。
- ‘计数’
‘-q个中的'谁
。
- ‘计数链’
‘-我中的'杜
。
- ‘创造’
用于焦油
和备份文件
。
- ‘切割标记’
‘-c(c)中的'沙尔
。
- ‘外部参照’
‘-x个中的'插件
。
- ‘日期’
‘-d日中的'触摸
。
- ‘调试’
‘-d日中的'制作
和4米
;‘-t吨“在野牛队。
- ‘定义’
‘-D类中的'4米
。
- ‘定义’
‘-d日'在野牛和插件
。
- ‘删除’
‘-D类中的'焦油
。
- ‘取消引用’
‘-L(左)中的'文件名
,大杂烩
,备份文件
,杜
,最小二乘法
、和焦油
。
- ‘取消引用参数’
‘-D类中的'杜
。
- ‘装置’
指定I/O设备(特殊文件名)。
- ‘变音符号’
‘-d日中的'重新编码
。
- ‘字典顺序’
‘-d日中的'看
。
- ‘差异’
‘-d日中的'焦油
。
- ‘数字’
‘-n个中的'csplit(csplit)
。
- ‘目录’
在各种程序中指定要使用的目录。在最小二乘法
,它表示显示目录本身而不是其内容。在rm(毫米)
和自然对数
,这意味着不处理指向目录的链接特别是。
- ‘抛弃一切’
‘-x个中的'带
。
- ‘discard-locals公司’
‘-X(X)中的'带
。
- ‘干式运行’
‘-n个中的'制作
。
- ‘预计起飞时间’
‘-e(电子)中的'差异
。
- ‘elide-空’
‘-z(z)中的'csplit(csplit)
。
- ‘结束删除’
‘-x个中的'wdiff公司
。
- ‘端嵌件’
‘-z(z)中的'wdiff公司
。
- ‘整个新文件’
‘-N个中的'差异
。
- ‘环境保护’
‘-e(电子)中的'制作
。
- ‘电动势’
‘-e(电子)中的'参数代换
。
- ‘纪元’
用于GDB。
- ‘误差极限’
用于制造信息
。
- ‘错误输出’
‘-o个中的'4米
。
- ‘逃跑’
‘-b条中的'最小二乘法
。
- ‘从中排除’
‘-X(X)中的'焦油
。
- ‘执行官’
用于GDB。
- ‘出口’
‘-x个中的'参数代换
。
- ‘退出-0’
‘-e(电子)中的'取消遮蔽
。
- ‘展开选项卡’
‘-t吨中的'差异
。
- ‘表达’
‘-e(电子)中的'塞德
。
- ‘仅限外部’
‘-克中的'纳米
。
- ‘提取物’
‘-我中的'备份文件
;‘-x个中的'焦油
。
- ‘面’
‘-(f)中的'手指
。
- ‘快速的’
‘-(f)中的'苏
。
- ‘致命警告’
‘-E类中的'4米
。
- ‘文件’
‘-(f)中的'目瞪口呆
,信息
,制作
,公吨
,塞德
、和焦油
。
- ‘场分隔器’
‘-F类中的'目瞪口呆
。
- ‘文件前缀’
‘-b条“在野牛队。
- ‘文件类型’
‘-F类中的'最小二乘法
。
- ‘文件-来自’
‘-T型中的'焦油
。
- ‘填充柱’
用于制造信息
。
- ‘旗杆操纵’
‘-F类中的'聚四氟乙烯
。
- ‘固定输出文件’
‘-年“在野牛队。
- ‘跟随’
‘-(f)中的'尾
。
- ‘脚注样式’
用于制造信息
。
- ‘力’
‘-(f)中的'内容提供商
,自然对数
,毫伏
、和rm(毫米)
。
- ‘强制前缀’
‘-F类中的'沙尔
。
- ‘前景’
对于服务器程序,在前台运行;换句话说,不要做任何特殊的事情来运行服务器在背景中。
- ‘格式’
用于最小二乘法
,时间
、和聚四氟乙烯
。
- ‘冷冻状态’
‘-F类中的'4米
。
- ‘全名’
用于GDB。
- ‘间隙尺寸’
‘-克中的'聚四氟乙烯
。
- ‘得到’
‘-x个中的'焦油
。
- ‘图形’
‘-我中的'ul公司
。
- ‘绘图’
‘-克中的'重新编码
。
- ‘组’
‘-克中的'安装
。
- ‘gzip公司’
‘-z(z)中的'焦油
和沙尔
。
- ‘散列大小’
‘-H(H)中的'4米
。
- ‘收割台’
‘-小时中的'反汇编
和重新编码
- ‘标题’
‘-H(H)中的'谁
。
- ‘帮助’
用于询问简短的使用信息。
- ‘此处分隔符’
‘-d日中的'沙尔
。
- ‘藏匿控制区’
‘-q个中的'最小二乘法
。
- ‘html格式’
在制造信息
,输出HTML。
- ‘虚度’
‘-u个中的'谁
。
- ‘条件编译’
‘-D类中的'差异
。
- ‘忽视’
‘-我中的'最小二乘法
;‘-x个中的'重新编码
。
- ‘忽略所有空间’
‘-w个中的'差异
。
- ‘忽略支持’
‘-B中的'最小二乘法
。
- ‘忽略空行’
‘-B中的'差异
。
- ‘无知的人’
‘-(f)中的'看
和聚四氟乙烯
;‘-我中的'差异
和wdiff公司
。
- ‘忽略错误’
‘-我中的'制作
。
- ‘忽略文件’
‘-我中的'聚四氟乙烯
。
- ‘无知诱导’
‘-我中的'etags公司
。
- ‘无信号文件’
‘-(f)“在Oleo中。
- ‘忽视中断’
‘-我中的'球座
。
- ‘忽略匹配线’
‘-我中的'差异
。
- ‘忽略空间更改’
‘-b条中的'差异
。
- ‘忽略零’
‘-我中的'焦油
。
- ‘包括’
‘-我中的'etags公司
;‘-我中的'4米
。
- ‘包括dir’
‘-我中的'制作
。
- ‘增量的’
‘-G公司中的'焦油
。
- ‘信息’
‘-我’, ‘-我',和'-米“在手指中。
- ‘初始文件’
在某些程序中,指定要读取的文件名作为用户的init文件。
- ‘最初的’
‘-我中的'扩大
。
- ‘初始标签’
‘-T型中的'差异
。
- ‘索引节点’
‘-我中的'最小二乘法
。
- ‘交互式’
‘-我中的'内容提供商
,自然对数
,毫伏
,rm(毫米)
;‘-e(电子)中的'4米
;‘-第页中的'参数代换
;‘-w个中的'焦油
。
- ‘混合型’
‘-第页中的'沙尔
。
- ‘iso-8601标准’
用于日期
- ‘工作’
‘-j个中的'制作
。
- ‘公正打印’
‘-n个中的'制作
。
- ‘继续前进’
‘-k个中的'制作
。
- ‘保留文件’
‘-k个中的'csplit(csplit)
。
- ‘千字节’
‘-k个中的'杜
和最小二乘法
。
- ‘语言’
‘-我中的'etags公司
。
- ‘less模式’
‘-我中的'wdiff公司
。
- ‘级别-gzip’
‘-克中的'沙尔
。
- ‘行字节’
‘-C类中的'分裂
。
- ‘线’
用于分裂
,头
、和尾
。
- ‘链接’
‘-我中的'备份文件
。
- ‘皮棉’
- ‘皮棉’
用于目瞪口呆
。
- ‘列表’
‘-t吨中的'备份文件
;‘-我中的'重新编码
。
- ‘列表’
‘-t吨中的'焦油
。
- ‘字面意义的’
‘-N个中的'最小二乘法
。
- ‘平均负荷’
‘-我中的'制作
。
- ‘登录’
用于苏
。
- ‘机器’
用于uname公司
。
- ‘宏观名称’
‘-M(M)中的'聚四氟乙烯
。
- ‘邮件’
‘-米中的'你好
和uname公司
。
- ‘make-directories公司’
‘-d日中的'备份文件
。
- ‘生成文件’
‘-(f)中的'制作
。
- ‘映射’
用于GDB。
- ‘最大参数’
‘-n个中的'参数代换
。
- ‘max-chars(最大值)’
‘-n个中的'参数代换
。
- ‘最大线’
‘-我中的'参数代换
。
- ‘最大负载’
‘-我中的'制作
。
- ‘最大利润’
‘-P(P)中的'参数代换
。
- ‘网状物’
‘-T型中的'谁
。
- ‘消息’
‘-T型中的'谁
。
- ‘最小值’
‘-d日中的'差异
。
- ‘混合uuencode’
‘-M(M)中的'沙尔
。
- ‘模式’
‘-米中的'安装
,mkdir公司
、和mkfifo公司
。
- ‘修改时间’
‘-米中的'焦油
。
- ‘多卷’
‘-M(M)中的'焦油
。
- ‘名称前缀’
‘-一个“在野牛队。
- ‘嵌套限制’
‘-L(左)中的'4米
。
- ‘网络头’
‘-一个中的'沙尔
。
- ‘新文件’
‘-W公司中的'制作
。
- ‘无既定规则’
‘-第页中的'制作
。
- ‘无字符计数’
‘-w个中的'沙尔
。
- ‘不存在颈部’
‘-x个中的'沙尔
。
- ‘无共同点’
‘-3中的'wdiff公司
。
- ‘不创造’
‘-c(c)中的'触摸
。
- ‘无定义’
‘-D类中的'etags公司
。
- ‘未删除’
‘-1中的'wdiff公司
。
- ‘无偏差’
‘-d日中的'内容提供商
。
- ‘未插入’
‘-2中的'wdiff公司
。
- ‘不继续前进’
‘-S公司中的'制作
。
- ‘no-line系列’
‘-我“在野牛队。
- ‘无管道’
‘-P(P)中的'沙尔
。
- ‘无保护(no-prof)’
‘-e(电子)中的'gprof公司
。
- ‘无雷格克斯’
‘-R(右)中的'etags公司
。
- ‘无排序’
‘-第页中的'纳米
。
- ‘无冲击’
不要打印启动初始屏幕。
- ‘无分裂’
用于制造信息
。
- ‘非静态’
‘-一个中的'gprof公司
。
- ‘无时间’
‘-E类中的'gprof公司
。
- ‘无时间戳’
‘-米中的'沙尔
。
- ‘无有效期’
用于制造信息
。
- ‘不等待’
用于emacs客户端
。
- ‘不警告’
在各种程序中用于禁止警告。
- ‘节点’
‘-n个中的'信息
。
- ‘节点名’
‘-n个中的'uname公司
。
- ‘不匹配’
‘-(f)中的'备份文件
。
- ‘nstuff公司’
‘-n个中的'反汇编
。
- ‘无效的’
‘-0中的'参数代换
。
- ‘数’
‘-n个中的'猫
。
- ‘非空数字’
‘-b条中的'猫
。
- ‘数字排序’
‘-n个中的'纳米
。
- ‘数字-uid-gid’
‘-n个中的'备份文件
和最小二乘法
。
- ‘nx(纳克斯)’
用于GDB。
- ‘老年人的’
‘-o个中的'焦油
。
- ‘旧文件’
‘-o个中的'制作
。
- ‘单文件系统’
‘-我中的'焦油
,内容提供商
、和杜
。
- ‘只有免税的’
‘-o个中的'聚四氟乙烯
。
- ‘仅限教授’
‘-(f)中的'gprof公司
。
- ‘仅限时间’
‘-F类中的'gprof公司
。
- ‘选项’
‘-o个中的'获得选择权
,fd列表
,fd安装
,fd安装
、和fdumount(数量)
。
- ‘输出’
在各种程序中,指定输出文件名。
- ‘输出-前缀’
‘-o个中的'沙尔
。
- ‘覆盖’
‘-o个中的'rm(毫米)
。
- ‘覆盖’
‘-c(c)中的'取消遮蔽
。
- ‘主人’
‘-o个中的'安装
。
- ‘分页’
‘-我中的'差异
。
- ‘段落相关的’
用于制造信息
。
- ‘父母’
‘-第页中的'mkdir公司
和rmdir(远程管理目录)
。
- ‘全部通过’
‘-第页中的'ul公司
。
- ‘直通’
‘-第页中的'备份文件
。
- ‘港口’
‘-P(P)中的'手指
。
- ‘可移植性’
‘-c(c)中的'备份文件
和焦油
。
- ‘posix公司’
用于目瞪口呆
。
- ‘前缀内置’
‘-P(P)中的'4米
。
- ‘前缀’
‘-(f)中的'csplit(csplit)
。
- ‘保存’
用于焦油
和内容提供商
。
- ‘保护环境’
‘-第页中的'苏
。
- ‘保留修改时间’
‘-米中的'备份文件
。
- ‘保留订单’
‘-秒中的'焦油
。
- ‘保留权限’
‘-第页中的'焦油
。
- ‘打印’
‘-我中的'差异
。
- ‘印刷字体’
‘-L(左)中的'合作管理计划
。
- ‘打印数据库’
‘-第页中的'制作
。
- ‘印刷目录’
‘-w个中的'制作
。
- ‘打印文件名’
‘-o个中的'纳米
。
- ‘打印symdefs’
‘-秒中的'纳米
。
- ‘打印机’
‘-第页中的'wdiff公司
。
- ‘促使’
‘-第页中的'预计起飞时间
。
- ‘代理’
指定HTTP代理。
- ‘查询用户’
‘-X(X)中的'沙尔
。
- ‘问题’
‘-q个中的'制作
。
- ‘安静的’
在许多程序中用于抑制通常的输出。每程序接受'--安静'应该接受'--沉默'作为同义词。
- ‘安静的地方’
‘-问中的'沙尔
- ‘报价名称’
‘-问中的'最小二乘法
。
- ‘雷达散射截面’
‘-n个中的'差异
。
- ‘重新间隔’
用于目瞪口呆
。
- ‘读-写块’
‘-B中的'焦油
。
- ‘readnow(阅读)’
用于GDB。
- ‘侦察’
‘-n个中的'制作
。
- ‘记录编号’
‘-R(右)中的'焦油
。
- ‘递归的’
用于文件名
,大杂烩
,内容提供商
,最小二乘法
,差异
,和rm(毫米)
。
- ‘参考’
‘-第页中的'触摸
。
- ‘参考文献’
‘-第页中的'聚四氟乙烯
。
- ‘正则表达式’
‘-第页中的'战术通信
和etags公司
。
- ‘释放’
‘-第页中的'uname公司
。
- ‘重新加载状态’
‘-R(右)中的'4米
。
- ‘重新安置’
‘-第页中的'反汇编
。
- ‘重命名’
‘-第页中的'备份文件
。
- ‘代替’
‘-我中的'参数代换
。
- ‘报告标识文件’
‘-秒中的'差异
。
- ‘重置访问时间’
‘-一个中的'备份文件
。
- ‘颠倒’
‘-第页中的'最小二乘法
和纳米
。
- ‘颠倒的’
‘-(f)中的'差异
。
- ‘右侧-左侧’
‘-R(右)中的'聚四氟乙烯
。
- ‘同阶’
‘-秒中的'焦油
。
- ‘相同的权限’
‘-第页中的'焦油
。
- ‘节约’
‘-克中的'stty公司
。
- ‘东南方’
用于GDB。
- ‘句子regexp’
‘-S公司中的'聚四氟乙烯
。
- ‘分离目录’
‘-S公司中的'杜
。
- ‘分离器’
‘-秒中的'战术通信
。
- ‘序列’
使用者重新编码
选择文件或管道以对过程进行排序。
- ‘壳’
‘-秒中的'苏
。
- ‘展示所有内容’
‘-A类中的'猫
。
- ‘show-c-功能’
‘-第页中的'差异
。
- ‘显示ends’
‘-E类中的'猫
。
- ‘展示功能线’
‘-F类中的'差异
。
- ‘展示标签’
‘-T型中的'猫
。
- ‘沉默的’
在许多程序中用于抑制通常的输出。每个程序都接受‘--沉默'应该接受'--安静'作为同义词。
- ‘大小’
‘-秒中的'最小二乘法
。
- ‘插座’
指定网络服务器用于其套接字的文件描述符,而不是打开和绑定新的套接字。这为在非特权进程中运行通常需要保留端口号。
- ‘分类’
用于最小二乘法
。
- ‘来源’
‘-W源中的'目瞪口呆
。
- ‘稀疏的’
‘-S公司中的'焦油
。
- ‘速度-大口径’
‘-H(H)中的'差异
。
- ‘拆分-at’
‘-E类中的'取消遮蔽
。
- ‘分裂尺寸限制’
‘-L(左)中的'沙尔
。
- ‘挤扁的’
‘-秒中的'猫
。
- ‘启动-删除’
‘-w个中的'wdiff公司
。
- ‘开始插入’
‘-年中的'wdiff公司
。
- ‘启动文件’
用于焦油
和差异
指定其中的哪个文件开始处理的目录。
- ‘统计学’
‘-秒中的'wdiff公司
。
- ‘标准文件列表’
‘-S公司中的'沙尔
。
- ‘停止’
‘-S公司中的'制作
。
- ‘严格的’
‘-秒中的'重新编码
。
- ‘带’
‘-秒中的'安装
。
- ‘全脱衣舞’
‘-秒中的'带
。
- ‘条带调试’
‘-S公司中的'带
。
- ‘提交人’
‘-秒中的'沙尔
。
- ‘后缀’
‘-S公司中的'内容提供商
,自然对数
,毫伏
。
- ‘后缀格式’
‘-b条中的'csplit(csplit)
。
- ‘总和’
‘-秒中的'gprof公司
。
- ‘总结’
‘-秒中的'杜
。
- ‘象征的’
‘-秒中的'自然对数
。
- ‘符号’
用于GDB和反汇编
。
- ‘向斜层’
‘-秒中的'4米
。
- ‘系统名’
‘-秒中的'uname公司
。
- ‘选项卡’
‘-t吨中的'扩大
和展开
。
- ‘标签大小’
‘-T型中的'最小二乘法
。
- ‘终端’
‘-T型中的'tput(输出)
和ul公司
。‘-t吨中的'wdiff公司
。
- ‘文本’
‘-一个中的'差异
。
- ‘文本文件’
‘-T型中的'沙尔
。
- ‘时间’
用于最小二乘法
和触摸
。
- ‘超时’
指定放弃某些操作之前等待的时间。
- ‘到标准输出’
‘-哦中的'焦油
。
- ‘全部的’
‘-c(c)中的'杜
。
- ‘触摸’
‘-t吨中的'制作
,兰利卜
、和重新编码
。
- ‘追踪’
‘-t吨中的'4米
。
- ‘传统的’
‘-t吨中的'你好
;‘-W传统中的'目瞪口呆
;‘-G公司中的'预计起飞时间
,4米
、和聚四氟乙烯
。
- ‘tty公司’
用于GDB。
- ‘类型定义’
‘-t吨中的'插件
。
- ‘typedefs和c++’
‘-T型中的'插件
。
- ‘类型集模式’
‘-t吨中的'聚四氟乙烯
。
- ‘解压缩’
‘-z(z)中的'焦油
。
- ‘无条件的’
‘-u个中的'备份文件
。
- ‘未定义’
‘-U型中的'4米
。
- ‘未定义-仅限’
‘-u个中的'纳米
。
- ‘更新’
‘-u个中的'内容提供商
,插件
,毫伏
,焦油
。
- ‘使用’
用于目瞪口呆
; 与'相同--帮助’.
- ‘uuencode(uu编码)’
‘-B中的'沙尔
。
- ‘香草操作’
‘-V(V)中的'沙尔
。
- ‘冗长的’
打印有关进度的更多信息。许多程序都支持这一点。
- ‘验证’
‘-W公司中的'焦油
。
- ‘版本’
打印版本号。
- ‘版本控制’
‘-V(V)中的'内容提供商
,自然对数
,毫伏
。
- ‘v研磨’
‘-v(v)中的'插件
。
- ‘体积’
‘-V(V)中的'焦油
。
- ‘如果……怎么办’
‘-W公司中的'制作
。
- ‘全尺寸限制’
‘-我中的'沙尔
。
- ‘宽度’
‘-w个中的'最小二乘法
和聚四氟乙烯
。
- ‘字重体验’
‘-W公司中的'聚四氟乙烯
。
- ‘可写的’
‘-T型中的'谁
。
- ‘0’
‘-z(z)中的'gprof公司
。
4.11 OID分配¶
OID(对象标识符)1.3.6.1.4.1.11591已分配给GNU项目(感谢谢尔盖·波兹尼亚科夫)。这些用于SNMP,LDAP、X.509证书等。网站https://www.alvestrand.no/objectid网站(自愿)列出许多OID分配。
如果您需要GNU包的新插槽,请编写maintainers@gnu.org。这是当前弧的列表分配:
1.3.6.1.4.1.11591 GNU1.3.6.1.4.1.11591.1 GNU半径1.3.6.1.4.1.11591.2 GnuPG1.3.6.1.4.1.11591.2.1符号1.3.6.1.4.1.11591.2.1.1 pka地址1.3.6.1.4.1.11591.3 GNU雷达1.3.6.1.4.1.11591.4 GNU GSS1.3.6.1.4.1.11591.5 GNU Mailutils公司1.3.6.1.4.1.11591.6 GNU石狮1.3.6.1.4.1.11591.7 GNU无线电1.3.6.1.4.1.11591.8 GNU Dico1.3.6.1.4.1.11591.9 GNU冲刺1.3.6.1.4.1.11591.12摘要算法1.3.6.1.4.1.11591.12.2老虎/1921.3.6.1.4.1.11591.13加密算法1.3.6.1.4.1.11591.13.2蛇1.3.6.1.4.1.11591.13.2.1蛇形-128-ECB1.3.6.1.4.1.11591.13.2.2蛇-128-CBC1.3.6.1.4.1.11591.13.2.3蛇形-128-OFB1.3.6.1.4.1.11591.13.2.4蛇形-128-CFB1.3.6.1.4.1.11591.13.2.21蛇形-192-ECB1.3.6.1.4.1.11591.13.2.22蛇形-192-CBC1.3.6.1.4.1.11591.13.2.23蛇形-192-OFB1.3.6.1.4.1.11591.13.2.24蛇形-192-CFB1.3.6.1.4.1.11591.13.2.41蛇形-256-ECB1.3.6.1.4.1.11591.13.2.42蛇形-256-CBC1.3.6.1.4.1.11591.13.2.43蛇形-256-OFB1.3.6.1.4.1.11591.13.2.44蛇形-256-CFB1.3.6.1.4.1.11591.14 CRC算法1.3.6.1.4.1.11591.14.1 CRC 321.3.6.1.4.1.11591.15椭圆曲线1.3.6.1.4.1.11591.15.1版本25519
4.12内存使用¶
如果一个程序通常只使用几兆内存,那么不必费心制造任何内存努力减少内存使用。例如,如果对于其他原因导致操作文件超过几兆长,这是将整个输入文件读取到内存中进行操作是合理的。
然而,对于诸如猫
或尾
,那可以有效地操作非常大的文件,重要的是避免使用人为限制文件大小的技术。如果一个程序按行工作并且可以应用于任意用户提供的输入文件,它应该只在内存中保留一行,因为这并不难,用户希望能够对输入进行操作大于该值的文件将一次性放入内存。
如果您的程序创建了复杂的数据结构,只需将它们放入内存,如果malloc公司
收益无效的
。
内存分析工具,如瓦尔格林
可能有用,但不要为了避免错误警报而使程序复杂化。对于例如,如果在进程退出之前才使用内存,则不要释放它只是为了让这样的工具安静下来。
4.13文件使用¶
程序应准备在以下情况下运行/用户使用程序和/等是只读文件系统。因此,如果程序管理日志文件,锁定文件、备份文件、分数文件或其他为了内部目的而修改,这些文件不应存储在/用户使用程序或/等。
有两个例外。/等用于存储系统配置信息;程序修改是合理的中的文件/等当其任务是更新系统配置时。此外,如果用户明确要求修改目录中的一个文件程序将其他文件存储在同一个文件中是合理的目录。
5充分利用C¶
本章提供了如何最好地使用C语言的建议编写GNU软件时。
请将源代码行的长度保持在79个字符或更少,以便在最广泛的环境中实现最大的可读性。
重要的是要放上开始C主体的开括号函数,以便它们将启动一个defun。几个工具在第一列中查找开大括号以找到C的开头功能。这些工具无法处理未按这种方式格式化的代码。
避免在列中放置左大括号、左括号或左括号一个是当它们位于函数内部时,这样它们就不会启动defun。开始的左大括号结构
尸体可以放在第一列如果你觉得把这个定义当作一个defon是有用的。
函数定义还必须以第一列中的函数。这有助于人们搜索函数定义,也可能有助于某些工具识别它们。因此,使用标准C语法,格式如下:
静态字符*concat(字符*s1,字符*s2){...}
或者,如果您想使用传统的C语法,请将定义格式化为这个:
静态字符*concat(s1,s2)/*名称从这里的第一列开始*/字符*s1,*s2;{/*在此处第一列中打开大括号*/...}
在标准C中,如果参数在一行中不合适,按如下方式拆分:
整数lots_of_args(int an_integer,长a_long,短a_short,双(双)...
对于结构
和枚举
类型,同样将大括号放入第一列,除非全部内容放在一行:
结构foo{整数a,b;}
或
结构foo{int a,b;}
本节的其余部分给出了我们对以下方面的建议C格式样式,这也是缩进
1.2及更新版本中的程序。它对应于选项
-nbad-bap-nbc-bbo-bl-bli2-bls-ncdb-nce-cp1-cs-di2-ndj-nfc1-nfca-hnl-i2-ip5-lp-pcs-psl-nsc-nsob
我们不认为这些建议是要求,因为如果两个不同的程序具有不同的功能,则不会给用户带来任何问题格式样式。
但无论你使用什么风格,请始终如一地使用,因为混合一个程序中的样式看起来很难看。如果你是对现有程序进行更改,请遵循以下风格那个节目。
对于函数体,我们推荐的样式如下:
如果(x<foo(y,z))哈哈=巴[4]+5;其他的{而(z){哈哈+=foo(z,z);z--;}return++x+bar();}
当程序在开括号和逗号后面。特别是在逗号之后。
将表达式拆分为多行时,请将其拆分在操作员之前,而不是在操作员之后。以下是正确的方法:
if(foothisis_long&&bar>win(x,y,z)&&剩余条件)
尽量避免两个优先级不同的运算符位于同一位置压痕等级。例如,不要这样写:
mode=(in模式[j]=VOID模式||GET_MODE_SIZE(外模式[j])>GET_MODE_SIZE(内模式[j]])? outmode[j]:输入模式[j]);
相反,请使用额外的括号,以便缩进显示嵌套:
模式=((inmode[j]==VOID模式||(GET_MODE_SIZE(出模式[j])>GET_MODE_SIZE(入模式[j]]))? outmode[j]:输入模式[j]);
插入额外的括号,以便Emacs能够正确地缩进代码。例如,下面的缩进看起来很好,如果你用手做的话,
v=rup->ru_utime.tv_sec*1000+rup->ru_utime.tv_usec/1000+rup->ru_stime.tv_sec*1000+rup->ru_stime.tv使用c/1000;
但是Emacs会改变它。添加一组括号会产生一些看起来同样漂亮的东西,Emacs会保存下来:
v=(rup->ru_utime.tv_sec*1000+rup->ru_utime.tv_usec/1000+rup->ru_stime.tv_sec*1000+rup->ru_stime.tv usec/1000);
设置do-while语句的格式如下:
请使用换页字符(control-L)将程序划分为页面位于逻辑位置(但不在函数中)。这没关系页面的长度,因为它们不必适合打印的页面第页。Formfeed应该单独出现在行上。
5.3 C构件的清洁使用¶
请显式声明所有对象的类型。例如,您应该显式声明函数的所有参数,并且应该声明要返回的函数整数
而不是忽略整数
。
一些程序员喜欢使用GCC-墙壁'选项,并更改发出警告时进行编码。如果你想这样做,那就去做。其他程序员不喜欢使用“-墙壁’,因为它给对他们不想更改的有效合法代码发出警告。如果你想这样做,那么就这样做。编译器应该是你的仆人,不是你的主人。
不要为了安抚静态分析工具而让程序变得丑陋作为皮棉
,叮当作响
、和GCC,带有额外警告选项,如-W转换和-温德夫.这些工具可以帮助查找错误和不清晰的代码,但它们也可以生成如此多的错误警报,让它们保持沉默会损害可读性不必要的石膏、包皮和其他并发症。例如,请不要将铸件插入空隙
或者什么都不做功能仅用于安抚绒线检查器。
外部函数的声明以及稍后出现在源文件应该全部放在文件开头附近的一个位置(位于文件中第一个函数定义之前),或者应该放在头文件中。不要放外部
内部声明功能。
过去通常使用相同的局部变量(名称,如电子显微镜
)在一个值中重复不同的值功能。与其这样做,不如声明一个单独的本地变量,并为其命名有意义。这不仅使程序更容易理解,而且有助于优秀编译器进行优化。您也可以移动将每个局部变量声明为包含的最小范围它的所有用途。这使得程序更加干净。
不要使用隐藏全局标识符的局部变量或参数。GCC’-W阴影'选项可以检测到此问题。
不要在一个跨越行的声明中声明多个变量。相反,在每一行开始一个新的声明。例如,相反其中:
写下以下内容之一:
或者这样:
(如果它们是全局变量,则每个变量前面都应有注释无论如何。)
当你有一个如果
-其他的
语句嵌套在另一个语句中如果
语句,始终在如果
-其他的
。因此,千万不要这样写:
总是这样:
if(foo){if(巴)赢();其他的损失();}
如果您有如果
嵌套在其他的
语句,可以写入否则,如果
在一条线上,像这样,
用它然后
-像前面一样缩进的部分然后
-部分,或编写嵌套如果
在大括号内,如下所示:
不要在同样的声明。相反,请分别声明结构标记然后使用它来声明变量或typedef。
尽量避免在内部分配任务如果
-条件(赋值里面虽然
-条件良好)。例如,不要写这个:
if((foo=(char*)malloc(sizeof*foo))==NULL)致命(“虚拟内存耗尽”);
相反,请写下以下内容:
foo=(char*)malloc(sizeof*foo);if(foo==NULL)致命(“虚拟内存耗尽”);
5.4命名变量、函数和文件¶
程序中全局变量和函数的名称用作注释。所以不要选择简洁的名称,而要寻找提供有关变量含义的有用信息的名称或功能。在GNU程序中,名称应该是英语,就像其他名称一样评论。
局部变量名可以更短,因为它们只在内部使用一个上下文,其中(大概)注释解释了它们的目的。
尽量限制在符号名称中使用缩写。可以做几个缩写,解释它们的意思,然后使用它们经常使用,但不要使用太多晦涩的缩写。
请使用下划线分隔名称中的单词,以便Emacs单词命令在其中可能很有用。坚持小写;储备宏和的大写枚举
常量,和用于名称前缀这遵循一个统一的惯例。
例如,您应该使用以下名称忽略空间更改标记
;不要用这样的名字iCant读取此
。
指示命令行选项是否已指定的名称应以选项的含义命名,而不是以选项字母。注释应说明期权及其字母。例如,
/*忽略水平空白(-b)中的更改*/int ignore_space_change_flag;
如果要使用常量整数值定义名称,请使用枚举
而不是'#定义’. GDB知道枚举常数。
您可能希望确保所有文件名都不会冲突如果将文件加载到MS-DOS文件系统,则会缩短名称。你可以使用该程序多施克
进行测试。
一些GNU程序被设计为将自己的文件名限制为14字符或更少,以避免在读入文件时发生文件名冲突较旧的System V系统。请在现有的GNU程序有它,但在新的GNU中没有必要这样做程序。多施克
还报告长度超过14的文件名字符。
5.5系统类型之间的可移植性¶
在Unix世界中,“可移植性”是指移植到不同的Unix版本。对于GNU程序来说,这种可移植性是可取的,但不是最重要的。
GNU软件的主要目的是作为GNU的一部分运行在各种类型的硬件。因此,绝对必要的可移植性非常有限。支持基于Linux的GNU非常重要系统,因为它们是人们主要使用的GNU形式。
使GNU程序在GNU以外的操作系统上运行系统不是开发GNU包的核心目标的一部分。你永远不要这样做。然而,用户会要求您这样做,只要你不这样做,配合这些请求是有用的让它主导项目或阻碍主要目标。
支持其他免费或几乎免费的操作系统是很好的(例如,*BSD)。支持各种类Unix系统是令人满意,尽管不是最重要的。这通常不太难,所以你也可以这样做。但你不必认为这是一种义务,如果真的很难。
在大多数情况下,最好将程序移植到更多平台,但你不应该让它占用你太多的时间而妨碍你你需要以更核心的方式改进计划。如果它开始这样做,请告诉用户你不想再花钱了时间在这里-其他人必须编写代码、调试代码、文档然后你可以安装它。
您也可以出于技术原因拒绝移植修补程序用户提交的其他修补程序。这取决于你。
实现可移植到大多数类Unix系统的最简单方法是使用Autoconf。你的程序不太可能需要了解更多Autoconf无法提供的有关主机平台的信息因为大多数需要这些知识的项目已经已写入。
避免使用半内部数据库的格式(例如目录)当有更高级别的替代方案时(读目录
).
对于与Unix不同的系统,如MS-DOS、Windows、VMS、MVS、,和旧的Macintosh系统,支持它们通常需要很多工作。在这种情况下,最好花时间添加功能这将在GNU和GNU/Linux上有用,而不是在支持其他不兼容的系统。
如果您支持Windows,请不要将其缩写为“win”。请参见商标。
通常我们会完整地写下“Windows”这个名称,但如果简短非常重要(如文件名和一些符号名),我们缩写将其改为“w”。例如,在GNU Emacs中,我们使用w32型'在文件中Windows特定文件的名称,但Windows的宏条件被称为WINDOWSNT(窗口)
原则上可以也是'w64型’.
定义“功能测试宏”是一个好主意_GNU_来源
编译C文件时。在GNU上编译时或GNU/Linux,这将启用GNU库扩展的声明函数,如果您可以在程序中以其他方式定义相同的函数名。(实际上你不必使用如果您愿意,可以使用这些功能使程序更易于移植到其他系统。)
但无论您是否使用这些GNU扩展,都应该避免使用他们的名字来表达任何其他含义。这样做会很困难将代码转移到其他GNU程序中。
5.6 CPU之间的可移植性¶
由于CPU之间的差异,甚至GNU系统也会有所不同类型,例如字节排序和对齐的差异要求。处理这些差异是绝对必要的。然而,不要试图迎合整数
将小于32位。我们不支持16位机器以GNU为单位。
你不需要迎合这种可能性长的
会更小指针和尺寸_t
。我们知道这样一个平台:64位Microsoft Windows上的程序。如果你关心制作包裹使用Mingw64在Windows上运行,需要处理8字节指针和4字节长的
,这将破坏此代码:
printf(“size=%lu\n”,(unsigned long)sizeof数组);printf(“diff=%ld\n”,(长)(指针2-指针1));
您的软件包中是否支持Mingw64和一般Windows你的选择。GNU项目并没有说你有责任这样做。我们的目标是替换专有系统,包括Windows,而不是增强它们。如果人们迫使你运行程序如果你对Windows不感兴趣,可以用“切换GNU/Linux—您的自由取决于它。”
预定义的文件大小类型,如关闭(_t)
是个例外:长于长的
在许多平台上,因此上述代码不会与他们合作。打印关闭(_t)
可移植的价值是自己逐个打印数字。
不要假设整数
对象也是其最低有效字节的地址。在big-endian上这是错误的机器。因此,不要犯以下错误:
整数c;...while((c=getchar())!=EOF)写入(文件描述符,&c,1);
相反,使用无符号字符
如下所示。(未签名的
是为了可移植到不寻常的系统烧焦
已签名并且其中有整数溢出检查。)
整数c;while((c=getchar())!=EOF){无符号字符u=c;写入(文件描述符,&u,1);}
如果可以,请避免将指针强制转换为整数。这样的演员很多降低可移植性,在大多数程序中很容易避免。在将指针强制转换为整数是必要的情况,例如Lisp将类型信息和地址存储在一起的解释器你必须做出明确的规定来处理不同的单词尺寸。您还需要为以下系统做好准备:您可以从中获得的正常地址范围malloc公司
从很远的地方开始从零开始。
5.7调用系统功能¶
从历史上看,C语言的实现差异很大系统缺乏ANSI/ISO C89的完整实现。如今,然而,所有实际系统都有C89编译器和GNU C支持几乎所有的C99和一些C11。类似地,大多数系统实现POSIX.1-2001库和工具,许多都有POSIX.12008。
因此几乎没有理由支持旧的C或非POSIX系统,您可能想利用标准C和POSIX编写更清晰、更可移植或更快的代码。你应该使用标准可能的接口;但如果GNU扩展使您的程序更易于维护、功能更强大或更好,请不要犹豫使用它们。无论如何,不要自己声明系统功能;这是冲突的秘诀。
尽管有这些标准,但几乎每个库函数都有一些某些系统上的可移植性问题。以下是一些示例:
打开
带尾随的名称/
在许多平台上处理不当。
打印
长双倍
可能未实施;浮点值无限和NaN经常处理不当;大精度输出可能是不正确。
readlink(读链接)
可能会回来整数
而不是ssize_t(签名_ t)
。
扫描
在Windows上,错误编号
失败时未设置。
格努利布对这方面。Gnulib提供了标准接口的实现在许多缺少它们的系统上,包括便携式系统增强GNU接口的实现,从而使用它们可移植,以及POSIX-1.2008接口,其中一些接口缺失即使是在最新的GNU系统上。
Gnulib还提供了许多有用的非标准接口;例如,标准数据结构的C实现(哈希表、二进制树),错误检查内存分配的类型安全包装功能(xmalloc语言
,xrealloc公司
),和错误输出消息。
Gnulib与GNU Autoconf和Automake集成以删除程序员编写可移植代码的负担:Gnulib使您configure脚本自动确定缺少哪些功能使用Gnulib代码来提供缺少的部分。
Gnulib和Autoconf手册有关于便携性:介绍在里面格努利布和看见便携式C和C++在里面自动控制.请咨询他们了解更多详细信息。
5.8国际化¶
GNU有一个名为GNU gettext的库,可以轻松地将将程序中的消息转换为各种语言。你应该用这个每个程序中的库。信息出现时使用英语并让gettext提供将其转换为其他语言。
使用GNU gettext需要调用获取文本
宏围绕每个可能需要转换的字符串,如下所示:
printf(gettext(“正在处理文件“%s”…”),文件);
这允许GNU gettext替换字符串“正在处理文件“%s”。。。”
带有翻译版本。
一旦程序使用gettext,请注意编写对获取文本
添加需要翻译的新字符串时。
在包中使用GNU gettext涉及指定文本域名称对于包装。文本域名用于分隔此包的翻译来自其他包的翻译。通常,文本域名应与包—例如,'coreutils公司'用于GNU核心实用程序。
要使gettext工作良好,请避免编写使对单词或句子结构的假设。当你想要的时候句子的精确文本因数据而异,使用两个或更多可选字符串常量,每个常量包含一个完整的句子,而不是在单个单词或短语中插入条件化的单词或短语句子框架。
下面是一个不该做的事情的示例:
printf(“%s已满”,容量>5000000?“磁盘”:“软盘”);
如果将gettext应用于所有字符串,如下面所示,
printf(gettext(“%s已满”),容量>5000000?gettext(“磁盘”):gettext,“软盘”);
译者几乎不知道“磁盘”和“软盘”的意思是在另一个字符串中被替换。更糟糕的是,在某些语言中(如法语)这种结构行不通:“full”一词的翻译取决于关于句子第一部分的性别;它碰巧不是“磁盘”与“软盘”相同。
完整的句子可以毫无问题地翻译:
printf(容量>5000000?gettext(“磁盘已满”):gettext(“软盘已满”);
类似的问题出现在句子结构层面代码:
printf(“#隐式规则搜索已完成%s。\n”,f->triedimplict?“”:“不”);
正在添加获取文本
对此代码的调用无法为提供正确的结果所有语言,因为某些语言中的否定需要添加单词在句子中的多个位置。相比之下,添加获取文本
如果代码启动,调用会直接执行任务就像这样:
printf(f->tried_in隐式? “#隐式规则搜索已完成。\n”,:“#隐式规则搜索尚未完成。\n”);
另一个例子是:
printf(“已处理%d个文件%s”,文件,nfiles!=文件1 ? “s”:“”);
这个例子的问题是,它假设复数是由通过添加“s”。如果对格式字符串应用gettext,如下所示,
printf(gettext(“已处理%d个文件%s”),文件,nfiles!=文件1 ? “s”:“”);
消息可以使用不同的单词,但仍将强制使用“s”代表复数。下面是一种更好的方法,将gettext应用于两个字符串独立:
printf((nfiles!=1?gettext(“已处理%d个文件”):gettext(“已处理%d个文件”),文件);
但这仍然不适用于波兰语这样的语言,波兰语有三种复数形式:一个表示nfiles==1,一个表示nniles==2,3,4,22,23,24。。。另一个是GNUngettext公司
函数解决了这个问题:
printf(ngettext(“处理%d个文件”,“处理%d文件”,文件),文件);
5.9字符集¶
坚持ASCII字符集(纯文本,7位字符)是首选GNU源代码注释、文本文档和其他除非有充分的理由做其他事情,因为应用程序域。例如,如果源代码处理法国革命日历,如果其文字字符串包含月份名称中的重音字符,如“Floréal”。另外,它也可以(但不是必需的)使用非ASCII字符表示正确的更改日志中参与者的名称(请参见更改日志).
如果需要使用非ASCII字符,通常应坚持使用一种编码,当然是在单个文件中。UTF-8可能成为最佳选择。
5.10引号字符¶
在C语言环境中,GNU程序的输出应该保持普通ASCII用于向用户发送的消息中的引号字符:最好是0x22(‘”')或0x27(''')用于左引号和右引号。虽然GNU程序传统上使用0x60('`')用于打开和0x27(''')用于结束引号,现在的引号'`像这个''通常是不对称呈现的,因此引用'“就像这个“'或'“就像这样”“通常看起来更好。
GNU程序生成是可以的,但不是必需的非C语言环境中特定于语言环境的引号。例如:
printf(gettext(“正在处理文件“%s”…”),文件);
这里,法语翻译可能会导致获取文本
返回一串“交易记录%s›。。。”
,生成报价更适合法语地区。
有时程序可能需要使用左引号和右引号直接。按照惯例,获取文本
翻译字符串‘“`”'到左引号和字符串'"'"'到右引号,程序可以使用这些翻译。一般来说,不过,最好在以下上下文中翻译引号字符较长的字符串。
如果程序的输出可能被另一个程序解析程序,最好提供一个选项来进行此解析可靠。例如,您可以使用来自C语言或Bourne shell的约定。参见示例选项--引用样式GNU的最小二乘法
。
511万¶
如果您使用甲基丙烯酸甲酯
要读取或写入文件,也不要假设对所有文件都有效或对所有文件都失败。它可能对某些文件有效在别人身上失败。
正确的使用方法甲基丙烯酸甲酯
是在特定文件上尝试你想用什么?如果甲基丙烯酸甲酯
不起作用,请依靠用另一种方式完成工作阅读
和写
。
需要这种预防措施的原因是GNU内核(HURD)提供了一个用户可扩展的文件系统,其中可以有许多不同种类的“普通文件”。他们中的许多人支持甲基丙烯酸甲酯
,但有些人没有。让程序处理很重要所有这些类型的文件。
6记录程序¶
理想情况下,GNU程序应该附带完整的免费文档用于参考和教程目的。如果包可以编程或扩展,文档应涵盖编程或扩展它,以及仅仅使用它。
6.1 GNU手册¶
GNU系统首选的文档格式是Texinfo格式化语言。每个GNU包(理想情况下)都应该具有Texinfo中的文档供参考和学习者使用。特辛福使用TeX,并生成信息文件。也可以生成来自Texinfo源的HTML输出。请参阅Texinfo手册,或硬拷贝或在线版本,可通过信息
或Emacs信息子系统(C-h i公司).
现在,其他一些格式(如Docbook和Sgmltexi)可以自动转换为Texinfo。生产特新佛是可以的通过这种方式转换文档,只要它能产生良好的结果。
确保您的手册对一个对主题并通读。这意味着涵盖基本主题一开始,后面才是高级主题。这也意味着定义首次使用的每个专门术语。
请记住,GNU手册(和其他GNU)的读者文档)是全球性的,可能会使用多年几十年。这意味着读者可能会有非常不同的文化参考点。几十年后,除了老人外,所有人都会不同的文化参照点;很多事情“人人都知道”关于“今天可能被大多数人遗忘。
因此,尽量避免使用取决于正确理解的文化参考点,或在妨碍不认识他们的人阅读的方式。
同样,在措辞上要保守(除了技术性的术语)、语言结构和拼写:旨在创造它们十年前读者就可以理解了。在任何比赛中时尚,GNU写作甚至不应该有资格进入。
偶尔提及空间或时间是可以的本地化参考点或事实,如果它直接相关或旁白。当它们不再有意义,也不会有很多工作。
相比之下,引用GNU和相关的自由软件运动。这些是一个中心这是我们信息的一部分,因此我们应该利用机会提及他们。他们是基本的道德立场,所以他们会很少改变。
程序员倾向于将程序的结构作为文档结构。但这种结构不是有助于解释如何使用程序;可能是这样对用户来说是无关紧要和令人困惑的。
相反,构建文档的正确方法是根据用户在阅读时会想到的概念和问题。这一原则适用于每个级别,从最低(排序段落中的句子)到最高(章节主题的顺序在手册中)。有时,这种想法结构与正在记录的软件的实现结构-但是它们通常是不同的。学习写作的重要部分文档是为了学会在不经意间发现构建文档,如实现,停止自己,寻找更好的替代品。
例如,GNU系统中的每个程序可能都应该记录在一本手册中;但这并不意味着每个程序都应该有自己的手册。这将遵循实现,而不是帮助用户的结构理解。
相反,每本手册应涵盖一个连贯的话题例如,而不是手册差异
和手册差异3
,我们有一本“文件比较”手册,涵盖了这两个方面程序,以及合作管理计划
.通过记录这些程序通过共同努力,我们可以使整个主题更加清晰。
讨论程序的手册当然应该记录所有程序的命令行选项及其所有命令。它应该举例说明它们的用法。但不要将手册组织为列表的功能。相反,要按子主题进行逻辑组织。地址用户在考虑以下工作时会问的问题程序确实如此。不要只是告诉读者每个功能可以做什么说出它适合做什么工作,并展示如何将其用于那些工作工作。解释什么是推荐的用法,以及什么样的用法用户应该避免。
一般来说,GNU手册应该既是教程又是参考。它的设置应便于通过Info访问每个主题,以及直接阅读(附录除外)。GNU手册应该很好地介绍初学者从开始,并应提供黑客想要的所有详细信息。野牛手册就是一个很好的例子,请看一下看看我们的意思。
这并不像最初听起来那么难。将每个章节排列为对主题进行逻辑分解,但对各部分进行排序,并写出它们文本,这样直接阅读这一章就有意义了。做同样,当把书组织成章节时,以及当组织一个部分分成段落。口号是:,在每个点,地址前文提出的最基本和最重要的问题。
如有必要,在手册开头添加额外章节都是纯教程,涵盖了该主题的基础知识。这些提供了初学者理解手册其余部分的框架。这个野牛手册提供了一个很好的例子来说明如何做到这一点。
为了作为参考,手册应该有一个列出所有函数、变量、选项和重要概念节目的一部分。一个组合索引可以用于简短的手册,但有时对于复杂的包,最好使用多个指数。Texinfo手册包括关于编制良好索引的建议条目,请参见制作索引条目在里面GNU(全球导航单元)特辛福,然后查看定义索引在里面GNU Texinfo公司。
不要使用Unix手册页作为如何编写GNU文档的模型;它们大多数都很简洁,结构很差,而且给出的信息不够充分对基本概念的解释。(当然,有一些例外情况。)此外,Unix手册页使用一种特殊的格式,即与我们在GNU手册中使用的不同。
请在手册中包含一个电子邮件地址,以便报告漏洞在手册文本中。
请不要使用Unix中使用的术语“路径名”文档;改用“文件名”(两个单词)。我们使用这个术语“path”仅用于搜索路径,即目录名列表。
请不要使用术语“非法”来指代错误输入计算机程序。请为此使用“无效”,并保留“非法”一词是指法律禁止的活动。
请不要写“()'在函数名之后,仅表示它是一个函数。foo()
不是函数,而是函数调用时不带参数。
只要可能,请坚持主动语态,避免被动语态,使用现在时态,而不是将来时态。对于实例,编写“The functionfoo公司
返回包含以下内容的列表一和b条“而不是”包含一和b条将返回。”主动语态的一个优点是要求你陈述句子的主语;用被动语态声音,你可能会忽略主题,这会导致模糊。
当语法要求时,使用将来时态是恰当的,如,“如果您键入x个,计算机将在10年内自行构建秒。”
6.2文档字符串和手册¶
一些编程系统,如Emacs,提供了一个文档字符串对于每个函数、命令或变量。你可能想写一个通过编译文档字符串和编写他们周围没有多余的文字,但你不能这样做这种做法是一个根本错误。文笔优美的文本文档字符串对于手册来说是完全错误的。
当文档字符串出现在屏幕上,将没有其他文字来介绍或解释它。同时,它在风格上可能相当非正式。
手册中描述函数或变量的文本不得出现独自一人;它出现在章节或小节的上下文中。其他文本在本节开头,应解释一些概念,以及通常应提出一些适用于多个功能或变量。中函数和变量的前面描述第节还将提供有关主题的信息。A描述写为独立会重复一些信息;这冗余看起来很糟糕。同时文档字符串在手册中是完全不可接受的。
使用文档字符串编写优秀手册的唯一好方法就是把它们作为写作好文章的信息来源。
6.3手册结构细节¶
手册的标题页应说明程序或手册中记录的包。手册的顶部节点应也包含此信息。如果手册更改更多经常高于或独立于程序,也会声明一个版本这两个位置的手册编号。
手册中记录的每个程序都应有一个名为‘程序调用'或'正在调用程序’. 这个节点(及其子节点,如果有)应描述程序的命令行参数以及如何运行它(信息类人员将在手册页中查找)。以“”开头@示例’包含程序的所有选项和参数的模板使用。
或者,将一个菜单项放在某个菜单中,该菜单项的名称符合以下条件之一上述模式。标识该项指向的节点作为节点,无论节点的实际名称如何。
“--使用'信息阅读器的功能查找这样的节点或菜单项以查找相关文本,因此这是至关重要的每个Texinfo文件都有一个。
如果一本手册描述了几个程序,那么它应该有这样一个节点手册中描述的每个程序。
6.4手册许可¶
请为所有符合以下条件的GNU手册使用GNU免费文档许可证超过几页长。同样适用于短款系列文档—您只需要整个GNU FDL的一个副本收藏。对于单个短文档,可以使用非常宽松的非版权许可证,以避免长许可证占用空间。
请参见https://www.gnu.org/copyleft/fdl-howto.html了解更多解释如何使用GFDL。
请注意,不必包含GNU GPL或GNU的副本许可证既不是GPL也不是LGPL的手册中的LGPL。它可以最好将程序许可证包含在一本大手册中;在一个简短的手册,其大小将大大增加,包括程序的许可证,最好不要包含它。
6.5手动学分¶
请将手册的主要人类作者视为作者,在手册的标题页上。如果有公司赞助这项工作,谢谢公司在手册中的适当位置,但不要引用公司作为一个作家。
6.7新闻文件¶
除了手册之外,包还应该有一个名为新闻其中包含一个用户可见的更改列表提到。在每个新版本中,将项目添加到文件的前面,并确定它们所属的版本。不要丢弃旧项;离开它们位于文件中较新的项目之后。通过这种方式,用户从任何以前的版本都可以看到新功能。
如果新闻文件变得很长,移动一些较旧的项目到名为ONEWS公司并在末尾添加一条注释,说明用户访问该文件。
6.8变更日志¶
保存更改日志,以描述对程序源所做的所有更改文件夹。这样做的目的是为了让人们调查未来将了解可能引入该bug的更改。通常,通过查看最近更改的内容可以发现新的错误。更重要的是,更改日志可以帮助您消除概念通过为您提供冲突概念是如何产生的历史,它们来自谁,以及为什么做出了相互冲突的更改。
因此,更改日志应该足够详细和准确提供通常需要的信息软件法医学具体来说,更改日志应该为以下问题很简单:
- 哪些更改影响了特定的源文件?
- 是否重命名或移动了特定的源文件,如果是,作为什么变化?
- 哪些更改影响了给定函数或宏或数据结构?
- 是函数(或宏或数据结构的定义)重命名或从另一个文件中移动,如果是,作为其中的一部分改变?
- 删除函数(或宏或数据结构)的更改是什么?
- 给定更改的基本原理是什么,其主要内容是什么思想?
- 是否有任何关于变更的额外信息?如果有,在哪里可以找到它?
历史上,更改日志是在特殊格式上维护的文件夹。现在,项目通常将其源文件保存在版本控制系统(VCS),例如Git,颠覆,或Mercurial。如果VCS存储库是公开的可访问,并且单独提交更改(一次提交用于每个逻辑变更集)并记录每个变更的作者,然后VCS记录的信息可用于生成更改从VCS日志中注销,并回答上述问题使用合适的VCS命令提出问题。(然而VCS日志消息仍需要提供一些支持信息,如下所述。)维护此类功能的项目VCS存储库可以决定不维护单独的更改日志文件,而是依靠VCS来保持更改日志。
如果您决定不维护单独的更改日志文件,您应该仍然考虑在发布tarball中提供它们,以获得好处希望在不访问项目的VCS存储库。存在可以生成更改日志VCS日志中的文件;例如gitlog到changelog脚本是Gnulib的一部分,可以用于Git存储库。在Emacs中,命令C-x v a(vc-update-change-log
)增量更新更改日志VCS日志中的文件。
如果单独的更改日志文件是正常情况下打电话更改日志,并且每个此类文件涵盖整个目录。每个目录都可以有自己的更改日志文件,或者目录可以使用其父目录的更改日志-最多你。
6.8.1变更日志概念和惯例¶
您可以将更改日志视为概念上的“撤消列表”说明早期版本与当前版本的差异。人们可以看到当前版本;他们不需要更改日志告诉他们其中有什么。他们想要从更改日志中得到什么是明确的解释早期版本的不同之处。每个进入在里面更改日志描述单个更改或最小更改属于一起的一批更改,也称为变更集。
最好使用收割台线:一行完整的句子,总结变更集。如果您将更改日志保存在VCS中应该是一项要求,因为VCS命令显示以缩写形式更改日志,例如git日志—单行,治疗特别是标题行。(在一个更改日志文件,标题行后面的行表示谁是更改的作者,以及安装时。)
在更改日志条目的标题行后面跟随整体变化。这应该是一个清晰的描述。特别注意变更集的各个方面很容易从diff或修改的文件名和功能:变更的总体思路和需求,以及对不同文件/函数所做更改之间的关系(如果有)。如果在某些公共论坛上讨论了更改或其原因,例如作为项目的问题跟踪器或邮件列表总结变革中讨论的要点描述,并包含指向该讨论或问题ID的指针对于那些想完整阅读它的人。
解释新代码的各个部分如何与其他代码协同工作的最佳位置在代码的注释中,而不是在更改日志中。
如果你认为改变需要解释为什么这个需要进行更改-也就是说,旧代码有什么问题这需要改变你可能是对的。请把代码中注释中的解释,人们可以随时看到它他们看到了代码。这种解释的一个例子是,“这函数过去是迭代的,但当MUMBLE是树。”(尽管如此简单的原因不需要这种解释。)
对变化进行其他类型解释的最佳位置是更改日志条目。特别是,评论通常不会说明原因一些代码被删除或移动到另一个位置-属于对所做更改的描述。
按照对更改的自由文本描述,这是一个好主意列出您需要的实体或定义的名称根据它们所在的文件以及中的更改内容进行更改每一个。请参见更改日志的样式如果项目使用现代VCS将保存更改日志信息,如中所述更改日志,显式列出了被更改并不是绝对必要的,在某些情况下(如许多地方的相同机械变化)甚至乏味。已经结束了由您决定是否允许项目开发人员省略日志条目中更改的文件和函数列表,以及在某些特定条件下是否允许此类遗漏。然而,在做出这个决定时,请考虑以下几点提供每次更改的更改实体列表的好处:
- 产生有用的更改日志VCS日志中的文件如果更改日志条目没有列出修改了函数/宏,因为VCS命令无法仅从提交信息可靠地复制其名称。对于例如,当函数的头部分发生更改时定义,差异块的标题,如VCS日志中所示命令将错误的函数命名为被修改的函数(通常函数在被修改的函数之前定义),因此使用这些差异收集修改后函数的名称将产生不准确的结果结果。您将需要使用专门的脚本,例如gnulib的vcs到changelog.py,以解决这些问题困难,并确保它支持您的项目。
- 而现代VCS命令,如Gitgit对数-L和数字对数-G,提供强大的方法来发现影响某个函数、宏或数据结构(因此可能制作更改日志如果您有存储库,则不需要文件可用),它们有时会失败。例如,git对数-L不支持一些现成的编程语言的语法。明确提及修改后的函数/宏可以找到相关变更简单可靠。
- 某些VCS命令在以下情况下存在困难或限制跨文件移动或重命名跟踪更改。同样,如果实体这些困难是可以克服的。
- 使用生成的更改日志文件夹可能没有可用的存储库和VCS命令给他们。命名修改的实体可以缓解这个问题。
由于这些原因,请提供修改的文件和函数的列表每次更改都会使更改日志更加有用,因此我们建议在可能和可行的情况下包括它们。
也可以生成命名修改实体的列表通过运行脚本。其中一个脚本是mklog.py文件(写入Python 3);它由通用条款
项目。Gnulib提供这种脚本的另一种变体,称为vcs到changelog.py,的一部分vcs到changelog
模块。请注意,这些脚本目前支持的编程语言少于手动命令由Emacs提供(参见更改日志的样式). 因此上述生成更改日志
文件来自VCS提交历史记录,例如通过gitlog到changelog
脚本,通常提供更好的结果表明,贡献者坚持提供良好的提交消息。
6.8.2变更日志的样式¶
下面是一些更改日志条目的简单示例,从标题行,说明谁进行了更改以及安装时间,然后是对具体变化的描述。(这些示例包括摘自Emacs。)请记住,显示日期的行只有在分离更改日志文件,而不是将更改日志保存在VCS。
2019-08-29诺姆·波斯塔夫斯基<npostavs@gmail.com>在术语中处理完全未编码的输入(Bug#29918)*lisp/term.el(term-emulate-terminal):如果整个解码后的字符串是八位字符。不要试图保存在这种情况下,用于下一次迭代的字符串。*测试/lisp/term-tests.el(term-decode-partial)(术语可编入):新测试。2019-06-15保罗·艾格特<eggert@cs.ucla.edu>到tputs位于libtinfow中的平台的端口*configure.ac(tputs_library):还可以尝试tinfow、ncursesw(Bug#33977)。2019年2月8日Eli Zaretskii<eliz@gnu.org>改进“date-to-time”和“parse-time-string”的文档*doc/lispref/os.texi(时间解析):文档“parse-time-string”,并参考它以了解“date-to-time”参数。*lisp/calendar/time-date.el(日期到时间):请参阅文档要“解析时间字符串”的字符串,以获取有关DATE参数的格式。(错误号34303)
如果你提到修改过的函数或变量的名称重要的是要完整地命名它们。不要缩写函数或变量名字,不要把它们组合在一起。后续维护人员通常会搜索函数名以查找所有符合以下条件的更改日志条目属于它;如果你缩写这个名字,他们就找不到了他们搜索。
例如,一些人倾向于缩写函数组通过书写命名'*寄存器.el({insert,jump-to}-寄存器)’;这不是一个好主意,因为搜索跳转到寄存器
或插入寄存器
找不到该条目。
用空行分隔无关的更改日志条目。不要放条目的单个更改之间的空行。您可以省略文件名和星号(当连续的单个更改位于相同的文件。
通过用‘)',而不是',',并用打开延续‘(’. 这使得Emacs中的高亮显示效果更好。下面是一个示例:
*src/keyboar.c(菜单栏项目,工具栏项目)(Fexecute_extended_command):处理“keymap”属性。
向添加条目的最简单方法更改日志是Emacs的命令M-x添加-更改-长条目,或其变体C-x 4个a(add-change-log-entry-other窗口
). 这是自动的收集更改的文件名和更改的函数或变量,并根据约定格式化更改日志条目如上所述,由您来描述您所做的更改到该函数或变量。
安装其他人的更改时,请将参与者的姓名输入更改日志条目而不是条目的文本中。在其他单词,写下:
2002年7月14日John Doe<jdoe@gnu.org网站>*把它缝起来。
而不是这样:
2002-07-14常规维护人员<usual@gnu.org>*把它缝起来。修补程序依据jdoe@gnu.org。
将他人的更改提交到VCS时,请使用VCS功能指定作者。例如,使用Git,使用git提交--作者=作者。
至于日期,那应该是您应用更改的日期。(对于VCS,使用适当的命令行开关,例如。,git提交--日期=日期)
现代VCS有命令应用通过电子邮件发送的更改(例如,Git已经吉特am); 在这种情况下,变更集的作者制作日期将自动从电子邮件中收集消息并记录在存储库中。如果准备好补丁使用合适的VCS命令,例如git格式-补丁,电子邮件正文还将包含更改集,因此重发或转发消息不会造成干扰将这些变化归因于作者。因此,我们建议您请求您的贡献者使用以下命令吉特格式-补丁准备补丁。
6.8.3简单变更¶
某些简单类型的更改不需要太多细节日志。
如果更改的描述足够简短,它可以作为自己的标题行:
2019-08-29埃利·扎勒茨基<eliz@gnu.org>*lisp/simple.el(kill-do-not-save-duplicates):文档修复。(错误号36827)
当您以简单的方式更改函数的调用顺序时,并将函数的所有调用方更改为使用新的调用序列,无需为所有您更改的呼叫者。只需在函数的条目中写入即可被呼叫时,“所有呼叫者都改变了”,如下所示:
*keyboard.c(Fcommand_execute):新参数SPECIAL。所有呼叫者都已更改。
当您只更改注释或文档字符串时,只需编写一个条目,而不提及函数。Just“医生fixes”对于更改日志来说已经足够了。
当您在多个文件中进行更改时,这些更改是从一个文件中机械地执行的潜在的变化,这足以描述潜在的变化。下面是一个影响中所有文件的更改示例存储库:
2019-01-07保罗·艾格特<eggert@cs.ucla.edu>将版权年更新为2019年运行“TZ=UTC0 admin/update-copyright$(git-ls-files)”。
测试套件文件是软件的一部分,因此我们建议它们作为用于更改目的的代码。
无需为非软件创建更改日志条目文件(手册、帮助文件、媒体文件等)。这是因为他们不易受到难以理解的错误的影响。要更正一个错误,你不需要知道错误段落的历史;它足以将文件中的内容与实际情况进行比较。
但是,当该项目从其贡献者处获得版权分配,以便使作者记录更加准确。因此,我们建议保留项目Texinfo源的更改日志手册。
6.8.4条件变更¶
源文件通常可以包含有构建时间条件的代码或静态条件。例如,C程序可以包含编译时间#如果
条件句;在中实施的程序解释语言可以包含函数的模块导入仅对特定版本的口译员;和Automake生成文件.am文件可以包含变量定义或目标声明考虑配置时Automake条件是否为true。
许多更改也是有条件的:有时添加一个新变量,或函数,甚至是一个新的程序或库取决于构建时条件。指出在更改日志中,显示更改适用的条件。
我们用于指示条件更改的约定是使用条件名称周围的方括号。
条件变化可能发生在多种情况下变化,所以这里有一些例子来帮助澄清。这是第一次该示例描述了C、Perl和Python文件中的更改,这些文件是有条件但没有关联的函数或实体名称:
*xterm.c[SOLARIS2]:包含<string.h>。*FilePath.pm[$^O eq'VMS']:导入VMS::功能模块。*framework.py[sys.version_info<(2,6)]:生成“with”语句可从__future_导入,以支持python 2.5。
为了简单起见,我们的其他示例仅限于C,作为次要示例使其适应其他语言所需的更改应该是不言而喻。
接下来,这里有一个条目描述了一个全新的定义条件:C宏框架_窗口_P
定义(并使用)仅当宏HAVE_X_窗口
定义如下:
*frame.h[HAVE_X_WINDOWS](frame_WINDOW_P):宏定义。
接下来,函数中的更改条目初始化_显示
,其整体定义是无条件的,但变化它们包含在“#ifdef HAVE_LIBNCURSES(如果定义HAVE_LIBNCURSES)’有条件的:
*dispnew.c(init_display)[HAVE_LIBNCURSES]:如果是X,则调用tgetent。
最后,这里是一个只有在以下情况下才会生效的更改条目某个宏是不定义:
*host.c(gethostname)[!HAVE_SOCKETS]:替换为winsock版本。
6.8.5指示更改的零件¶
指示使用尖括号更改的功能部分包含更改部分的操作指示。这是一个条目对于函数部分的更改sh-while-getopts公司
那个处理第页
命令:
*progmodes/sh-script.el(sh-while-getopts)<sh>:处理用户特定的选项字符串为空。
6.9手册页¶
在GNU项目中,手册页是次要的。没有必要或期望每个GNU程序都有一个手册页,但有些程序有。您可以选择是否在程序中包含手册页。
当您做出此决定时,请考虑支持手册页每次更改程序时都需要持续努力。时间你花在手册页上的时间是从更有用的工作中抽出的。
对于更改很少的简单程序,更新手册页可能是一份小工作。那么没有什么理由不包括手册页,如果你有一个。
对于变化很大的大型程序,更新手册页可能会成为一个沉重的负担。如果用户愿意捐赠手册页,您可以觉得接受这份礼物很昂贵。拒绝这个人可能更好除非同一个人同意承担全部责任保持它,这样你就可以彻底洗手不干了。如果这个志愿者后来停止了工作,然后觉得没有义务自己捡起来;最好从直到其他人同意更新。
当一个程序只改变了一点点时,您可能会觉得差异很小,如果没有这些差异,手册页仍然有用正在更新。如果是这样的话,在男人的开头附近放一个醒目的便条页面说明您不维护它,并且Texinfo手册更具权威性。注释应说明如何访问Texinfo文档。
确保手册页包含版权声明和免费许可。简单的全许可许可适用于简单的手册页(参见其他文件的许可证通知在里面GNU信息维护者).
对于较长的手册页,有足够的解释和文档它们可以被视为真正的手册,使用GFDL(参见手册许可证).
最后,GNU help2man程序(https://www.gnu.org/software/help2man/)是实现自动化的一种方法生成手册页,本例中来自--帮助输出。在许多情况下,这就足够了。
6.10阅读其他手册¶
可能有非免费书籍或文档文件描述您正在记录的程序。
可以使用这些文档作为参考,就像新的代数教科书可以阅读其他有关代数的书籍。很大一部分任何非小说类书籍都由事实组成,在这种情况下,事实是关于某个程序有效,这些事实对于每个写这个主题的人。但注意不要复制您的概述现有非自由格式的结构、措辞、表格或示例文件。从免费文档复制可能是可以的;请检查一下与FSF讨论个别案件。
7发布过程¶
发布不仅仅是将源文件打包到tar文件并将其用于FTP。你应该这样设置你的软件它可以配置为在各种系统上运行。您的Makefile应该符合下面描述的GNU标准,以及您的目录布局还应符合下面讨论的标准。这样做使您可以轻松地将包包含到更大的框架中所有GNU软件。
7.1配置应如何工作¶
每个GNU发行版都应该附带一个名为配置
。此脚本提供了描述要为其编译程序的机器和系统的类型。这个配置
脚本必须记录配置选项,以便它们会影响编译。
这里的描述是配置
GNU包中的脚本。许多软件包都实现了它使用GNU Autoconf(请参阅介绍在里面自动控制)和/或GNU Automake(请参阅介绍在里面自动制作),但你不必使用这些工具。你可以用任何方式实现它你喜欢;例如,通过制作配置
被包裹起来完全不同的配置系统。
另一种方式配置
要操作的脚本是使来自标准名称的链接,例如配置。小时到适当的地方所选系统的配置文件。如果你使用这个技巧,分配应该不包含名为配置。小时。这样人们就无法构建程序,而不首先配置它。
另一件事是配置
可以做的是编辑Makefile。如果你这样做,分发应该不包含名为生成文件相反,它应该包含一个文件生成文件.in哪一个包含用于编辑的输入。再一次,这是为了让人们如果不先配置程序,则无法构建程序。
如果配置
确实写了生成文件,然后生成文件应具有名为的目标生成文件这导致了配置
要重新运行,请设置上次设置的相同配置时间。这些文件配置
读数应列为的依赖关系生成文件。
从配置
脚本应该在开头有注释,说明它们是生成的自动使用配置
。这样用户就不会认为尝试手动编辑它们。
这个配置
脚本应该编写一个名为配置状态它描述了在程序是上次配置的。此文件应该是一个shell脚本,如果运行,将重新创建相同的配置。
这个配置
脚本应接受表单的选项‘--srcdir公司=目录名'指定找到源的目录(如果它不是当前目录)。这使构建成为可能程序位于单独的目录中,以便实际的源目录未修改。
如果用户未指定“--srcdir公司',那么配置
应该检查两者。和..看看能不能找到消息来源。如果它在其中一个地方找到源,应该使用它们那里。否则,应报告找不到源,并且应以非零状态退出。
通常是简单的支持方式--srcdir公司'是通过编辑的定义VPATH公司
进入Makefile。一些规则可能需要显式引用指定的源目录。为了做到这一点可能,配置
可以将名为源目录
其值正好是指定的目录。
此外,“配置'脚本应采用选项对应于大多数标准目录变量(参见安装目录的变量). 以下是列表:
--前缀--exec-prefix--bindir--sbindir--libexecdir--sysconfdir--共享状态目录--本地状态目录--运行状态目录--libdir--includedir--oldincludedir--数据根目录--datadir--infodir--localedir--mandir--docdir--htmldir—dvidir—pdfdir—psdir
这个配置
脚本还应采用一个参数,该参数指定要为其生成程序的系统类型。这个论点应该是这样的这个:
例如,基于Athlon的GNU/Linux系统可能是‘i686-pc-linux-gnu’.
这个配置
脚本需要能够解码所有可能的描述机器的替代方法。因此,‘athlon-pc-gnu/linux'将是有效的别名。有一个贝壳脚本已调用配置订阅可以用作子例程来验证系统类型和规范化别名。
这个配置
脚本还应选择--建造=构建类型,应等于平原构建类型论点。例如,“配置--构建=i686-pc-linux-gnu'相当于'配置i686-pc-linux-gnu’. 当生成类型未由选项指定时或论点配置
脚本通常应该使用shell脚本配置猜测。
允许其他选项更详细地指定软件或机器上的硬件,以包括或排除可选部件或调整某些工具或参数的名称:
- ‘--启用-特征[=参数]’
配置包以构建和安装可选用户级别已调用设施特征。这允许用户选择要包含的可选功能。提供可选的参数属于‘不'应省略特征,如果默认生成。
否'--启用'选项应该曾经使一个功能更换另一个。否'--启用'选项应始终替换一个有用的行为表示另一个有用的行为。唯一正确使用‘--启用'是关于是否构建程序的一部分的问题或将其排除。
- ‘--带有-包裹’
包裹包裹将安装,因此配置此包与合作包裹。
的可能值包裹包括‘gnu-as(gnu-a)'(或'气体’), ‘gnu-ld’, ‘gnu-libc’,‘gdb公司’,‘x个’,和‘x工具箱’.
不要使用“--与'选项指定要使用的文件名查找特定文件。这超出了“--与’选项用于。
- ‘变量=价值’
设置变量的值变量到价值。这是用于覆盖构建过程。例如,用户可以发出“配置CFLAGS=-g CXXFLAGS=-g'使用调试信息生成,而不使用默认优化。
将变量指定为的参数配置
,如下所示:
比在环境变量中设置它们更好:
因为它有助于稍后重新创建相同的配置配置状态。但是,这两种方法都应支持。
全部配置
脚本应该接受所有的“细节”选项和变量设置,无论它们是否不同于手头的特定包裹。特别是,他们应接受以“”开头的任何选项--带有-'或‘--启用-’. 这样用户就可以配置用一组选项一次性完成整个GNU源代码树。
您会注意到,类别--带有-'和'--启用-’窄:它们不要为任何类型的选项提供一个位置你可能会想到。这是故意的。我们想限制可能性GNU软件中的配置选项。我们不希望GNU程序具有独特的配置选项。
执行部分编译过程的包可能支持交叉编译。在这种情况下程序可能不同。
这个配置
脚本通常应处理指定类型的系统同时作为主机和目标,从而生成一个程序适用于与其运行的机器类型相同的机器。
编译程序以在不同于内部版本的主机类型上运行类型,使用configure选项--主机=主机类型,其中主机类型使用与相同的语法构建类型.主机类型通常默认为构建类型。
要配置交叉编译器、交叉汇编程序或其他应使用configure指定与主机不同的目标选项'--目标=目标类型’. 的语法目标类型与主机类型相同。所以命令会看起来像这样:
./configure--主机=主机类型--目标=目标类型
目标类型通常默认为主机类型。交叉操作没有意义的程序不需要接受‘--目标'选项,因为为配置整个操作系统交叉运算不是一个有意义的运算。
有些程序有自动配置自身的方法。如果您的程序设置为这样做,您的配置
脚本可以简单地忽略它的大部分论点。
7.2生成文件惯例¶
这个描述了为GNU程序编写Makefile的约定。使用Automake将帮助您编写遵循以下内容的Makefile习俗。有关可移植Makefiles的更多信息,请参阅POSIX公司和便携式Make编程在里面自动控制。
7.2.1 Makefile的一般惯例¶
每个Makefile都应包含以下行:
以避免系统出现故障壳牌公司
变量可能是从环境中继承下来的。(这对GNU来说从来都不是问题制作
)
不同制作
程序具有不兼容的后缀列表和隐含的规则,这有时会造成混乱或不当行为。所以最好只使用您在特定Makefile中需要的后缀,如下所示:
第一行清除后缀列表,第二行介绍所有可能受此Makefile中隐式规则约束的后缀。
不要想当然。位于命令执行的路径中。什么时候?在make,请确保它使用./如果程序构建为品牌的一部分或$(斯里兰卡卢比)/如果文件是不变的部分源代码的。如果没有这些前缀之一,则当前搜索使用路径。
两者之间的区别./(该生成目录)和$(斯里兰卡卢比)/(该源目录)很重要,因为用户可以使用“--srcdir公司'选项到配置.形式规则:
foo.1:foo.man sedscriptsed-f sedscript foo.man>foo.1
当生成目录不是源目录时将失败,因为foo.man(美食家)和塞德斯cript位于源目录中。
使用GNU时制作
,依赖于'VPATH公司'查找源文件将在存在单个依赖项文件的情况下工作,自从制作
自动变量'$<'将代表源文件。(许多版本的制作
设置'$<’仅在隐式规则中。)Makefile目标类似
foo.o:bar.c$(CC)-I.I$(srcdir)$(CFLAGS)-c bar。c-o foo。o个
应改为
foo.o:bar.c$(CC)-I.-I$(srcdir)$(CFLAGS)-c$<-o$@
为了允许'VPATH公司“以正确工作。当目标有多个依赖项,使用显式$(斯里兰卡卢比)'是最简单的让规则发挥作用的方法。例如,上面的目标食品.1最好写为:
foo.1:foo.man sedscriptsed-f$(srcdir)/sedscript$(srcdir)/foo.man>$@
GNU发行版通常包含一些非源文件文件—例如,信息文件,以及Autoconf、Automake、,野牛或Flex。由于这些文件通常出现在源文件中目录中,它们应该始终出现在源目录中,而不是出现在生成目录。因此,更新Makefile规则时应将更新了源目录中的文件。
但是,如果文件没有出现在分发中,则Makefile不应将其放在源目录中,因为程序在通常情况下不应修改源目录无论如何。
尽量使构建和安装目标,至少子目标)正确使用并行制作
。
7.2.2 Makefiles中的实用程序¶
编写Makefile命令(以及任何shell脚本,例如配置
)在下面运行第页
(都是传统的伯恩外壳和POSIX公司外壳),不csh公司
.不要使用任何的特殊功能科什
或猛击
,或POSIX公司特征在传统Bourne中没有得到广泛支持第页
。
这个配置
脚本和生成文件规则安装时不应直接使用任何实用程序,除非:
awk cat cmp cp diff echo expr false grep install-info ln lsmkdir mv printf pwd rm rmdir sed sleep sort tar test touch tr真
压缩程序,如gzip公司
可用于距离
规则。
一般来说,坚持广泛支持(通常POSIX公司-指定)这些程序的选项和功能。对于例如,不要使用'mkdir-p',虽然很方便,因为很少有系统根本不支持它,而其他系统则不安全用于并行执行。有关已知不兼容性的列表,请参阅可移植外壳编程在里面自动控制。
最好避免在makefile中创建符号链接,因为很少有文件系统不支持它们。
生成和安装的Makefile规则也可以使用编译器和相关程序,但应通过制作
变量,以便用户可以替换替代品。以下是我们的一些程序平均值:
ar bison cc flex安装ld ldconfig lex制作makeinfo ranlib texi2dvi yacc
使用以下内容制作
运行这些程序的变量:
$(AR)$(BISON)$(CC)$(柔性)$(安装)$(LD)$(本地配置)$(LEX)$(制造)$(MAKEINFO)$(兰利)$(TEXI2DVI)$(YACC)
当您使用兰利卜
或ldconfig(ldconfig)
,你应该确保如果系统没有问题的程序,就不会发生什么不好的事情。安排忽略该命令中的错误,并在此之前打印消息告诉用户此命令失败并不意味着一个问题。(Autoconf'AC_PROG_RANLIB语言'宏可以帮助)
如果使用符号链接,则应为系统实现回退没有符号链接。
可以通过Make变量使用的其他实用程序包括:
chgrp chmod chown mknod公司
可以在Makefile部分(或脚本)中使用其他实用程序仅适用于您了解这些实用程序的特定系统存在。
7.2.3指定命令的变量¶
生成文件应提供变量以覆盖某些命令、选项、,等等。
特别是,您应该通过变量运行大多数实用程序。因此,如果您使用Bison,将一个名为比森
其默认值值设置为“野牛',并用引用它$(比森)
当你需要使用野牛时。
文件管理实用程序,如自然对数
,rm(毫米)
,毫伏
、和因此,不需要以这种方式通过变量引用,因为用户不需要用其他程序替换它们。
每个程序名变量都应该附带一个选项变量用于为程序提供选项。附加'旗帜'到program-name变量名以获取选项变量name for例子,BISONFLAGS公司
.(名称CFLAGS公司
对于C编译器,YFLAGS公司
对于yacc,以及LFLAGS公司
对于lex,是这条规则的例外,但我们保留它们是因为它们是标准的。)使用CPPFLAGS公司
在任何运行预处理器,并使用LDFLAGS(着陆标志)
在任何编译命令中链接以及直接使用ld个
。
如果有C编译器选项必须被适当使用编译某些文件,不要将其包含在CFLAGS公司
。用户希望能够指定CFLAGS公司
他们自己自由的。相反,安排将必要的选项传递给C编译器独立于CFLAGS公司
,通过在编译命令或定义隐式规则,如下所示:
CFLAGS=-gALL_CFLAGS=-I.$(CFLAGS).c.o公司:$(CC)-c$(CPPFLAGS)$(ALL_CFLAGS)$<
务必包括“-克'中的选项CFLAGS公司
,因为那不是必修的以便正确编译。您可以将其视为默认值这只是推荐的。如果将包设置为默认情况下使用GCC编译,那么您还可以包括“-哦’默认值为CFLAGS公司
也。
放置CFLAGS公司
编译命令中的最后一个,在其他变量之后包含编译器选项,因此用户可以使用CFLAGS公司
到超越其他人。
CFLAGS公司
应该在每次调用C编译器时使用,既有编译的,也有链接的。
每个Makefile都应该定义变量安装
,这是用于将文件安装到系统中的基本命令。
每个Makefile还应该定义变量安装_程序
和安装数据
。(默认为安装_程序
应该是$(安装)
; 的默认值安装数据
应该是${安装}-m 644
.)然后应使用这些变量作为用于实际安装的命令,用于可执行文件和非可执行文件分别是。这些变量的最小使用如下:
$(INSTALL_PROGRAM)foo$(bindir)/foo$(INSTALL_DATA)libfoo.a$(libdir)/libfoo。一
但是,最好支持DESTDIR公司
上的前缀目标文件,如下一节所述。
在一个文件中安装多个文件是可以接受的,但不是必需的命令,最后一个参数是目录,如:
$(INSTALL_PROGRAM)foo bar baz$(bindir)
7.2.4DESTDIR公司
:支持分阶段安装¶
DESTDIR公司
是在每个已安装的目标文件之前添加的变量,这样地:
$(INSTALL_PROGRAM)foo$(DESTDIR)$(bindir)/foo$(INSTALL_DATA)libfoo.a$(DESTDIR)$(libdir)/libfoo。一
这个DESTDIR公司
变量由用户在制作
命令行作为绝对文件名。例如:
DESTDIR公司
应仅在中支持安装*
和卸载*
目标,因为这些是唯一的目标非常有用。
如果您的安装步骤正常安装/usr/local/bin/foo和/usr/local/lib/libfoo。一,然后是如上例所述调用的安装将安装/tmp/stage/usr/local/bin/foo和/tmp/stage/usr/local/lib/libfoo。一而不是。
准备变量DESTDIR公司
以这种方式对每个目标规定分阶段安装,其中未安装文件直接放置到预期位置,但会被复制到一个临时位置(DESTDIR公司
). 但是,已安装的文件维护它们的相对目录结构和任何嵌入的文件名不会被修改。
您不应该设置的值DESTDIR公司
在您的生成文件完全;然后通过以下方式将文件安装到其预期位置违约。此外,指定DESTDIR公司
不应更改以任何方式操作软件,因此其价值不应包含在任何文件内容中。
DESTDIR公司
支持通常用于创建包。它是对于希望了解给定软件包的内容的用户也很有帮助在何处安装,并允许通常没有权限的用户安装到保护区,在获得这些权限。最后,它可以与以下工具一起使用装载
,其中代码安装在一个位置,但会显示使用符号链接或特殊挂载安装在其他地方操作。因此,我们强烈建议GNU包支持DESTDIR公司
尽管这不是绝对要求。
7.2.5安装目录变量¶
安装目录应该始终由变量命名,因此易于安装在非标准位置。这些的标准名称变量及其在GNU包中应该具有的值如下如下所述。它们基于标准文件系统布局;它的变体用于GNU/Linux和其他现代操作系统。
安装程序在调用时应覆盖这些值制作
(例如。,make prefix=/usr安装)或配置
(例如。,configure--前缀=/usr). GNU(全球导航单元)程序包不应该试图猜测哪个值应该适合这些变量安装在系统上:使用此处指定的默认设置使所有GNU包都能正常工作同样,允许安装程序实现任何所需的布局。
所有安装目录及其父目录都应该在安装到之前创建(如果需要)。
前两个变量设置了安装的根。所有的其他安装目录应该是以下目录之一的子目录这两个,不应该直接安装到这两个中目录。
前缀
¶
用于构造所列变量的默认值的前缀如下所示。的默认值前缀
应该是/usr/本地。构建完整的GNU系统时,前缀将为空/用户使用程序将是指向的符号链接/。(如果您正在使用Autoconf,请将其写为“@前缀@’.)
正在运行'进行安装'具有不同的值前缀
从用来构建程序的那个应该不重新编译程序。
执行_前缀
¶
用于构造某些下面列出的变量。的默认值执行_前缀
应该是$(前缀)
。(如果您正在使用Autoconf,请将其写为“@执行_前缀@’.)
一般来说,$(exec_prefix)
用于包含特定于机器的文件(如可执行文件和子例程库),虽然$(前缀)
直接用于其他目录。
正在运行'进行安装'具有不同的值执行_前缀
从用于构建程序的不重新编译程序。
可执行程序安装在以下目录之一。
粘合剂
¶
用于安装用户可以运行的可执行程序的目录。这通常应该是/usr/local/bin,但将其写为$(exec_prefix)/bin。(如果您正在使用Autoconf,请将其写为“@粘合剂@’.)
sbindir公司
¶
用于安装可从中运行的可执行程序的目录shell,但通常只对系统管理员有用。这个通常应该是/usr/local/sbin,但将其写为$(exec_prefix)/sbin。(如果您正在使用Autoconf,请将其写为“@sbindir公司@’.)
libexecdir(库执行目录)
¶
用于安装由其他用户运行的可执行程序的目录程序而不是用户。此目录通常应为/usr/local/libexec,但将其写为$(exec_prefix)/libexec。(如果您正在使用Autoconf,请将其写为“@libexecdir(库执行目录)@’.)
“”的定义libexecdir(库执行目录)'对于所有包都是一样的,因此您应该将数据安装在其中的一个子目录中。大多数程序包将其数据安装在$(libexecdir)/数据包名称/,可能位于其附加子目录中,例如$(libexecdir)/数据包名称/机器/版本。
程序在执行期间使用的数据文件分为以两种方式分类。
- 一些文件通常由程序修改;其他人从不正常修改(尽管用户可以编辑其中的一些)。
- 一些文件是架构相关的,可以由所有人共享现场机器;一些是架构相关的,可以共享仅通过同类机器和操作系统;其他人可能永远不会在两台机器之间共享。
这有六种不同的可能性。然而,我们希望除了对象之外,不鼓励使用与体系结构相关的文件文件和库。制作其他数据文件要干净得多架构依赖性,通常并不难。
下面是Makefiles应该用来指定目录的变量将这些不同类型的文件放入:
- ‘数据根目录’
只读体系结构independent的目录树的根数据文件。这通常应该是/usr/local/share(usr/local/share),但是写为$(前缀)/股.(如果使用Autoconf,请编写它是'@数据根目录@’.) ‘数据目录'的默认值为基于此变量;也是'信息目录’, ‘曼迪尔',和其他。
- ‘数据目录’
用于安装特殊只读的目录该程序的与体系结构无关的数据文件。这通常是与“数据根目录',但我们使用两个分开的变量,以便您可以移动这些特定于程序的文件,而无需更改信息文件、手册页等的位置。
这通常应该是/usr/local/share(usr/local/share),但将其写为$(datarootdir).(如果使用Autoconf,请将其写为‘@数据目录@’.)
“”的定义数据目录'对于所有软件包都是一样的,所以您应该将数据安装在其中的子目录中。大多数程序包将其数据安装在$(数据目录)/数据包名称/。
- ‘sysconfdir系统’
用于安装属于单机&也就是说,用于配置主机的文件。梅勒和网络配置文件,/等/密码,依此类推在这里。此目录中的所有文件都应该是普通ASCII文本文件夹。此目录通常应为/usr/local/etc,但是写为$(前缀)等。(如果您正在使用Autoconf,请将其写为“@sysconfdir系统@’.)
此目录不是安装由生成的可执行文件的正确位置正在运行'制作“-他们可能属于$(libexecdir)或$(sbindir)。也不要在此处安装将在正常使用过程中修改(目的是更改排除的系统的配置)。这些可能是属于$(本地状态目录)。
- ‘共享数据目录’
用于安装architecture-independent数据文件的目录程序在运行时进行修改。这通常应该是/usr/local/com,但将其写为$(前缀)/com。(如果您正在使用Autoconf,请将其写为“@共享数据目录@’.)
- ‘本地状态目录’
安装程序修改的数据文件的目录它们运行,并且属于一个特定的机器。用户不应该需要修改此目录中的文件以配置包的操作;将这些配置信息放在单独的文件中在里面$(数据目录)或$(sysconfdir)。$(本地状态目录)通常应该是/usr/local/var,但将其写为$(前缀)/var。(如果您正在使用Autoconf,请将其写为“@本地状态目录@’.)
- ‘运行状态目录’
用于安装程序修改的数据文件的目录当它们运行时,这与一台特定的机器有关,需要持续时间不超过程序的执行时间例如,通常寿命很长,直到下次重新启动。PID文件for系统守护进程是一种典型的用法。此外,此目录除非在重新启动时,否则不应进行清理,而/临时管理计划(TMPDIR公司
)可以任意清洁。这应该是通常是/var/运行,但将其写为$(localstatedir)/运行。将其作为单独的变量允许使用/运行例如,如果需要。(如果您正在使用Autoconf 2.70或更高版本,将其写为“@运行状态目录@’.)
这些变量指定安装特定文件类型(如果您的程序有)。每个GNU包都应该有信息文件,所以每个程序都需要信息目录',但不是全部需要'图书馆馆长'或'利普迪尔’.
- ‘包括迪尔’
用于安装用户要包含的头文件的目录带有C’的程序#包括'预处理器指令。这个通常应该是/usr/local/include,但将其写为$(前缀)/include。(如果您正在使用Autoconf,请将其写为“@包括ir@’.)
除GCC之外的大多数编译器都不在目录中查找头文件/usr/local/include。因此,以这种方式安装头文件是仅适用于GCC。有时这不是问题,因为这些库实际上只打算与GCC一起使用。但是一些图书馆旨在与其他编译器一起使用。他们应该安装头文件位于两个位置,其中一个由指定包括迪尔
和一个由指定旧的includedir
。
- ‘旧的includedir’
安装目录'#包括'用于的头文件GCC以外的编译器。这通常应该是/usr/include(使用/包含)。(如果您正在使用Autoconf,可以将其写为“@旧的includedir@’.)
Makefile命令应检查旧的includedir
为空。如果是,他们不应该尝试使用它;他们应该取消头文件的第二次安装。
除非标题来自同一个包裹。因此,如果您的Foo包提供头文件食品。小时,则应安装收割台中的文件旧的includedir
目录,如果(1)没有食品。小时那里或(2)食品。小时存在的来自愚人节包装。
判断是否食品。小时来自Foo包裹,放了一个魔法注释的文件部分中的字符串,以及格雷普
对于那根绳子。
- ‘文档目录’
安装文档文件(非Info)的目录这个包裹。默认情况下,它应该是/usr/local/share/doc/你的背包,但应该写为$(datarootdir)/文档/你的背包.(如果使用Autoconf,将其写为“@文档目录@’.) 这个你的背包子目录,其中可以包含版本号,以防止文件与通用名称,例如自述文件。
- ‘信息目录’
用于安装此程序包的信息文件的目录。由默认值,应该是/usr/local/share/info,但应该是写为$(datarootdir)/info.(如果使用Autoconf,将其写为“@信息目录@’.)信息目录
与文档目录
与现有实践兼容。
- ‘html目录’
- ‘dvidir公司’
- ‘脉冲多普勒频移红外’
- ‘公共安全目录’
用于安装特定文档文件的目录格式。它们都应该设置为$(文档目录)
默认情况下。(如果您正在使用Autoconf,请将其写为“@html目录@’,‘@dvidir公司@'等)提供多种翻译的软件包应将其安装在‘$(htmldir)/’全部, ‘$(pdfdir)/’全部等,其中全部是区域设置缩写,如“英语'或'pt_BR(磅/平方英尺)’.
- ‘图书馆馆长’
目标文件和目标代码库的目录。不要在这里安装可执行文件,它们可能应该进入$(libexecdir)而不是。的价值图书馆馆长
通常应该是/usr/local/lib,但将其写为$(exec_prefix)/lib。(如果您正在使用Autoconf,请将其写为“@图书馆馆长@’.)
- ‘利普迪尔’
用于安装此包中任何Emacs Lisp文件的目录。由默认值,应该是/usr/local/share/emacs/site-lisp,但它应写为$(datarootdir)/emacs/site-lisp。
如果使用Autoconf,请将默认值写为“@利普迪尔@’.为了制造@利普迪尔@工作,你需要以下几行在您的配置.ac文件:
lispdir=“${datarootdir}/emacs/site-lisp”AC_SUBST(lispdir)
- ‘当地居民’
为此安装特定于本地语言环境的消息目录包裹。默认情况下,它应该是/usr/local/share/locale,但是它应该写成$(datarootdir)/语言环境.(如果您是使用Autoconf,将其写为“@当地居民@’.) 此目录通常每个语言环境都有一个子目录。
Unix样式的手册页安装在以下位置之一:
- ‘曼迪尔’
用于安装此的手册页(如果有)的顶级目录包裹。通常情况下/usr/local/share/man,但你应该写为$(datarootdir)/人.(如果您正在使用Autoconf,将其写为“@曼迪尔@’.)
- ‘手动1目录’
安装第1节手册页的目录。将其写为$(曼迪尔)/人1。
- ‘man2dir(手动目录)’
安装第2节手册页的目录。将其写为$(曼迪尔)/人2
- ‘…’
-
不要让任何GNU软件的主要文档成为手册页。用Texinfo写一本手册。手册页仅用于为了人们在Unix上运行GNU软件,Unix是次要的仅适用于。
- ‘manext(manext)’
已安装手册页的文件扩展名。这应该包含一个句点,后跟适当的数字;通常应该是“.1’.
- ‘man1分机’
已安装的第1节手册页的文件扩展名。
- ‘man2ext(man2ext)’
已安装的第2节手册页的文件扩展名。
- ‘…’
使用这些名称而不是“manext(manext)'如果软件包需要安装man本手册多个章节中的第页。
最后,您应该设置以下变量:
- ‘源目录’
正在编译的源的目录。这个的价值变量通常由配置
shell脚本。(如果您正在使用Autoconf,请使用'srcdir=@srcdir@’.)
例如:
#安装目录的通用前缀。#注意:启动安装时,此目录必须存在。前缀=/usr/localdatarootdir=$(前缀)/sharedatadir=$(datarootdir)exec_prefix=$(前缀)#将命令“gcc”的可执行文件放在何处。bindir=$(exec_prefix)/bin#放置编译器使用的目录的位置。libexecdir=$(exec_prefix)/libexec#信息文件的放置位置。infodir=$(datarootdir)/info
如果您的程序将大量文件安装到标准的用户特定目录,对它们进行分组可能很有用放入该程序特有的子目录中。如果你这样做,你应该写入安装
创建这些子目录的规则。
不要期望用户在的值中包含子目录名上面列出的任何变量。拥有一套统一的安装目录的变量名使用户能够为几个不同的GNU包指定完全相同的值。在为了使其有用,所有包的设计必须确保当用户这样做时,它们将明智地工作。
有时,并非所有这些变量都可以在当前Autoconf和/或Automake的发布;但从Autoconf 2.60开始,我们相信他们都是。如果缺少任何描述,请参阅此处的描述作为Autoconf将实现的内容的规范。作为一个程序员,您可以使用Autoconf的开发版本或在发布稳定版本之前,避免使用这些变量支持他们。
7.2.6用户标准目标¶
所有GNU程序的Makefile中都应该有以下目标:
- ‘全部的’
编译整个程序。这应该是默认目标。这个目标不需要重建任何文档文件;信息文件应通常包括在分发中,以及DVI(和其他文档格式)文件只能在明确要求时生成的。
默认情况下,Make规则应该编译并与“-克',所以可执行程序具有调试符号。否则,你就是在撞车事故面前基本上是无助的,而且通常情况下易于用新版本复制。
- ‘安装’
编译程序并将可执行文件、库等复制到它们实际使用时应驻留的文件名。如果有用于验证程序是否正确安装的简单测试,此目标应该运行该测试。
安装可执行文件时不要剥离它们。这有助于最终稍后可能需要的调试,现在磁盘空间很便宜和动态加载程序通常确保在正常执行。需要剥离二进制文件的用户可以调用安装-跳闸
目标是做到这一点。
如果可能,写下安装
目标规则,使其不会修改程序生成目录中的任何内容,前提是‘制造所有“刚刚完成。这便于构建程序使用一个用户名,并在另一个用户名下安装。
这些命令应该创建文件所在的所有目录已安装,如果它们还不存在。这包括目录指定为变量的值前缀
和执行_前缀
以及所需的所有子目录。一种方法是通过安装目录
目标如下所述。
使用“-'在安装手册页的任何命令之前,以便制作
将忽略任何错误。这是在有系统的情况下没有安装Unix手册页文档系统的。
安装Info文件的方法是将其复制到$(信息目录)具有$(安装数据)
(参见用于指定命令的变量),然后运行这个安装信息
程序(如果有)。安装信息
是编辑信息的程序目录文件以添加或更新给定信息文件的菜单项;它是Texinfo包的一部分。
下面是安装Info文件的示例规则,该文件还尝试处理一些其他情况,例如安装信息
不在场。
do-install-info:foo.info安装目录$(正常安装)#在中首选信息文件。到srcdir中的一个。如果测试-f foo.info;则d=\否则d=“$(srcdir)”;fi\$(INSTALL_DATA)$$d/foo.info\“$(DESTDIR)$(infodir)/foo.info”#仅在install-info存在时运行它。#使用“if”而不只是在#行,这样我们就可以从安装信息中注意到真正的错误。#使用“$(SHELL)-c”,因为有些SHELL没有#当出现未知命令时,会优雅地失败。$(安装后)if$(SHELL)-c“安装信息--版本”\>/偏差/空值2>&1;然后\install-info--dir file=“$(DESTDIR)$(infodir)/dir”\“$(DESTDIR)$(infodir)/foo.info”\否则为真;fi(菲涅耳)
在编写安装
目标,您必须将所有命令分为三类:普通命令,预安装命令和安装后命令。请参见安装命令类别。
- ‘安装-html’
- ‘安装-dvi’
- ‘安装-pdf’
- ‘安装-ps’
这些目标以Info以外的格式安装文档;它们将由安装程序的人员显式调用包,如果需要该格式。GNU更喜欢Info文件,因此必须由安装安装
目标。
当您有许多文档文件要安装时,我们建议通过安排这些目标来避免碰撞和混乱安装在相应安装目录的子目录中,例如html目录
。例如,如果您的包有多个手册,并且您希望安装包含许多文件的HTML文档(例如“分割”模式输出makeinfo--html
),你会的当然要使用子目录,或使用同名的两个节点在不同的手册中将相互覆盖。
请做这些安装-格式
目标调用用于的命令格式例如,通过格式依赖关系。
- ‘卸载’
删除所有已安装的文件—“安装’和'安装-*'目标创建。
此规则不应修改进行编译的目录,仅安装文件的目录。
卸载命令分为三类,就像安装命令。请参见安装命令类别。
- ‘安装-跳闸’
喜欢安装
,但在安装时删除可执行文件他们。在简单的情况下,此目标可以使用安装
中的目标一种简单的方法:
安装行程:$(MAKE)INSTALL_PROGRAM=“$(INSTALL-PROGRAM)-s”\安装
但是,如果该包安装了脚本和实际可执行文件安装-跳闸
目标不能只引用安装
目标;它必须剥离可执行文件,但不能剥离脚本。
安装-跳闸
不应剥离生成中的可执行文件正在复制以进行安装的目录。它应该只剥离已安装的副本。
通常我们不建议剥离可执行文件,除非您确定这个程序没有bug。但是,可以合理地安装剥离可执行文件以进行实际执行,同时保存未剥离的可在其他地方执行,以防出现错误。
- ‘清洁的’
删除当前目录中通常由创建的所有文件构建程序。如果其他目录中的文件由该生成文件创建。但是,不要删除那些记录配置。还保留可能由建筑,但通常不是,因为分布随附他们。无需删除创建的父目录带有“mkdir-p”,因为他们无论如何都可能存在。
删除.dvi如果文件不属于发行版的一部分,请单击此处。
- ‘分布式清理’
删除当前目录(或由此创建的)中的所有文件makefile)。如果您已经解压缩了源代码并构建了程序,但没有创建任何其他文件,'进行distclean'应只保留文件在分发中。但是,不需要删除使用“”创建的父目录mkdir-p',因为他们无论如何都可能存在。
- ‘最清洁的’
喜欢“清洁的',但可能会避免删除一些通常不想重新编译。例如,“最清洁的’GCC的目标未删除库gcc。一,因为重新编译它很少有必要,而且需要很多时间。
- ‘保持清洁’
删除几乎所有可以使用此Makefile重建的内容。这通常包括删除的所有内容分布式清理
,加上更多:Bison生成的C源文件、标记表、信息文件和等等。
我们之所以说“几乎一切”,是因为运行命令‘使维护人员保持清洁'不应删除配置即使如果配置可以使用Makefile中的规则重新创建。更多一般来说,'使维护人员保持清洁'不应删除任何内容需要存在才能运行配置然后开始构建程序。此外,无需删除父级使用“”创建的目录mkdir-p',因为他们可以无论如何都存在。这些是唯一的例外;保持清洁
应该删除其他可以重建。
“保持清洁'目标旨在由的维护者使用包,而不是普通用户。您可能需要专用工具重建一些文件使维护人员保持清洁'删除。由于这些文件通常包含在发行版中,因此我们不注意使它们易于重建。如果你觉得需要再次打开完整的分发包,不要怪我们。
为了帮助用户了解这一点保持清洁
目标应该从这两个方面开始:
@echo'此命令供维护人员使用;它'@echo'删除可能需要特殊工具才能重建的文件。'
- ‘标签’
更新此程序的标记表。
- ‘信息’
生成所需的任何信息文件。编写规则的最佳方法是跟随:
信息:foo.infofoo.info:foo.texi chap1.exi-chap2.texi$(MAKEINFO)$(srcdir)/foo.texi
必须定义变量MAKEINFO公司
在Makefile中。它应该运行制造信息
这是Texinfo的一部分分配。
通常,GNU发行版附带Info文件,这意味着信息文件存在于源目录中。因此,品牌信息文件的规则应该在源目录中更新它。什么时候?用户构建包,通常Make不会更新信息文件因为它们已经是最新的了。
- ‘数字视频接口’
- ‘html格式’
- ‘pdf格式’
- ‘秒’
以给定格式生成文档文件。这些目标应该始终存在,但如果给定的输出无法生成格式。这些目标不应是依赖项的全部的
目标;用户必须手动调用它们。
以下是从Texinfo生成DVI文件的示例规则:
dvi:食物.dvifoo.dvi:foo.texi chap1.texi chap2.texi$(TEXI2DVI)$(srcdir)/foo.tex公司
必须定义变量德克萨斯州
在Makefile中。它应该运行程序texi2dvi公司
是特新佛的一部分分配。(texi2dvi公司
使用TeX完成格式化。TeX未与Texinfo一起分发。)或者,只写依赖项,并允许GNU制作
提供命令。
下面是另一个示例,这个示例用于从Texinfo生成HTML:
html:foo.htmlfoo.html:foo.texi chap1.texi chap2.texi$(TEXI2HTML)$(srcdir)/foo.texi
同样,您需要定义变量TEXI2HTML公司
在Makefile中;例如,它可能会运行makeinfo--无拆分--html
(制造信息
是Texinfo发行版的一部分)。
- ‘距离’
为此程序创建一个分发tar文件。tar文件应该是设置为tar文件中的文件名以子目录开头name,它是它的分发包的名称。这个name可以包含版本号。
例如,GCC版本1.40的分发tar文件解压缩到名为的子目录一般合同条款-1.40。
最简单的方法是适当地创建子目录命名,使用自然对数
或内容提供商
在其中安装适当的文件,以及然后焦油
该子目录。
用压缩tar文件gzip公司
例如,实际GCC版本1.40的分发文件称为gcc-1.40.tar.gz号文件。也可以支持其他免费压缩格式。
这个距离
目标应该显式依赖于所有非源文件以确保它们在分发中是最新的分配。请参见发布信息。
- ‘检查’
执行自检(如果有)。用户必须在之前构建程序运行测试,但不需要安装程序;你应该写自检,以便在程序构建时可以工作,但不能安装。
建议将以下目标作为程序的常规名称它们在其中很有用。
安装检查
执行安装测试(如果有)。用户必须构建并安装运行测试之前的程序。你不应该假设$(绑定)位于搜索路径中。
安装目录
添加名为“”的目标很有用安装目录'创建安装文件的目录及其父目录。有一个脚本名为mk安装目录哪一个方便这;您可以在Gnulib包中找到它。您可以使用这样的规则:
#确保所有安装目录(例如$(bindir))#如果需要的话,通过制造它们来实现真正的存在。安装目录:mkinstalldirs$(srcdir)/mkinstalldirs$(bindir)$(datadir)\$(库目录)$(信息目录)\$(曼迪尔)
或者,如果您希望支持DESTDIR公司
(强烈鼓励),
#确保所有安装目录(例如$(bindir))#如果需要的话,通过制造它们来实现真正的存在。安装目录:mkinstalldirs$(srcdir)/mk安装目录\$(DESTDIR)$(bindir)$(DEST DIR)@(datadir)\$(DESTDIR)$(libdir)$(DEST DIR)@(infodir)\$(DESTDIR)$(曼迪尔)
此规则不应修改执行编译的目录。它应该只创建安装目录。
7.2.7安装命令类别¶
在编写安装
目标,您必须将所有命令分为三类:普通命令,预安装命令和安装后命令。
普通命令将文件移动到适当的位置,并将其模式。他们不能修改任何文件,除非是完全修改的文件从他们所属的包裹中。
预安装和安装后命令可能会更改其他文件;特别是,它们可以编辑全局配置文件或数据库。
预安装命令通常在正常之前执行命令和安装后命令通常在正常命令。
安装后命令最常见的用法是运行安装信息
。这不能用普通命令完成,因为它更改了一个文件(Info目录),但该文件并非完全来自仅从正在安装的包开始。这是后期安装命令,因为它需要在正常命令之后执行安装包的Info文件。
大多数程序不需要任何预安装命令,但我们有以备不时之需。
要对中的命令进行分类安装
这三个规则类别,插入类别行其中之一。类别行指定后面的命令的类别。
类别行由选项卡和对特殊Make的引用组成变量,并在末尾添加可选注释。有三个您可以使用的变量,每个类别一个;变量名指定类别。类别行在正常执行中是不可用的因为这三个Make变量通常是未定义的(并且不应该在makefile中定义它们)。
以下是三个可能的类别行,每个行都有一个注释解释其含义:
$(安装前)#随后是预安装命令。$(安装后)#安装后命令如下。$(正常安装)#随后是正常命令。
如果在安装
规则,所有命令都被归类为正常命令,直到第一类行。如果不使用任何类别行,则所有命令都是归类为正常。
这些是的类别行卸载
以下为:
$(PRE_UNINSTALL)#随后是预卸载命令。$(POST_UNINSTALL)#安装后命令如下。$(正常_UNINSTALL)#随后是正常命令。
通常,预卸载命令用于删除条目从Info目录中。
如果安装
或卸载
目标具有任何依赖项它充当安装的子例程,然后您应该启动每个带有类别行的依赖项命令,并启动带有类别行的主目标命令。这样,你可以确保每个命令都放在正确的类别中,而不管实际运行的依赖项。
安装前和安装后命令不应运行任何程序,但以下程序除外:
[basename bash cat chgrp chmod chown cmp cp dd diff echo展开expr false查找getopt grep gunzip gzip主机名安装install-info kill ldconfig ln ls md5summkdir mkfifo mknod mv printenv pwd rm rmdir sed排序tee测试触摸真uname xargs是
这样区分命令的原因是为了制作二进制包。通常,二进制包包含所有需要安装的可执行文件和其他文件,并且有自己的安装它们的方法-使其不需要正常运行安装命令。但安装二进制软件包确实需要执行安装前和安装后命令。
构建二进制包的程序通过提取安装前和安装后命令。这里有一种方法提取预安装命令(-秒选择制作
需要静音有关输入的消息子目录):
make-s-n安装-o全部\PRE_INSTALL=预安装\POST_INSTALL=安装后\NORMAL_INSTALL=正常安装\|gawk-f预安装.wk
其中文件预安装.wk可能包含以下内容:
$0~/^(正常安装|安装后)[\t]*$/{on=0}在{print$0}上$0~/^预安装[\t]*$/{on=1}
7.3发布¶
您应该使用一对版本号来标识每个版本主要版本和次要版本。我们不反对使用超过两个数字,但你不太可能真的需要它们。
打包分发Foo版本69.96
在一片焦油中名称为的文件食品-69.96.tar.gz。它应该打开包装名为的子目录食品-69.96。
构建和安装程序时,不得修改任何文件包含在分发中。这意味着形成的所有文件程序的任何部分都必须分类为来源文件夹和非源文件。源文件是由人类编写的并且从未自动更改;非源文件是从由Makefile控制的程序生成源文件。
分发内容应包含名为自述文件带有软件包概述:
- 包裹名称;
- 软件包的版本号,或在可以找到包的版本;
- 软件包功能的一般描述;
- 对文件的引用安装,其中应包含安装程序的说明;
- 任何不寻常的顶级目录的简要说明,或文件或其他提示,供读者查找源代码;
- 对包含复制条件的文件的引用。如果使用GNU GPL,则应该位于名为复制.如果使用GNU LGPL,它应该位于名为复制。LESSER公司。
当然,所有源文件都必须在发行版中。它是可以将非源文件与生成它们的源文件,前提是它们是最新的它们是从源代码生成的,并且依赖于机器,因此分布的正常构建永远不会修改它们。我们通常包括由Autoconf、Automake、,野牛,弯曲
、TeX和制造信息
; 这有助于避免我们的发行版之间不必要的依赖性,以便用户可以安装他们喜欢的任何软件包的任何版本。不要对其他软件产生新的依赖。
实际可能会被生成和修改的非源文件安装程序应该从未包含在分配。因此,如果您确实要分发非源文件,请始终当你制作新的发行版时,确保它们是最新的。
确保分发中的所有文件都是全球可读的,并且该目录是全球可读的和全球可搜索的(八进制模式755)。我们过去建议发行版中的所有目录也世界可写(八进制模式777),因为焦油
否则在提取存档文件时无法处理用户。这在创建存档时很容易导致安全问题,然而,现在我们建议不要这样做。
不要在分发本身中包含任何符号链接。如果焦油文件包含符号链接,人们甚至无法将其解压缩不支持符号链接的系统。此外,不要使用多个不同目录中一个文件的名称,因为某些文件系统无法处理此问题,这会阻止解压缩分配。
请确保所有文件名在MS-DOS上都是唯一的。A类MS-DOS上的名称最多由8个字符组成,可以选择后跟句点和最多三个字符。MS-DOS将截断额外的句点前后的字符。因此,Foobar黑客。c(c)和Foobar黑客。o个不含糊;他们被截断为福巴哈。c(c)和福巴哈。o个,其中包括截然不同。
在您的分发中包含texinfo.tex公司你用过测试打印任何*.texinfo公司或*.特西文件夹。
同样,如果您的程序使用小型GNU软件包,如regex,getopt、obstack或termcap将它们包含在分发文件中。如果不使用它们,将使分发文件在可能给不知道什么的用户带来不便的费用要获取的其他文件。
8非自由软件和文档参考¶
GNU计划不应向任何非免费程序的使用。专有软件是一种社交和道德问题,我们的目标是结束这个问题。我们无法阻止某些人编写专有程序,或停止其他人不会使用它们,但我们可以也应该拒绝向新的潜在客户做广告,或者向公众提供他们的存在是合法的。
自由软件的GNU定义可在GNU网站上找到https://www.gnu.org/philosophy/free-sw.html,以及定义免费文档的https://www.gnu.org/philosophy/free-doc.html.术语“免费”本文档中使用的“非自由”指的是这些定义。
重要许可证列表以及它们是否符合免费条件https://www.gnu.org/licenses/license-list.html。如果不是明确许可证是否符合免费条件,请询问GNU项目通过写信给licensing@gnu.org。我们会回答,如果许可证是一个重要的许可证,我们将把它添加到列表中。
当一个非自由程序或系统众所周知时,您可以在传递它是无害的,因为可能想使用它的用户可能已经知道了。例如,可以解释一下如何在一些广泛使用的非免费软件之上构建包操作系统,或如何与一些广泛使用的操作系统一起使用非自由程序,首先解释如何在GNU上使用它系统。
然而,你应该只提供必要的信息来帮助那些已经使用非免费程序来使用您的程序的用户它不提供或参考关于专有程序,并不意味着专有程序增强你的程序,或者它的存在在任何方面都是一件好事事情。目标应该是人们已经在使用专有的程序将获得他们需要的关于如何使用免费使用它进行编程,而那些尚未使用专有该计划不会看到任何可能引起他们兴趣的东西在里面。
你不应该为非免费程序推荐任何非免费插件,但是可以提到一些免费的插件来帮助它与您的程序,以及如何在需要时安装免费插件运行一些非自由程序。
如果非自由程序或系统在程序域中不明确,你的程序根本不应该提及或支持它,因为这样做会倾向于推广非免费程序您的程序。(您不能指望为您的如果Foobar不存在,则在Foobar用户之间执行程序可能想使用您的程序的人通常都知道。)
有时程序本身是自由软件,但依赖于非自由平台才能运行。例如,它过去是许多Java程序依赖于一些非免费Java库的情况。(请参见https://www.gnu.org/philosophy/java-trap.html)推荐或推广这样的节目就是在推广另一个节目它需要的程序;因此,法官提到前者就好像他们都提到了后者。因此,我们对在自由软件目录中列出Java程序:我们想避免推广非免费Java库。
Java不再有这个问题,但一般原则仍然存在相同:不要推荐、推广或合法化依赖于在非自由软件上运行。
一些自由程序强烈鼓励使用非自由软件。A类典型示例是mplayer(mplayer)
它本身就是自由软件,而且免费代码可以处理某些类型的文件。然而,mplayer(mplayer)
建议对其他类型的文件和安装的用户mplayer(mplayer)
很有可能安装这些编解码器。建议mplayer(mplayer)
实际上,是为了促进非免费编解码器的使用。
因此,您不应该推荐那些强烈鼓励使用非自由软件。这就是为什么我们不列出mplayer(mplayer)
在自由软件目录中。
GNU包不应将用户引向任何非免费文档免费软件。可以免费包含的免费文档操作系统对于完成GNU系统或任何免费操作系统,因此鼓励它是一个优先事项;建议使用我们不允许包含的文档会破坏推动社区制作我们可以制作的文档包括。所以GNU包永远不应该推荐非免费文档。
相比之下,参考年的期刊文章和教科书是可以的用于解释程序如何工作的程序注释,甚至尽管它们不是免费的。这是因为我们不包括这样的GNU系统中的东西,即使它们是自由的,也在软件发行版需要包含的范围。
引用描述或推荐非免费该计划正在推广该计划,因此请不要链接到(或包含此类材料的网站。此政策是与GNU包的网页特别相关。
链接链呢?关注几乎所有网站的链接最终会导致非自由软件的推广;这是这是web固有的特性。以下是我们如何对待这一点。
如果AT&T的网站推荐AT&T,则您不应访问该网站非自由软件包;你不应该参考页面第页链接到AT&T的网站,将其作为获取非自由程序,因为页面的那部分第页它本身推荐非免费程序并使其合法化。
但是,如果第页包含AT&T网站的其他链接目的(如长途电话服务),这不是原因你不应该链接到第页。
网页以一种隐含但特别强大的方式推荐程序如果它要求用户运行该程序才能使用该页面。许多页面都包含他们以这种方式推荐的JavaScript代码。此JavaScript代码可以是免费的或非免费的,但通常是非免费的案例。
如果您引用页面的目的无法实现如果不运行非自由JavaScript代码,则不应引用因此,如果引用页面的目的是为了让人们查看视频或订阅邮件列表,以及查看或如果用户的浏览器阻止非免费JavaScript代码,然后不要引用该页面。
极端的情况是依赖非免费的网站JavaScript代码甚至可以看见页面的内容。任何网站托管于wix.com网站
“有这个问题,还有一些其他站点。让人们阅读这些页面的内容实际上是敦促他们运行那些非免费的程序,所以请不要参考那些页面。(此类页面也会破坏网络,因此有两个原因值得谴责。)
相反,请引用页面中的摘录来表达您的观点,或者找另一个地方参考这些信息。