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,
|
||||
version: "0.1.0",
|
||||
build_path: "../../_build",
|
||||
# config_path: "../../config/config.exs",
|
||||
compilers: [:yecc, :leex, :elixir, :asn1, :erlang, :app],
|
||||
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",
|
||||
lockfile: "../../mix.lock",
|
||||
elixir: "~> 1.14",
|
||||
|
|
Loading…
Reference in New Issue