feat(mix): compile asn1 files
This commit is contained in:
parent
21313c766d
commit
066fd0481b
|
@ -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
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue