自定义编译器模块
这是 Rebar3 3.7.0 中的一个新功能,用于编写要与之一起使用的自定义编译器。当您拥有想要与 Erlang 资源一起构建的不同语言的文件时,此功能非常有用。从 Rebar3 3.14.0 开始,该接口得到了增强,可以更好地跟踪有向无环图 (DAG) 中的文件,这使您可以注释构建工件,并允许 Rebar3 跟踪应用程序之间的依赖关系。
此接口目前在内部用于 .xrl
、.yrl
和 .mib
文件。很少有插件尝试过它。
🚧
这是一个不稳定的接口
由于我们还没有很多插件作者尝试过此接口,因此将其标记为不稳定,并且可能会发生更改。
我们正在寻求贡献者的帮助,以便在将其标记为稳定之前进一步稳定它。如果您愿意联系我们并帮助迭代 自定义编译器插件 中提供的功能,则应使用此功能。
您的自定义编译器可能需要更复杂的内容。例如,此接口提供的工具不足以构建使用
mix
作为构建工具运行的项目,并且该插件使用 自定义编译器插件。
当前接口
定义了以下回调函数
%% specify what kind of files to find and where to find them. Rebar3 handles
%% doing all the searching from these concepts.
context(AppInfo) ->
%% Mandatory Fields
%% directories containing source files
#{src_dirs => ["/path/to/src/"],
include_dirs => ["/path/to/includes/"],
src_ext => ".erl",
out_mappings => [{".beam", "/path/to/ebin"}],
%% Optional Fieldsstate passed to dependencies callback
dependencies_opts => term()}. % optional, v3.14+
%% Define which files each of the files depends on, including includes and whatnot.
%% This is then used to create a digraph of all existing files to know how to propagate
%% file changes. The Digraph is passed to other callbacks as `G' and annotates all files
%% with their last changed timestamp
%% Prior to 3.14, the `State' argument was not available.
dependencies("/path/to/file.erl", "/path/to/",
["/path/to/all/other_sources/", ...], State) ->
["path/to/deps.erl", ...].
%% do your own analysis aided by the graph to specify what needs re-compiling.
%% You can use this to add more or fewer files (i.e. compiler options changed),
%% and specify how to schedule their compilation. One thing we do here for
%% Erlang files is look at the digraph to only rebuild files with newer
%% timestamps than their build artifacts (which are also in the DAG after the
%% first build) or those with compiler options that changed (the
%% compile_and_track callback lets you annotate artifacts)
needed_files(G, ["/path/to/all/files.erl", ...], [{".beam", "/path/to/ebin"}], AppInfo) ->
%% the returned files to build essentially specify a schedule and priority with special
%% option sets
%% Files that _must_ be built first like those in parse transforms, with
%% different build options
{{["/top/priority/files.erl"], CompilerOpts},
%% {Sequential, Parallel} build order for regular files, with shared
%% compiler options
{{["/path/to/file.erl", ...], ["other/files/mod.erl", ...]}, CompilerOpts}}.
%% Compilation callback with the ability to track build artifacts in the DAG itself.
%% Introduced in 3.14. Prior to this version, refer to `compile/4'.
compile_and_track("/path/to/file.erl", [{".beam, "/path/to/ebin"}],
AppOptDict, CompilerOpts) ->
%% Successfully built a file, tying it to artifacts with optional metadata
{ok, [{"/path/to/file.erl", "path/to/ebin/file.beam", Metadata}]} |
%% Successfully built a file, but it has compiler warnings
{ok, [{"/path/to/file.erl", "path/to/ebin/file.beam", Metadata}],
["Some compiler warning"]} |
%% Failed build
{error, ["error strings"], ["warning strings"]} | error.
%% A simpler compilation mechanism which does not track build artifacts into the
%% DAG for the compiler. Change for built files must be figured out from files on
%% disk or other storage.
compile("/path/to/file.erl", [{".beam", "/path/to/ebin"}],
AppConfig, CompilerOpts) ->
ok
| {ok, ["Some compiler warning"]}
| {ok, ["error strings"], ["warning strings"]}.
%% Just delete files however you need to
clean(["/path/to/file"], AppInfo) -> _.
将编译器模块初始化为插件
在注册 自定义编译器插件 的同一位置注册编译器模块
%% Note: the name of the module matches the name of the plugin application
-module(my_compiler_plugin).
-export([init/1]).
%% Called when Rebar3 first boots, before even parsing the arguments
%% or commands to be run. Purely initiates the provider, and nothing
%% else should be done here.
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
%% Optional:
%% Provider = providers:create([Options]),
%% State1 = rebar_state:add_provider(State, Provider),
%% This adds the new compiler module:
State1 = rebar_state:append_compilers(State, [my_compiler_mod]),
%% If needing the new compiler module to take precedence over
%% other ones (i.e. generating .erl files from another format):
State2 = rebar_state:prepend_compilers(State1, [translator_mod]),
{ok, State2}.
上次修改时间:2024年1月11日:更新 custom_compiler_modules.md (3c0a8ba)