Using multiple modules in a package

I’ve been coding in Julia for a while but only recently have I started developing packages. Right now I’ve activated a new environment, called A. Environment A wants to define a package, also called A, and so there is a file names A.jl under the A/src directory. A, in turn, needs to use modules B, C, and D, so there are also B.jl, C.jl, and D.jl files under source, and A.jl consists solely of

module A
   include("B.jl")
   include("C.jl")
   include("D.jl")
end

when I try “using A” I get the following error:

julia> using A
[ Info: Precompiling A [376ac33e-dbe2-4852-b43b-cb274be2c3c1]
ERROR: LoadError: LoadError: ArgumentError: Package A does not have B in its dependencies:
- If you have A checked out for development and have
  added B as a dependency but haven't updated your primary
  environment's manifest file, try `Pkg.resolve()`.
- Otherwise you may need to report an issue with A

…and I am stumped. B is not a package, it’s just a file defining a module. What am I doing wrong?

Check your current work directory by inserting “println(pwd())” before the include statements. It is possible that the current work directory is not the same path these files are stored at. Current work directory really depends on where you started the Julia process and whether you have switched directory after that.

If you want to make sure Julia looks for B.jl etc. at the same path as the file A.jl, you can try this:

module A
   include(joinpath(@__DIR__, "B.jl"))
   include(joinpath(@__DIR__, "C.jl"))
   include(joinpath(@__DIR__, "C.jl"))
end

@__DIR__ will expand to the path where the current file is.

@__DIR__ works well for me except in one situation: if you want to build an app using PackageCompiler and distribute that to other machines, be careful that @__DIR__ will expand to an absolute path in your development machine during compilation, which may not match the path on the target machine.

This means that (most likely) somewhere in the module A there is a using B. using B essentially mean “load the external package B”, but what you want here is probably “load the local module B” , right? To achieve that you need to use using .B instead (note the dot) which looks for the B module in the current scope (e.g. the A module).

What Zhong_Pan said is not relevant; include("B.jl") always means include(joinpath(@__DIR__, "B.jl")).

5 Likes