非常教程

Erlang 20参考手册

编译器 | compiler

编译器 | compile

模块

编译

模块摘要

Erlang编译器

描述

该模块提供了一个与标准Erlang编译器的接口。它可以生成包含目标代码的新文件,也可以返回可以直接加载的二进制文件。

出口

env_compiler_options()

返回通过环境变量提供的编译器选项ERL_COMPILER_OPTIONS如果该值是一个列表,则按原样返回。如果它不是一个列表,它就被放入一个列表中。

file(File)

file(File, [verbose,report_errors,report_warnings])是一样的。

file(File, Options) -> CompRet

类型

编译文件中的代码File,这是一个Erlang源代码文件,不包含.erl扩展名。Options确定编译器的行为。

如果成功返回{ok,ModuleName},或者error有错误。如果编译成功没有错误,则会创建一个对象代码文件。如果源代码中的模块名称与输出文件的基本名称不同,则认为这是错误的。

可供选择的办法:

basic_validation

该选项是测试模块是否会成功编译的快速方法。这对于想要验证它们发出的代码的代码生成器很有用。没有代码生成。如果启用了erl_lint警告,则还会返回模块生成的警告(如未使用的变量和函数的警告)。

使用选项strong_validation来生成编译器将生成的所有警告。

strong_validation

类似于选项basic_validation。没有生成代码,但会运行更多的编译器传递,以确保生成由优化过程生成的警告(例如,不匹配的子句或保证在运行时出现异常而失败的表达式)。

binary

编译器以二进制形式返回目标代码,而不是创建目标文件。如果成功,编译器会返回{ok,ModuleName,Binary}

bin_opt_info

编译器将发出有关二进制匹配优化(成功和不成功)的信息性警告。有关更多信息,请参见bin_opt_info效率指南中的相关章节。

compressed

编译器会压缩生成的目标代码,这对嵌入式系统很有用。

debug_info

在编译的光束模块Erlang Abstract Formatdebug_info块中包含调试信息。诸如Debugger,Xref和Cover之类的工具要求包含调试信息。

警告:源代码可以从调试信息重建。使用加密的调试信息(encrypt_debug_info)来防止这种情况。

有关详情,请参阅beam_lib(3)

{debug_info, {Backend, Data}}

包含自定义调试信息,以编译梁模块中的Backend自定义Data模块形式提供。给定的模块必须实现一个debug_info/4功能,并且负责产生不同的代码表示,如在所描述的debug_infobeam_lib(3)

警告:源代码可以从调试信息重建。使用加密的调试信息(encrypt_debug_info)来防止这种情况。

{debug_info_key,KeyString}{debug_info_key,{Mode,KeyString}}

包含调试信息,但对其进行加密,以便在未提供密钥的情况下无法访问它。(也可以提供选项debug_info,但不是必需的。)使用此选项是在测试过程中始终提供调试信息并保护源代码的好方法。

Mode是用于加密调试信息的加密算法的类型。默认(现在是唯一的)类型是des3_cbc

有关详情,请参阅beam_lib(3)

encrypt_debug_info

类似于debug_info_key选项,但该键是从.erlang.crypt档案。

有关详情,请参阅beam_lib(3)

deterministic

省略返回列表中的元组optionssource元组Module:module_info(compile)。这个选项将使得重现性构建变得更容易。

makedep

生成一个Makefile规则来跟踪标题依赖项。不产生任何目标文件。

默认情况下,写入此规则<File>.Pbeam。但是,如果binary设置了选项,则不会写入任何内容,并返回规则Binary

例如,如果您有以下模块:

-module(module).

-include_lib("eunit/include/eunit.hrl").
-include("header.hrl").

此选项生成的Makefile规则如下所示:

module.beam: module.erl \
  /usr/local/lib/erlang/lib/eunit/include/eunit.hrl \
  header.hrl

{makedep_output, Output}

写入生成的规则Output而不是默认值<File>.PbeamOutput可以是一个文件名或一个io_device()。要写入标准输出,请使用standard_io。但是,如果binary已设置,则不会写入任何内容,Output并将结果返回给调用方{ok, ModuleName, Binary}

{makedep_target, Target}

更改发送到的规则的名称Target

makedep_quote_target

Target引用特殊字符(1)中的字符。

makedep_add_missing

将丢失的标头视为生成的文件,并将它们添加到依赖项中。

makedep_phony

为每个依赖项添加一个假目标。

'P'

在文件中,经过预处理和解析转换,生成已解析代码的列表。<File>.P没有产生任何目标文件。

'E'

在执行了所有源代码转换之后,在文件中生成代码的列表。<File>.E没有产生任何目标文件。

'S'

生成文件中汇编程序代码的列表。<File>.S没有产生任何目标文件。

report_errors/report_warnings

导致错误/警告发生时打印出来。

report

两者report_errors和一个简短的表格report_warnings

return_errors

如果设置了该标志,{error,ErrorList,WarningList}则在出现错误时返回。

return_warnings

如果设置了此标志,则另有一个字段,其中包含WarningList,被添加到在成功时返回的元组中。

warnings_as_errors

导致将警告视为错误。自R13B04以来就支持此选项。

return

两者return_errors和一个简短的表格return_warnings

verbose

导致编译器提供更详细的信息,描述它正在做的事情。

{source,FileName}

设置返回的源的值module_info(compile)

{outdir,Dir}

为目标代码设置一个新目录。当前目录用于输出,但在使用此选项指定目录时除外。

export_all

导致导出模块中的所有函数。

{i,Dir}

添加Dir到包含文件时要搜索的目录列表中。遇到-include-include_lib指令时,编译器搜索以下目录中的头文件:

  • "."文件服务器的当前工作目录。
  • 已编译文件的基本名称。
  • 使用i选项指定的目录。首先搜索指定的目录。

{d,Macro}

{d,Macro,Value}

定义一个具有值Value的宏宏。宏的类型是atom,Value可以是任何术语。默认值是真。

{parse_transform,Module}

导致解析转换函数 Module:parse_transform / 2在代码检查错误之前应用于解析的代码。

from_asm

输入文件预计为汇编代码(缺省文件后缀“.S”)。请注意汇编程序文件的格式没有记录,并且可能会在不同版本之间更改。

from_core

输入文件预计是核心代码(默认文件后缀“.core”)。请注意,核心文件的格式没有记录,并且可能在不同版本之间更改。

no_strict_record_tests

不建议使用此选项。

默认情况下,Record#record_tag.field操作的生成代码将验证元组Record的大小是否正确,并且第一个元素是标记 record_tag。使用此选项可省略验证码。

no_error_module_mismatch

通常,编译器会验证源代码中给出的模块名称与输出文件的基本名称相同,如果不匹配,则拒绝生成输出文件。如果您有一个很好的理由(或其他原因)使模块名称与输出文件的名称无关,该选项会禁用该验证(如果不匹配,甚至不会有警告)。

{no_auto_import,[{F,A},...]}

使函数F / A不再从模块erlang自动导入,从而解决BIF名称冲突。如果想要使用与不带模块前缀的自动导入BIF相同的名称调用本地函数,则必须使用此选项来解决与在R14A之前自动导入的BIF有关的名称冲突。

注意

从R14A开始,向前,编译器会在尝试自动导入BIF之前将没有模块前缀的调用解析为本地或导入的函数。如果要调用BIF,请在调用中使用erlang模块前缀,而不是 {no_auto_import,[{F,A},...}}

如果这个选项被写入的源代码,作为一个 -compile指令,语法F / A可以用来代替{F,A} 。例:

-compile({no_auto_import,[错误/ 1]})。

no_auto_import

不要自动从模块erlang导入任何函数。

no_line_info

省略行号信息以便生成稍小的输出文件。

如果警告已打开(上述report_warnings选项),则以下选项控制将生成的警告类型。 除{warn_format,Verbosity}之外,以下所有选项都有两种形式:

  • 一个warn_xxx表单,打开警告。
  • 一种nowarn_xxx形式,关闭警告。

在下面的描述中,列出了用于更改默认值的表单。

{warn_format, Verbosity}

使格式错误的字符串作为参数io:format和类似函数发出警告。

Verbosity选择警告的数量:

  • 0=无警告
  • 1=对无效格式字符串和不正确参数数的警告
  • 2 =无法检查有效性时的警告,例如,格式字符串参数是变量时。

默认的详细程度是1。详细程度0也可以通过选项来选择nowarn_format

nowarn_bif_clash

此选项被删除,如果使用该选项将生成致命错误。

警告

从R14A开始,编译器不再调用自动导入的BIF,如果名称与本地函数或显式导入函数冲突,并且发出没有显式模块名称的调用。相反,调用本地或导入函数。仍在接受nowarn_bif_clash会使调用函数的模块与自动导入的BIF发生冲突,用新旧编译器进行编译,但语义完全不同。这就是为什么删除该选项的原因。

一直不鼓励使用这一选项。从R14A开始,使用它是一个错误。

若要解决BIF冲突,请使用显式模块名称或{no_auto_import,[F/A]}编译器指令

{nowarn_bif_clash, FAs}

此选项被删除,如果使用该选项将生成致命错误。

警告

一直不鼓励使用这一选项。从R14A开始,使用它是一个错误。

若要解决BIF冲突,请使用显式模块名称或{no_auto_import,[F/A]}编译器指令

nowarn_export_all

控件的使用关闭警告。export_all选择。默认情况下,发出警告如果选项export_all也给出了。

warn_export_vars

对第一次定义原语之后引用的所有隐式导出变量发出警告。默认情况下,编译器只对模式中引用的导出变量发出警告。

nowarn_shadow_vars

关闭函数对象中“新”变量的警告,或使用与一些已经定义的变量同名的列表理解。默认情况下,对这些变量发出警告。

nowarn_unused_function

关闭未使用的本地函数的警告。默认情况下,对导出函数没有直接或间接调用的所有本地函数发出警告。编译器在生成的BEAM文件中不包含未使用的本地函数,但是警告对于保持源代码的干净仍然很有用。

{nowarn_unused_function, FAs}

关闭未使用的本地函数的警告,如nowarn_unused_function但只适用于上述的局部函数。FAs是元组{Name,Arity}或者这样的元组的列表。

nowarn_deprecated_function

关闭调用已弃用函数的警告。缺省情况是为每个对编译器已知的函数的调用发出警告,以便不推荐使用。请注意,编译器不知道属性-deprecated(),但在Erlang / OTP中使用已组装的已弃用函数列表。要进行更全面的检查,可以使用Xref工具。另请参见xref(3)功能xref:m/1,也可通过功能访问c:xm/1

{nowarn_deprecated_function, MFAs}

关闭对不推荐函数的调用的警告,如nowarn_deprecated_function但只适用于上述函数。MFAs是元组{Module,Name,Arity}或者这样的元组的列表。

nowarn_deprecated_type

关闭使用不推荐类型的警告。默认情况下,对编译器已知的不推荐类型的每次使用都会发出警告。

nowarn_obsolete_guard

关闭对旧类型测试BIF的调用的警告,例如pid/1list/1...参见Erlang Reference Manual有关类型测试的完整列表,BIF及其旧的对应项。默认情况下,对旧类型测试BIF的调用发出警告。

warn_unused_import

对未使用的导入函数发出警告。默认情况下,不对未使用的导入函数发出警告。

nowarn_unused_vars

默认情况下,除了以下划线开头的变量(“Prolog样式警告”)外,未使用的变量会发出警告。使用此选项关闭此类警告。

nowarn_unused_record

关闭未使用记录类型的警告。默认情况下,对未使用的本地定义记录类型发出警告。

nowarn_get_stacktrace

关闭使用警告get_stacktrace/0在将来的发行版中,它可能无法工作。例如,默认情况下,如果get_stacktrace/0catch表情。

编译器在优化和代码生成期间会生成另一类警告。他们警告那些永远不会匹配的模式(例如a=b),总是评估为假的守卫,以及总是失败的表达(如atom+42)。

这些警告不能禁用(除非禁用所有警告)。

编译器不会警告它没有尝试优化的表达式。例如,编译器尝试评估1/0,检测到它会导致异常,并发出警告。但是,X/0由于其中的变量,编译器对类似表达式保持沉默。因此,编译器甚至不尝试评估,因此它不会发出警告。

警告

没有警告并不意味着代码中没有剩余的错误。

除include路径({i,Dir})外,所有选项都可以在带有属性的文件中给出-compile([Option,...])-compile()在函数定义之后允许属性。

选项{nowarn_unused_function, FAs}{nowarn_bif_clash, FAs}{nowarn_deprecated_function, MFAs},只有在文件中给出时才被识别。他们不受选项warn_unused_functionwarn_bif_clashwarn_deprecated_function

对于编译器的调试,或纯粹的好奇心,可以检查每个编译器生成的中间代码。要打印生成列表文件的完整选项列表,请compile:options()在Erlang shell提示符下输入。选项按照执行顺序打印。如果使用多个列表选项,则表示最早传递的那个选项将生效。

未识别的选项将被忽略。

WarningListErrorList具有以下格式:

[{FileName,[ErrorInfo]}].

ErrorInfo将在本节稍后介绍。这里包含文件名,因为编译器使用Erlang预处理器epp,它允许将代码包含在其他文件中。因此,重要的是要知道错误或警告的行号涉及哪个文件。

forms(Forms)

forms(Forms, [verbose,report_errors,report_warnings])是一样的。

forms(Forms, Options) -> CompRet

类型

与之类似file/1,但是将形式列表(以Erlang抽象格式表示形式)作为第一个参数。选项binary是隐含的,也就是说,不生成目标代码文件。对于通常产生列表文件的选项,例如'E',将返回该编译器的内部格式(Erlang术语,通常不是二进制),而不是二进制文件。

format_error(ErrorDescriptor) -> chars()

类型

使用ErrorDescriptor并返回描述错误的深层字符列表。当处理ErrorInfo结构(在章节中描述Error Information)时,通常会隐式地调用此函数。

output_generated(Options) -> true | false

类型

确定编译器是否生成beam具有给定选项的文件。true意味着beam生成一个文件。false意味着编译器生成一些列表文件,返回一个二进制文件,或仅仅检查源代码的语法。

noenv_file(File, Options) -> CompRet

file/2,除了ERL_COMPILER_OPTIONS没有咨询环境变量。

noenv_forms(Forms, Options) -> CompRet

forms/2,除了ERL_COMPILER_OPTIONS没有咨询环境变量。

noenv_output_generated(Options) -> true | false

类型

就像output_generated/1,除了环境变量ERL_COMPILER_OPTIONS没有咨询过。

默认编译器选项

(主机操作系统)环境变量ERL_COMPILER_OPTIONS可用于给出默认编译器选项。它的值必须是一个有效的Erlang术语。如果该值是一个列表,则按原样使用。如果它不是一个列表,它将被放入一个列表中。

该列表将追加到给任何选项file/2forms/2output_generated/2。使用替代函数noenv_file/2noenv_forms/2或者noenv_output_generated/2如果您不希望查阅环境变量,例如,如果从解析转换内部递归调用编译器。

该列表可以通过检索env_compiler_options/0

内联

编译器可以在Erlang模块内部进行函数内联。内联意味着函数的调用被替换为函数体,参数被替换为实际值。语义被保留,除非在内联代码中生成异常。据报异常情况发生在身体被插入的功能中。此外,function_clause例外情况也转换为类似的case_clause例外情况

内联函数时,如果导出原函数(通过显式导出或export_all给出选项),或者不是所有对函数的调用都内联,则保留原函数。

内联不一定会改善运行时间。例如,内联可以增加梁堆栈的使用,这可能会损害递归函数的性能。

内联从来都不是默认的。必须使用编译器选项或-compile()属性在源模块中。

要启用内联,可以使用该选项inline让编译器确定要内联哪些函数,或者{inline,[{Name,Arity},...]}让编译器内联所有对给定函数的调用。如果该选项compile在Erlang模块中的指令内给出,{Name,Arity}可写为Name/Arity

显式内联的示例:

-compile({inline,[pi/0]}).

pi() -> 3.1416.
    

隐式内联的示例:

-compile(inline).

该选项{inline_size,Size}控制允许内联的大型函数的大小。缺省值是24,它使内联代码的大小与非内联版本大致相同(仅内联了相对较小的函数)。

例子:

%% Aggressive inlining - will increase code size.
-compile(inline).
-compile({inline_size,100}).

列表函数内联

编译器还可以从模块内联各种列表操作函数。list在STDLIB。

必须使用编译器选项或-compile()属性在源模块中。

要启用列表功能的内联,请使用选项inline_list_funcs

以下功能是内联的:

  • lists:all/2
  • lists:any/2
  • lists:foreach/2
  • lists:map/2
  • lists:flatmap/2
  • lists:filter/2
  • lists:foldl/3
  • lists:foldr/3
  • lists:mapfoldl/3
  • lists:mapfoldr/3

解析变换

当程序员想要使用Erlang语法但具有不同的语义时,就会使用解析转换。然后将原始Erlang代码转换为其他Erlang代码。

错误信息

ErrorInfo前面提到的标准是ErrorInfo结构,该结构从所有I/O模块返回。它的格式如下:

{ErrorLine, Module, ErrorDescriptor}

ErrorLine是原子none如果错误不对应于特定行,例如,如果源文件不存在。

通过以下调用获得一个描述错误的字符串:

Module:format_error(ErrorDescriptor)

另见

epp(3), erl_id_trans(3), erl_lint(3), beam_lib(3)

编译器 | compiler相关

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1