feat(mix): compile asn1 files

This commit is contained in:
Thales Macedo Garitezi 2024-07-09 16:00:49 -03:00
parent 21313c766d
commit 066fd0481b
2 changed files with 89 additions and 2 deletions

View File

@ -0,0 +1,82 @@
defmodule Mix.Tasks.Compile.Asn1 do
use Mix.Task.Compiler
@recursive true
@manifest_vsn 1
@manifest "compile.asn1"
# TODO: use manifest to track generated files?
@impl true
def manifests(), do: [manifest()]
defp manifest(), do: Path.join(Mix.Project.manifest_path(), @manifest)
@impl true
def run(_args) do
add_to_path_and_cache(:asn1)
Mix.Project.get!()
config = Mix.Project.config()
app_root = File.cwd!()
asn1_srcs = config[:asn1_srcs] || []
manifest_data = read_manifest(manifest())
manifest_modified_time = Mix.Utils.last_modified(manifest())
Enum.each(asn1_srcs, &compile(&1, app_root, manifest_modified_time))
write_manifest(manifest(), manifest_data)
{:noop, []}
end
defp compile(src, app_root, manifest_modified_time) do
%{
src: src_path,
compile_opts: compile_opts
} = src
src_path =
app_root
|> Path.join(src_path)
|> Path.expand()
if stale?(src_path, manifest_modified_time) do
Mix.shell().info("compiling asn1 file: #{src_path}")
:ok = :asn1ct.compile(to_charlist(src_path), compile_opts)
else
Mix.shell().info("file is up to date, not compiling: #{src_path}")
end
end
defp stale?(file, manifest_modified_time) do
with true <- File.exists?(file),
false <- Mix.Utils.stale?([file], [manifest_modified_time]) do
false
else
_ -> true
end
end
defp read_manifest(file) do
try do
file |> File.read!() |> :erlang.binary_to_term()
rescue
_ -> %{}
else
{@manifest_vsn, data} when is_map(data) -> data
_ -> %{}
end
end
defp write_manifest(file, data) do
Mix.shell().info("writing manifest #{file}")
File.mkdir_p!(Path.dirname(file))
File.write!(file, :erlang.term_to_binary({@manifest_vsn, data}))
end
def add_to_path_and_cache(lib_name) do
:code.lib_dir()
|> Path.join("#{lib_name}-*")
|> Path.wildcard()
|> hd()
|> Path.join("ebin")
|> to_charlist()
|> :code.add_path(:cache)
end
end

View File

@ -7,9 +7,14 @@ defmodule EMQXDurableStorage.MixProject do
app: :emqx_durable_storage, app: :emqx_durable_storage,
version: "0.1.0", version: "0.1.0",
build_path: "../../_build", build_path: "../../_build",
# config_path: "../../config/config.exs", compilers: [:yecc, :leex, :elixir, :asn1, :erlang, :app],
erlc_options: UMP.erlc_options(), erlc_options: UMP.erlc_options(),
erlc_paths: UMP.erlc_paths(), erlc_paths: ["gen_src" | UMP.erlc_paths()],
# used by our `compile.asn1` compiler
asn1_srcs: [
%{src: "./asn.1/DurableMessage.asn",
compile_opts: [:per, :noobj, outdir: ~c"gen_src"]}
],
deps_path: "../../deps", deps_path: "../../deps",
lockfile: "../../mix.lock", lockfile: "../../mix.lock",
elixir: "~> 1.14", elixir: "~> 1.14",