{"id":15099937,"url":"https://github.com/cocoa-xu/fennec_precompile","last_synced_at":"2025-10-08T05:31:18.317Z","repository":{"id":40989118,"uuid":"508105110","full_name":"cocoa-xu/fennec_precompile","owner":"cocoa-xu","description":"Drop-in library for `:elixir_make` for precompiling NIF binaries with Zig as the cross-compiler.","archived":true,"fork":false,"pushed_at":"2022-12-02T13:52:25.000Z","size":103,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-07T17:25:51.030Z","etag":null,"topics":["elixir","elixir-library","zig"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cocoa-xu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-28T00:41:31.000Z","updated_at":"2022-12-02T13:52:28.000Z","dependencies_parsed_at":"2023-01-22T22:30:33.053Z","dependency_job_id":null,"html_url":"https://github.com/cocoa-xu/fennec_precompile","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/cocoa-xu/fennec_precompile","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoa-xu%2Ffennec_precompile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoa-xu%2Ffennec_precompile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoa-xu%2Ffennec_precompile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoa-xu%2Ffennec_precompile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cocoa-xu","download_url":"https://codeload.github.com/cocoa-xu/fennec_precompile/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cocoa-xu%2Ffennec_precompile/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278892120,"owners_count":26063933,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","elixir-library","zig"],"created_at":"2024-09-25T17:41:20.048Z","updated_at":"2025-10-08T05:31:17.925Z","avatar_url":"https://github.com/cocoa-xu.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FennecPrecompile\n\n(This repo is archived, please use [`cc_precompiler`](https://github.com/cocoa-xu/cc_precompiler))\n\nDrop-in library for `:elixir_make` for precompiling NIF binaries with Zig as the cross-compiler.\n\nThis work is inspired by ~~(massively copy-and-paste from)~~ [`rustler_precompiled`](https://github.com/philss/rustler_precompiled). However, this library is more focused on crosscompiling C/C++ projects using Zig as a cross-compiler whereas `rustler_precompiled` is focused on crosscompiling Rust projects to NIF using Rust with [`rustler`](https://github.com/rusterlium/rustler).\n\n## Installation\n\nIf [available in Hex](https://hex.pm/docs/publish), the package can be installed\nby adding `fennec_precompile` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:fennec_precompile, \"~\u003e 0.3.0\"}\n  ]\nend\n```\n\nDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)\nand published on [HexDocs](https://hexdocs.pm). Once published, the docs can\nbe found at \u003chttps://hexdocs.pm/fennec_precompile\u003e.\n\n## Usage\n### Setup `elixir_make`\nAdd `:elixir_make` to the `compilers` list and set `make_precompiler` to `FennecPrecompile` to use `fennec_precompile`. \n\n### Setup fennec_precompile specific config values\n`fennec_base_url` should be set to the base URL of the precompiled binaries.\n`fennec_nif_filename` will be used to indicate the file name of the compiled shared library.\n\n```elixir\n@version \"0.1.0\"\ndef project do\n  [\n    # ...\n    version: @version,\n    compilers: [:elixir_make] ++ Mix.compilers(),\n    make_precompiler: FennecPrecompile,\n    fennec_nif_filename: \"stb_image_nif\",\n    fennec_base_url: \"https://github.com/me/myproject/downloads/releases/v#{@version}\"\n    # ...\n  ]\nend\n```\n\nA table of supported environment variables, their scopes and examples can be found in the [`Enviroment Variable`](#environment-variable) section.\n\n## Precompile NIFs\nPrecompiling happens when run `mix elixir_make.precompile`.\n```elixir\n# optional settings to override the default cache directory\nexport ELIXIR_MAKE_CACHE_DIR=\"$(pwd)/cache\"\n\n# precompile\nmix elixir_make.precompile\n\n# it's also possible to run `mix elixir_make.precompile` with other flags \n# other flags will be passed to `:elixir_make`\nmix elixir_make.precompile --my-flag\n```\n\nWhat happens when you run `mix elixir_make.precompile`?\n\n- `CC` will be set to `zig cc -target \"ARCH-OS-ABI\"`\n- `CXX` will be set to `zig c++ -target \"ARCH-OS-ABI\"`\n- `CPP` will be set to `zig c++ -target \"ARCH-OS-ABI\"`\n\nEverything else is the same as when you run `mix compile` (with `:elixir_make`, or `mix compile.elixir_make`).\n\nThe following targets will be compiled by default:\n\n- macOS\n  - x86_64-macos\n  - aarch64-macos\n- Linux\n  - x86_64-linux-gnu\n  - x86_64-linux-musl\n  - aarch64-linux-gnu\n  - aarch64-linux-musl\n  - riscv64-linux-musl\n- Windows\n  - x86_64-windows-gnu\n\nA full list of supported targets can be found using `zig targets`.\n\nIt's worth noting that some targets may not successfully compile on certain platforms. For example, `x86_64-macos` will not compile on Linux and `x86_64-windows-msvc` will not compile on macOS.\n\n### Specifying targets to compile\nTo compile for a specific target/a list of targets, set the `FENNEC_PRECOMPILE_TARGETS` environment variable.\n\n```elixir\n# for example, to compile for aarch64-linux-musl,riscv64-linux-musl\nexport ELIXIR_MAKE_CACHE_DIR=\"$(pwd)/cache\"\nexport FENNEC_PRECOMPILE_TARGETS=\"aarch64-linux-musl,riscv64-linux-musl\"\nmix elixir_make.precompile\n```\n\n## Fetch Precompiled Binaries\nTo fetch precompiled binaries, run `mix elixir_make.fetch`.\n```elixir\n# fetch all precompiled binaries\nmix elixir_make.fetch --all\n# fetch specific binaries\nmix elixir_make.fetch --only-local\n\n# print checksums\nmix elixir_make.fetch --all --print\nmix elixir_make.fetch --only-local --print\n```\n\n## Use zig for native build\nThis section only relates to the behaviour of the `mix compile` and `mix compile [--args] ...` commands.\n\nFor native build, `zig` is not used by default for two reasons. \n\n1. For users who are only interested in using the app their native host, it is not necessary to compile the app using Zig.\n2. As this tool aim to be a drop-in replacement for `:elixir_make`, the default behaviour of `mix compile` and `mix compile [--args] ...` of this tool is the same as what would be expected with `:elixir_make`.\n\nHowever, you can choose to always use `zig` as the compiler by setting environment variable `FENNEC_PRECOMPILE_ALWAYS_USE_ZIG` to `true`.\n\nTo be more specific, by default, the environment variables `CC`, `CXX` and `CPP` will not be changed by this tool when running `mix compile` or `mix compile [--args] ...`. When `FENNEC_PRECOMPILE_ALWAYS_USE_ZIG` is `true`, the compiled NIF binaries (for the native host, identified as `ARCH-OS-ABI`) should be the same as the one generated by `mix elixir_make.precompile`.\n\nFor example, when running `mix compile` or `mix compile [--args]` on arm64 macOS with this option set to `true`, files in the `_build/${MIX_ENV}/lib/my_app/priv` directory should match the ones in the `my_app-nif-NIF_VERSION-aarch64-macos-VERSION.tar.gz` generated by `mix elixir_make.precompile`.\n\nTo install Zig from a package manager, please refer to the officail guide from zig, [Install Zig from a Package Manager](https://github.com/ziglang/zig/wiki/Install-Zig-from-a-Package-Manager).\n\n## Where is the precompiled binaries?\nThe path of the cache directory is determined in the following order:\n\n  1. `$ELIXIR_MAKE_CACHE_DIR`\n  2. `:filename.basedir(:user_cache, \"\", ...)`\n\nIf the environment variable `ELIXIR_MAKE_CACHE_DIR` is set, the cache directory will be `$ELIXIR_MAKE_CACHE_DIR`. Otherwise, the cache directory will be determined by the following function:\n\n```elixir\ncache_opts = if System.get_env(\"MIX_XDG\"), do: %{os: :linux}, else: %{}\ncache_dir = :filename.basedir(:user_cache, \"\", cache_opts)\n\ncache_dir =\n  System.get_env(\"ELIXIR_MAKE_CACHE_DIR\", cache_dir)\n  |\u003e Path.join(sub_dir)\n```\n\n## Environment Variable\n- `FENNEC_PRECOMPILE_TARGETS`\n  \n  Only used when running `mix elixir_make.precompile`. This environment variable is mostly used in CI or temporarily  specify the target(s) to compile. \n  \n  It is a comma separated list of targets to compile. For example,\n  \n  ```shell\n  export FENNEC_PRECOMPILE_TARGETS=\"aarch64-linux-musl,riscv64-linux-musl\"\n  mix elixir_make.precompile\n  ```\n\n  If `FENNEC_PRECOMPILE_TARGETS` is not set, the `fennec_precompile` will then check `config/config.exs` to see if there is a `:fennec_targets` key for `my_app`. If there is, the value of the key will be the targets.\n\n  ```elixir\n  import Config\n\n  config :fennec_precompile, :config, my_app: [\n    fennec_targets: [\"aarch64-linux-musl\", \"riscv64-linux-musl\"]\n  ]\n  ```\n\n  `:fennec_targets` in the `project` will only be used in the following cases:\n  ```elixir\n  def project do\n    [\n      # ...\n      fennec_targets: [\"aarch64-linux-musl\", \"riscv64-linux-musl\"]\n    ]\n  end\n  ```\n\n    1. When `:fennec_force_build` is set to `true`. In this case, the `:fennec_targets` acts as a list of compatible targets in terms of the source code. For example, NIFs that are specifically written for ARM64 Linux will fail to compile for other OS or CPU architeture. If the source code is not compatible with the current node, the build will fail.\n    2. When `:fennec_force_build` is set to `false`. In this case, the `:fennec_targets` acts as a list of available targets of the precompiled binaries. If there is no match with the current node, no precompiled NIF will be downloaded and the app will fail to start.\n\n- `FENNEC_PRECOMPILE_ALWAYS_USE_ZIG`\n\n  Only used when running `mix compile` or `mix compile [--args] ...`. \n  \n  It is a boolean value. When set to `true`, `zig` will be used as the compiler instead of the default `$CC`, `$CXX` or `$CPP`. For more information, please refer to the section above, [Use zig for native build](#use-zig-for-native-build).\n\n  ```shell\n  # this is the default, equivalent to run `mix compile` with `:elixir_make`\n  unset FENNEC_PRECOMPILE_ALWAYS_USE_ZIG\n  mix compile\n\n  # this will force using zig as the compiler\n  export FENNEC_PRECOMPILE_ALWAYS_USE_ZIG=true\n  mix compile\n  ```\n\n## License\n\nCopyright 2022 Cocoa Xu\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcocoa-xu%2Ffennec_precompile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcocoa-xu%2Ffennec_precompile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcocoa-xu%2Ffennec_precompile/lists"}