Local package precompilation fails for Julia 1.9.0

Upon upgrading to Julia 1.9.0, I can’t seem to create and load any locally developed package that includes a “using” or “import” statement. If I exclude using/import, it works fine. For example, I tried running through the tutorial at (5. Creating Packages · Pkg.jl) and it works only up until the point where “import JSON” is added to the source file. This happens on Mac and Ubuntu Linux, and irrespective of which particular package I’m importing.

After having gone through the steps in the tutorial, i.e. doing all of the following in the Pkg repl:

generate HelloWorld
activate ./HelloWorld
add Random JSON

… then exiting and modifying the src/HelloWorld.jl to import Random and JSON, everything works up until this point. But then:

julia> using HelloWorld
[ Info: Precompiling HelloWorld [01aee845-0708-42b8-bd19-d504c9382661]
ERROR: LoadError: ArgumentError: Package JSON [682c06a0-de6a-54ab-a142-c8b1cf79cde6] is required but does not seem to be installed:
 - Run `Pkg.instantiate()` to install all recorded dependencies.

Stacktrace:
 [1] _require(pkg::Base.PkgId, env::String)
   @ Base ./loading.jl:1739
 [2] _require_prelocked(uuidkey::Base.PkgId, env::String)
   @ Base ./loading.jl:1625
 [3] macro expansion
   @ ./loading.jl:1613 [inlined]
 [4] macro expansion
   @ ./lock.jl:267 [inlined]
 [5] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:1576
 [6] include
   @ ./Base.jl:457 [inlined]
 [7] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
   @ Base ./loading.jl:2010
 [8] top-level scope
   @ stdin:2
in expression starting at /Users/myersm/packages/julia/HelloWorld/src/HelloWorld.jl:1
in expression starting at stdin:2
ERROR: Failed to precompile HelloWorld [01aee845-0708-42b8-bd19-d504c9382661] to "/Users/myersm/.julia/compiled/v1.9/HelloWorld/jl_X8JZ67".
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
   @ Base ./loading.jl:2260
 [3] compilecache
   @ ./loading.jl:2127 [inlined]
 [4] _require(pkg::Base.PkgId, env::String)
   @ Base ./loading.jl:1770
 [5] _require_prelocked(uuidkey::Base.PkgId, env::String)
   @ Base ./loading.jl:1625
 [6] macro expansion
   @ ./loading.jl:1613 [inlined]
 [7] macro expansion
   @ ./lock.jl:267 [inlined]
 [8] require(into::Module, mod::Symbol)
   @ Base ./loading.jl:1576

I cannot replicate your problem. But what happens if you do:

using Pkg
Pkg.instantiate()

as suggested by the error message?

Perhaps important to note:
You need to start Julia in the folder HelloWorld with the command:

julia --project

An information that seams to be missing in the tutorial…

Thank you. The Pkg.instantiate() didn’t help, but moving into the HelloWorld directory and doing julia --project did.

Although that solved the toy HelloWorld problem I described, it brings to light a workflow question regarding locally developed packages. My usual workflow is to have a line in my .julia/config/startup.jl file, pushfirst!(LOAD_PATH, my_packages_dir), where my_packages_dir is a location where I have a number of small packages that I’ve developed myself but haven’t put on github anywhere, either because they’re works in progress or because they’re very specific to my own use-cases, not generally useful to others. This worked fine in Julia 1.8.3 that I was using before. But now is there an alternative, better way that I should go about this now in 1.9, or do I need to adjust my routine and start having my packages on github?

For example, suppose I want to use not just HelloWorld but also MyPkg1 and MyPkg2 at the same time, all of them locally developed. Using the julia --project approach, I would only be able to load one of these packages at a time, right?

The canonical way to do this is to place these packages in ~/.julia/dev and then Pkg.develop them into your environment. You can also give a full path to Pkg.develop to add a package into your environment.

One option that you may consider is to set JULIA_PKG_DEVDIR to my_packages_dir.

See 12. API Reference · Pkg.jl .

(@v1.9) pkg> ?dev
  [dev|develop] [--preserve=<opt>] [--shared|--local] pkg[=uuid] ...
  [dev|develop] [--preserve=<opt>] path

  Make a package available for development. If pkg is an existing local path, that path will be recorded in the manifest and used. Otherwise, a full git clone of pkg is made. The location of the clone
  is controlled by the --shared (default) and --local arguments. The --shared location defaults to ~/.julia/dev, but can be controlled with the JULIA_PKG_DEVDIR environment variable.

  When --local is given, the clone is placed in a dev folder in the current project. This is not supported for paths, only registered packages.

  This operation is undone by free.

  The preserve strategies offered by add are also available via the preserve argument. See add for more information.

  Examples

  pkg> develop Example
  pkg> develop https://github.com/JuliaLang/Example.jl
  pkg> develop ~/mypackages/Example
  pkg> develop --local Example

You can also use this from the Pkg REPL.

julia> using Pkg

help?> Pkg.develop
  Pkg.develop(pkg::Union{String, Vector{String}}; io::IO=stderr, preserve=PRESERVE_TIERED, installed=false)
  Pkg.develop(pkgs::Union{PackageSpec, Vector{PackageSpec}}; io::IO=stderr, preserve=PRESERVE_TIERED, installed=false)

  Make a package available for development by tracking it by path. If pkg is given with only a name or by a URL, the package will be downloaded to the location specified by the environment variable
  JULIA_PKG_DEVDIR, with joinpath(DEPOT_PATH[1],"dev") being the default.

  If pkg is given as a local path, the package at that path will be tracked.

  The preserve strategies offered by Pkg.add are also available via the preserve kwarg. See Pkg.add for more information.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  # By name
  Pkg.develop("Example")
  
  # By url
  Pkg.develop(url="https://github.com/JuliaLang/Compat.jl")
  
  # By path
  Pkg.develop(path="MyJuliaPackages/Package.jl")

  See also PackageSpec, Pkg.add.
1 Like

Thank you, mkitti. I’m able to get this to work now, but only if I put the locally developed package at .julia/dev as you suggested; otherwise, the JULIA_PKG_DEVDIR and Pkg.dev(path = …) options both produce the same Package X is required but does not seem to be installed error.