Multiple modules in compilecache file?

I was down a rabbithole trying to understand why I am getting multiple versions of a single package loaded in my application. And I think I narrowed it down to the fact that one of precompile cache files contains two “modules”. What I couldn’t figure out was why this happened and what I did wrong.

Here’s an illustration of this problem (not the actual code):

module A

end

module B

using A

end

module C

using A

end

using B
using C
# ┌ Warning: Replacing module `A`
# └ @ Base loading.jl:1036

println(pointer_from_objref(B.A))
println(pointer_from_objref(C.A))

I expect it to print the same pointer twice, but in fact I get different pointers. In my case A, B and C are separate packages.

My diagnostics took me to write this snippet:

function check_compilecache(pkgid)
    pkg_cache_paths = Base.find_all_in_cache_path(pkgid)
    for cachefile in pkg_cache_paths
        try
            modules = open(cachefile, "r") do io
                Base.isvalid_cache_header(io)
                Base.parse_cache_header(io)
            end[1]
            println(cachefile => modules)
        catch e
            println(cachefile => e)
        end
    end
end

So when I do check_compilecache(Base.PkgId(UUID("xxxx-xxxx-xxx"), "C")) it tells me that one of cache files has two modules: C and A. Which, I think, means that using B loads module A from A’s own compilecache, and using C loads C as well as another instance of A.

I am sorry if I missed some important detail, but I’ve kept a copy of compilecache and can probably inspect it more if anyone is kind enough to help me dig further.

This is all done running julia-1.7.2 in case it’s important

1 Like