Skip to content

mix deps.compile can't find reference to a struct from an already compiled dep #12913

@Sinc63

Description

@Sinc63

Elixir and Erlang/OTP versions

Erlang/OTP 25 [erts-13.2.2.2] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Elixir 1.15.5 (compiled with Erlang/OTP 25)

Operating system

Linux 4.18.0-372.9.1.el8.x86_64 #1 SMP Wed May 11 19:58:59 PDT 2022 x86_64 x86_64 x86_64 GNU/Linux

Current behavior

I'm working on updating our environment from Elixir 1.13 to Elixir 1.15. As such I'm in a process of trying to get all our dependencies to compile, which is a stepwise process.

I first encountered an error compiling phoenix_markdown:

==> phoenix_markdown
Compiling 2 files (.ex)
error: Earmark.Options.__struct__/0 is undefined, cannot expand struct Earmark.Options. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
  lib/phoenix_markdown/engine.ex:25: PhoenixMarkdown.Engine.compile/2


== Compilation error in file lib/phoenix_markdown/engine.ex ==
** (CompileError) lib/phoenix_markdown/engine.ex: cannot compile module PhoenixMarkdown.Engine (errors have been logged)
    (stdlib 4.3.1.2) lists.erl:1462: :lists.mapfoldl_1/3
could not compile dependency :phoenix_markdown, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile phoenix_markdown --force", update it with "mix deps.update phoenix_markdown" or clean it with "mix deps.clean phoenix_markdown"

earmark had been compiled in my first pass, this was my second.

Now I have this pair of results, which shows to me that for some reason while compiling a dependency that uses a struct from another dependency, the compiler is somehow unable to find and refer to the struct from the previously compiled dependency.

[root]# mix deps.compile mogrify link_preview
==> link_preview
Compiling 11 files (.ex)
error: Mogrify.Image.__struct__/0 is undefined, cannot expand struct Mogrify.Image. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
  lib/link_preview/parsers/html.ex:139: LinkPreview.Parsers.Html.filter_small_image/2


== Compilation error in file lib/link_preview/parsers/html.ex ==
** (CompileError) lib/link_preview/parsers/html.ex: cannot compile module LinkPreview.Parsers.Html (errors have been logged)
    (stdlib 4.3.1.2) lists.erl:1462: :lists.mapfoldl_1/3
    (stdlib 4.3.1.2) lists.erl:1463: :lists.mapfoldl_1/3
could not compile dependency :link_preview, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile link_preview --force", update it with "mix deps.update link_preview" or clean it with "mix deps.clean link_preview"
[root]# mix deps.compile mogrify link_preview --force
==> mogrify
Compiling 9 files (.ex)
Generated mogrify app
==> link_preview
Compiling 11 files (.ex)
warning: Floki.parse/1 is deprecated. Use `parse_document/1` or `parse_fragment/1` instead.
Invalid call found at 3 locations:
  lib/link_preview/parsers/opengraph.ex:20: LinkPreview.Parsers.Opengraph.title/2
  lib/link_preview/parsers/opengraph.ex:40: LinkPreview.Parsers.Opengraph.description/2
  lib/link_preview/parsers/opengraph.ex:67: LinkPreview.Parsers.Opengraph.images/2

warning: Tempfile.random/1 is undefined (module Tempfile is not available or is yet to be defined)
  lib/link_preview/parsers/html.ex:137: LinkPreview.Parsers.Html.filter_small_image/2

warning: Floki.parse/1 is deprecated. Use `parse_document/1` or `parse_fragment/1` instead.
Invalid call found at 3 locations:
  lib/link_preview/parsers/html.ex:20: LinkPreview.Parsers.Html.title/2
  lib/link_preview/parsers/html.ex:69: LinkPreview.Parsers.Html.images/2
  lib/link_preview/parsers/html.ex:91: LinkPreview.Parsers.Html.search_h/2

Generated link_preview app

The struct from mogrify should be available to link_preview even though mogrify was compiled in a previous pass of deps.compile.

Expected behavior

Two related dependencies should not need to be compiled in the same pass of deps.compile for the second app to refer to a struct from the first app. As long as the app containing the struct is already compiled it's structs should be available to other apps when compiled separately.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions