自己的包引用自己的另一个包报错

我写了一个包,PadInterp。它在终端中是可以运行的。
image

我希望在另一个包PolarCoordinates中调用它。

# 添加本电脑库路径,有尝试过移动到module下面,但是一样报错。
computername = ENV["COMPUTERNAME"]
if computername == "家里电脑"
    push!(LOAD_PATH, "E:/Documents/JuliaProgram/MyModules/")
end



module PolarCoordinates

using PadInterp, ...

export ...

...

end

运行结果是这样的:


其中:
Warning: Package PolarCoordinates does not have PadInterp in its dependencies
这句话我无论如何都不能理解:为什么我终端可以,但是这里不行?

1 个赞

你大概是需要使用 develop 功能:3. Managing Packages · Pkg.jl

pkg> activate path/to/PolarCoordinates
pkg> dev E:/Documents/JuliaProgram/MyModules/XXX
1 个赞

谢谢谢谢。
按你说的这么做了之后,突然发现,Project.toml里面多了点关于PadInterp的内容。我对Julia包的理解又进一步了。

你的每一个项目的全部依赖都写在 Project.toml 文件里

通过 dev 的话会在项目的 Manifest.toml 文件里面记录对应包是本地文件,你可以浏览一下 Manifest.toml 文件看看。

你好,我又来了。刚刚闹了个乌龙。原来是终端里future warnings for PolarCoordinates are suppressed,所以再次using的时候我以为好了的。

实际上,结果还是不行。

可是明明Manifest.toml里有了dependencies。

push!(LOAD_PATH, "E:/Documents/JuliaProgram/MyModules/") 去掉试试。一般很少会需要自己手动修改 LOAD_PATH

大佬好,我确实去掉了。毕竟Manifest.toml里面地址已经变成相对路径了:

[[deps.PadInterp]]
path = "../PadInterp"
uuid = "552853ef-3ac4-4c13-891a-605237077706"
version = "0.1.0"

这里相对路径和你视频里有点不同。你视频里面用dev ../Distances/XX.jl,要指定.jl文件。但是我测试下来,会报错说文件不存在(而且双击Tab,根本不会显示.toml文件和.jl文件作为候选项),我觉得它只认识文件夹,所以将XX.jl认为成了文件夹名?


这时我只dev到另一个库文件夹就不报错了,而且能正常引用了(有条件)。版本Julia 1.7.1。


但是目前还是有问题。目前我要运行,只能在库文件夹下面,activate .,然后才能using
image

但是到别的目录是失败的。

我不知道是我哪里错了?

附上我的目录结构。
image

很难判断你那边究竟做了哪些操作,我这里从零开始举一个例子吧。


我这里先设定一下环境变量 JULIA_DEPOT_PATH=~/Downloads/tmp 来告诉 Julia 使用一个新的部署环境。

可以看到这是一个非常干净的环境。

julia> LOAD_PATH
3-element Vector{String}:
 "@" # 当前项目所在目录
 "@v#.#" # 当前版本的根项目: $(JULIA_DEPOT_PATH)/environments/v1.7/Project.toml
 "@stdlib" # 标准库

然后随便找一个目录创建两个新的包:

(@v1.7) pkg> generate MyPkgA
  Generating  project MyPkgA:
    MyPkgA/Project.toml
    MyPkgA/src/MyPkgA.jl

(@v1.7) pkg> generate MyPkgB
  Generating  project MyPkgB:
    MyPkgB/Project.toml
    MyPkgB/src/MyPkgB.jl

shell> pwd
/Users/jc/Downloads/pkgtest

假设说我们想要让 MyPkgA 项目里能够正常使用 MyPkgB 的话:

(@v1.7) pkg> activate MyPkgA
  Activating project at `~/Downloads/pkgtest/MyPkgA`

(MyPkgA) pkg> st
     Project MyPkgA v0.1.0
      Status `~/Downloads/pkgtest/MyPkgA/Project.toml` (empty project)

julia> using MyPkgA
[ Info: Precompiling MyPkgA [d9bfe67c-2d5f-4848-978e-d22535e455c7]

julia> using MyPkgB
ERROR: ArgumentError: Package MyPkgB not found in current path:
- Run `import Pkg; Pkg.add("MyPkgB")` to install the MyPkgB package.

Stacktrace:
 [1] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:967

using MyPkgB 的时候,Julia 会按顺序分别在 LOAD_PATH 里寻找符合条件的 MyPkgB

  • @: 项目目录,即 MyPkgA/Project.toml。因为现在是空的所以没有。
  • @v#.#: 版本根目录,即 ~/Downloads/tmp/environments/v1.7/Project.toml。因为我重新设定了 JULIA_DEPOT_PATH 所以这也是空的。
  • @stdlib:标准库就更不可能有了

所以 using 失败了。


先说一个 “错误” 操作,就是在 @v#.# 里记录 MyPkgB 的信息:

(@v1.7) pkg> dev /Users/jc/Downloads/pkgtest/MyPkgB
   Resolving package versions...
    Updating `~/Downloads/tmp/environments/v1.7/Project.toml`
  [ab7b05f2] + MyPkgB v0.1.0 `~/Downloads/pkgtest/MyPkgB`
    Updating `~/Downloads/tmp/environments/v1.7/Manifest.toml`
  [ab7b05f2] + MyPkgB v0.1.0 `~/Downloads/pkgtest/MyPkgB`

这样一来无论是在哪个项目(MyPkgA 项目又或者是版本根项目)里,都可以正常使用 MyPkgB:

(@v1.7) pkg> activate MyPkgA
  Activating project at `~/Downloads/pkgtest/MyPkgA`

julia> using MyPkgB # 正常 using

但是需要注意的是 MyPkgA/Project.toml 里其实并没有记录 MyPkgB,你能够正常导入仅仅是因为 Julia 在 @v#.# 里面找到了。因此如果重启 Julia 并且试图让 MyPkgA 去使用 MyPkgB 的话,就会有警告发生:

# MyPkgA/src/MyPkgA.jl
module MyPkgA

using MyPkgB

greet() = MyPkgB.greet()

end # module
julia> using MyPkgA
[ Info: Precompiling MyPkgA [d9bfe67c-2d5f-4848-978e-d22535e455c7]
┌ Warning: Package MyPkgA does not have MyPkgB in its dependencies:
│ - If you have MyPkgA checked out for development and have
│   added MyPkgB 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 MyPkgA
└ Loading MyPkgB into MyPkgA from project dependency, future warnings for MyPkgA are suppressed.

这里警告的意思就是说 MyPkgB 并没有记录在 MyPkgA/Project.toml 里面 (primary environment’s manifest file)。但是因为 Julia 的 LOAD_PATH 里其他的路径 (@v#.#) 记录了所以倒也能够正常使用。

假如说我们把 MyPkgB 从版本根环境移除的话:

(@v1.7) pkg> st
      Status `~/Downloads/tmp/environments/v1.7/Project.toml` (empty project)

然后重开一个 Julia,就会直接报错而不是警告了,因为确实没找到:

(@v1.7) pkg> activate MyPkgA
  Activating project at `~/Downloads/pkgtest/MyPkgA`

julia> using MyPkgA
[ Info: Precompiling MyPkgA [d9bfe67c-2d5f-4848-978e-d22535e455c7]
ERROR: LoadError: ArgumentError: Package MyPkgA does not have MyPkgB in its dependencies:
- If you have MyPkgA checked out for development and have
  added MyPkgB 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 MyPkgA
Stacktrace:

结论?你需要在哪一个项目里使用你开发的 MyPkgB,那就需要在对应的项目 Project.toml (实际上是 Manifest.toml 了) 里面记录对应的 MyPkgB 信息。之所以出现警告大概是因为你之前在版本根项目 (@v#.#) 里面已经记录了 MyPkgB 的原因。

5 个赞

谢谢详细讲解,今天按您讲的步骤练了练,然后莫名其妙好了 :roll_eyes: