Julia模块预编译报错:Base.compilecache提示‘not found in path’
这个问题我之前也碰到过,核心原因是你对Base.compilecache的查找逻辑理解有点偏差,咱们一步步拆解解决:
首先得搞懂报错的根源:
你执行Base.compilecache("M")时,Julia会去LOAD_PATH环境变量配置的路径里查找名为M的模块,但你只是通过include("M.jl")把模块加载到当前REPL会话中,并没有把你的项目目录加入LOAD_PATH,所以Julia找不到对应的模块文件,自然报路径错误。
接下来给几种可行的解决办法:
方法一:直接用模块对象调用compilecache(最简单)
既然你已经通过include("M.jl")把模块加载到当前会话了,直接把模块对象传给Base.compilecache就行,不用传字符串:
include("M.jl") Base.compilecache(M) # 注意这里是M(模块对象),不是"M"(字符串)
这样Julia就能直接针对已加载的模块生成缓存文件,不用再去路径里找了。
方法二:把项目目录加入LOAD_PATH,用using触发预编译
如果想让Julia能全局找到你的模块,先把当前项目目录加入LOAD_PATH:
# 在项目文件夹启动REPL后执行 push!(LOAD_PATH, pwd()) # pwd()就是当前项目的路径 using M # 这一步会自动触发预编译,生成缓存文件
之后再调用Base.compilecache("M")也不会报错了,因为Julia已经能在LOAD_PATH里找到M模块。
额外补充:关于__precompile__()的小细节
你之前在模块前加__precompile__()其实等价于__precompile__(true),Julia 1.7及以后版本默认是开启预编译的,但如果你的模块里有一些无法预编译的代码(比如动态生成的代码、依赖运行时环境的逻辑),Julia会自动跳过预编译。如果想强制开启,可以明确写__precompile__(true);如果要排查预编译是否被跳过,可以在加载模块时加--trace-compile=compile_log.jl参数启动REPL,查看日志里的提示。
内容的提问来源于stack exchange,提问作者xji

