自訂編譯器模組
這是 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)