extra_applications(:host): probe fs for :wx instead of code:lib_dir/1 - #82
Merged
Merged
Conversation
After PR #80 the `extra_applications(:host)` check uses `:code.lib_dir(:wx)` to decide whether to include `:wx` in the generated `desktop.app`. That call consults Erlang's `NameDb` ETS table, which only knows about apps that have been loaded into the running VM. `mix deps.compile` runs each dep's `compile.all` in sequence, and each `compile.all` prunes the code path to only the apps the dep declared (see `Code.delete_paths(current_paths -- loaded_paths)` in `Mix.Tasks.Compile.All`). After the first dep that does not list `:wx` in its apps finishes, `:wx` is removed from both the code path AND from `NameDb`. By the time `desktop.application/0` is evaluated for the `:desktop` dep itself, `code:lib_dir(:wx)` returns `{:error, :bad_name}`, so `:wx` is dropped from `desktop.app` even though the wx app is still on disk and `wx.hrl` is still resolvable. The concrete failure window this opens: 1. `ensure_desktop_wx_erl!/0` runs while `NameDb` is still populated (before `compile.all` prunes), so `wx_headers_resolvable?/0` is true and `src/desktop_wx.erl` is generated with `-include_lib("wx/include/wx.hrl")`. 2. `extra_applications(:host)` runs after pruning, so `:wx` is not added to the app file. 3. `compile.erlang` then fails with `can't find include lib "wx/include/wx.hrl"`. (Side note: `mix deps.compile` passes `--no-code-path-pruning` to disable pruning, but `Mix.Tasks.Compile.All` only honors `--no-prune-code-paths` — different strings — so pruning still happens regardless of the intent.) Fix: probe the filesystem directly, mirroring what `wx_headers_resolvable?/0` already does. The filesystem state is independent of `NameDb` and stays consistent across the build. Tested locally on diode-drive: a fresh `mix deps.compile` previously failed with `can't find include lib "wx/include/wx.hrl"`; after this patch it succeeds and `_build/dev/lib/desktop/ebin/desktop.app` lists `:wx` in its `applications` entry. The behavior on hosts without `:wx` is preserved — `wx_app_on_disk?/0` returns false and the stub backend is used. Co-authored-by: Cursor <cursoragent@cursor.com>
dominicletz
added a commit
that referenced
this pull request
Aug 8, 2026
Enum.find/2 returns nil when no matching directory is found, but the
with clause used an unbound pattern that silently matched nil and let
the body run with wx_dir = nil, crashing Path.join/1 with:
** (FunctionClauseError) no function clause matching in
IO.chardata_to_string/1 (called with nil)
(elixir 1.16.3) lib/path.ex:672: Path.do_join/3
lib/desktop/mix.exs: Desktop.MixProject.wx_app_on_disk?/0
Reproducible on any OTP build configured --without-wx (e.g. the
elixir-desktop/ddrive macOS installer CI): the OTP root's lib/
directory has no wx-* entry, Enum.find returns nil, and the probe
crashes instead of returning false.
Add an is_binary(wx_dir) guard so the with chain falls through to
the existing `else _ -> false` clause on a no-wx host, and document
the pitfall in the comment block above extra_applications/1.
Fixes the regression introduced in #82 and unblocks downstream PRs
that bump the desktop dep to include the fs probe.
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After #80 added the
:wxguard inextra_applications(:host), freshmix deps.compileruns on hosts that havewxon disk can still failwith:
Root cause
The guard uses
:code.lib_dir(:wx)which consults Erlang'sNameDbETS table.
NameDbonly knows about apps that have been loaded intothe current VM.
mix deps.compileruns each dep'scompile.allin sequence, and eachcompile.allprunes the code path to only the apps the dep declared(
Code.delete_paths(current_paths -- loaded_paths)inMix.Tasks.Compile.All). After the first dep that does not list:wxin its apps finishes,
:wxis removed from both the code path ANDfrom
NameDb. By the timedesktop.application/0is evaluated forthe
:desktopdep itself,code:lib_dir(:wx)returns{:error, :bad_name}, so:wxis dropped fromdesktop.appeventhough the wx app is still on disk and
wx.hrlis still resolvable.The failure window:
ensure_desktop_wx_erl!/0runs whileNameDbis still populated(before
compile.allprunes), sowx_headers_resolvable?/0istrue and
src/desktop_wx.erlis generated with-include_lib("wx/include/wx.hrl").extra_applications(:host)runs after pruning, so:wxis notadded to the app file.
compile.erlangfails withcan't find include lib "wx/include/wx.hrl".(Side note:
mix deps.compilepasses--no-code-path-pruningtodisable pruning, but
Mix.Tasks.Compile.Allonly honors--no-prune-code-paths— different strings — so pruning stillhappens regardless of the intent. Filing that separately.)
Fix
Probe the filesystem directly, mirroring what
wx_headers_resolvable?/0already does. The filesystem state is independent of
NameDband staysconsistent across the build.
Test plan
mix deps.compileon a clean build completes end to endwith
:wxpresent in_build/dev/lib/desktop/ebin/desktop.app.mix compilecontinues to succeed.:wxstill see the stub backend generated(
wx_app_on_disk?/0returns false).Local reproduction was on
diode-drive(Apple Silicon, OTP 26.2.5custom build, Elixir 1.16.3-otp-24). The full
mix deps.compileandmix compileboth succeed with this patch and exercise the sameextra_applications(:host)code path that fails without it.Co-authored-by: Cursor cursoragent@cursor.com
Made with Cursor