defmodule HexagonTpu.MixProject do use Mix.Project @version "0.1.2" @github_url "https://github.com/monoflow-ayvu/hexagon-tpu" # cc_precompiler assembles arch-vendor-os-abi, so abi is just "gnu". @mix_target_triplets %{ "dragon_q6a" => {"aarch64", "nerves", "gnu"} } def project do maybe_set_target_triplet_from_mix_target() [ app: :hexagon_tpu, version: @version, elixir: "~> 1.17", start_permanent: Mix.env() == :prod, deps: deps(), package: package(), description: "QNN (Qualcomm AI Engine Direct) NIF bindings for the Hexagon NPU (QCS6490/HTP)", compilers: [:elixir_make] ++ Mix.compilers(), # Precompiled artifacts serve Hex consumers; anyone hacking on this # repo (dev/test) or setting HEXAGON_TPU_BUILD=1 builds from source. make_force_build: Mix.env() in [:dev, :test] or System.get_env("HEXAGON_TPU_BUILD") in ["1", "true"], make_precompiler: {:nif, CCPrecompiler}, make_precompiler_url: "#{@github_url}/releases/download/v#{@version}/@{artefact_filename}", make_precompiler_filename: "hexagon_tpu_nif", make_precompiler_priv_paths: ["hexagon_tpu_nif.so"], cc_precompiler: [ compilers: %{ {:unix, :linux} => %{ # current_target_from_env() drops the vendor, so dragon_q6a builds # resolve to plain aarch64-linux-gnu. Prefer the Nerves toolchain # when it's on PATH, fall back to the distro cross gcc. "aarch64-linux-gnu" => {aarch64_cc("gcc"), aarch64_cc("g++")}, "aarch64-nerves-linux-gnu" => { "aarch64-nerves-linux-gnu-gcc", "aarch64-nerves-linux-gnu-g++" }, # Host build: only useful with the QNN CPU backend / HTP simulator. "x86_64-linux-gnu" => {"gcc", "g++"} } } ] ] end defp aarch64_cc(tool) do nerves = "aarch64-nerves-linux-gnu-#{tool}" if System.find_executable(nerves), do: nerves, else: "aarch64-linux-gnu-#{tool}" end defp maybe_set_target_triplet_from_mix_target do case Map.get(@mix_target_triplets, System.get_env("MIX_TARGET")) do nil -> :ok {arch, vendor, abi} -> unless keep_external_target_triplet?() do System.put_env("TARGET_ARCH", arch) System.put_env("TARGET_VENDOR", vendor) System.put_env("TARGET_OS", "linux") System.put_env("TARGET_ABI", abi) end end end defp keep_external_target_triplet? do case System.get_env("HEXAGON_TPU_KEEP_TARGET_TRIPLET") do nil -> false value -> String.downcase(value) in ["1", "true", "yes"] end end def application do [ extra_applications: [:logger] ] end defp deps do [ {:nx, "~> 0.9"}, {:telemetry, "~> 1.0"}, {:elixir_make, "~> 0.8", runtime: false}, {:cc_precompiler, "~> 0.1", runtime: false}, {:ex_doc, ">= 0.0.0", only: :dev, runtime: false} ] end defp package do files = ~w( c_src cmake lib CMakeLists.txt Makefile README.md mix.exs ) |> maybe_add_checksum() [ name: "hexagon_tpu", licenses: ["Apache-2.0"], links: %{"GitHub" => @github_url}, files: files ] end defp maybe_add_checksum(files) do if File.exists?("checksum.exs"), do: ["checksum.exs" | files], else: files end end