Julia: __precompile__(false) does not work

Created on 1 Aug 2018  路  10Comments  路  Source: JuliaLang/julia

julia> mkpath("/tmp/pkgs/NPC/src")
"/tmp/pkgs/NPC/src"

julia> open("/tmp/pkgs/NPC/src/NPC.jl", "w") do io
           println(io, """
           __precompile__(false)
           module NPC

           foo() = 1

           end
           """)
       end

julia> push!(LOAD_PATH, "/tmp/pkgs")
4-element Array{String,1}:
 "@"        
 "@v#.#"    
 "@stdlib"  
 "/tmp/pkgs"

julia> using NPC
[ Info: Precompiling module NPC
ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled.
Stacktrace:
 [1] __precompile__(::Bool) at ./loading.jl:780
 [2] top-level scope at none:0
 [3] include at ./boot.jl:317 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1034
 [5] include(::Module, ::String) at ./sysimg.jl:29
 [6] top-level scope at none:0
 [7] eval at ./boot.jl:319 [inlined]
 [8] eval(::Expr) at ./client.jl:399
 [9] top-level scope at ./none:3
in expression starting at /tmp/pkgs/NPC/src/NPC.jl:1
ERROR: Failed to precompile NPC to /home/tim/.julia/compiled/v0.7/NPC.ji.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] macro expansion at ./logging.jl:310 [inlined]
 [3] compilecache(::Base.PkgId) at ./loading.jl:1173
 [4] _require(::Base.PkgId) at ./logging.jl:311
 [5] require(::Base.PkgId) at ./loading.jl:852
 [6] macro expansion at ./logging.jl:311 [inlined]
 [7] require(::Module, ::Symbol) at ./loading.jl:834

I'm on a branch that includes #28366.

Most helpful comment

While this remains unfixed, is there another way to disable precompilation of a package? I'm developing a package with a dependency that doesn't precompile (VideoIO) and have to go through the attempted precompillation repeatedly

All 10 comments

What if you rm -rf ~/.julia/compiled? I seem to remember that if there is an old precompile file there for the name of the package it will just precompile anyway.

Nope, same problem.

Turns out our tests checked whether __precompile__(false) properly generated an error if the file was being used by something that was __precompile__(true), but AFAICT we had no tests of __precompile__(false) on its own :cry: :

diff --git a/test/precompile.jl b/test/precompile.jl
index f834e029a2..6c47416a75 100644
--- a/test/precompile.jl
+++ b/test/precompile.jl
@@ -281,6 +281,7 @@ try
           """
           __precompile__(false)
           module Baz
+          baz() = 1
           end
           """)

@@ -291,6 +292,8 @@ try
         isa(exc, ErrorException) || rethrow(exc)
         occursin("__precompile__(false)", exc.msg) && rethrow(exc)
     end
+    @eval using Baz
+    @test Baz.baz() == 1

     # Issue #12720
     FooBar1_file = joinpath(dir, "FooBar1.jl")

leads to a test failure. Work around coming.

I still see this issue in 1.0.2 and 1.1.0-DEV.655
For me, the below module produces the repeated precompilation with every new session

__precompile__(false)

module DevPackage
greet() = "Hello world!"
end

Also, rm -rf ~/.julia/compiled dosen't fix the issue for me

Same problem for me with a newly created package and Julia 1.0.2 on Ubuntu.

I can also confirm this bug on 1.0.2. Disabling precompilation is not possible __precompile__(false) is ignored. Reopen?

@vtjnash, this seems unfixed for many people...

While this remains unfixed, is there another way to disable precompilation of a package? I'm developing a package with a dependency that doesn't precompile (VideoIO) and have to go through the attempted precompillation repeatedly

Browsing the code, I think the issue is that the call to jl_generating_output here returns 0, because in my IJulia at least all four of the options or'd are 0 (you can get the options struct with Base.JLOptions()). Doing some Googling, I think these correspond to compiler switches? Presumably one of them was true in the past?

e: Realised I could test this theory by sticking throw(Base.PrecompilableError()) at the top of my file. No such luck - I get further than with __precompile__(false) alone, but run into the same ERROR: LoadError: Declaring __precompile__(false) is not allowed in files that are being precompiled. that @timholy got back in August.

c.f. https://github.com/JuliaLang/julia/pull/30064

we could also perhaps early-parse the file to look for an obvious __precompile__(false) statement at the top if we don't already have a cache file (passing that parse result to eval a bit later in the function if the precompile fails)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sbromberger picture sbromberger  路  3Comments

ararslan picture ararslan  路  3Comments

i-apellaniz picture i-apellaniz  路  3Comments

wilburtownsend picture wilburtownsend  路  3Comments

TotalVerb picture TotalVerb  路  3Comments