From f5a38dc36b50406b643394907a88dab2794641ad Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sat, 23 Jan 2016 11:08:38 -0500 Subject: [PATCH] Document requirement of __precompile__ Fixes JuliaLang/julia#13200 (cherry picked from commit 59ca4424e098ae19103c2cf30638ca42866804ad) ref #14773 --- base/docs/helpdb.jl | 9 --------- base/loading.jl | 16 ++++++++++++++++ doc/manual/modules.rst | 4 ++++ doc/stdlib/base.rst | 2 ++ doc/stdlib/io-network.rst | 2 +- src/dump.c | 6 +++++- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/base/docs/helpdb.jl b/base/docs/helpdb.jl index 51afeea7c425e..4ed953a0f0345 100644 --- a/base/docs/helpdb.jl +++ b/base/docs/helpdb.jl @@ -10606,15 +10606,6 @@ This is only needed if your module depends on a file that is not used via `inclu """ include_dependency -doc""" - __precompile__(isprecompilable::Bool=true) - -Specify whether the file calling this function is precompilable. If `isprecompilable` is `true`, then `__precompile__` throws an exception when the file is loaded by `using`/`import`/`require` *unless* the file is being precompiled, and in a module file it causes the module to be automatically precompiled when it is imported. Typically, `__precompile__()` should occur before the `module` declaration in the file, or better yet `VERSION >= v"0.4" && __precompile__()` in order to be backward-compatible with Julia 0.3. - -If a module or file is *not* safely precompilable, it should call `__precompile__(false)` in order to throw an error if Julia attempts to precompile it. -""" -__precompile__ - doc""" randn!([rng], A::Array{Float64,N}) diff --git a/base/loading.jl b/base/loading.jl index 1fea7f1ea6cff..1dfe06c44da3a 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -155,6 +155,22 @@ precompilableerror(ex, c) = false # Call __precompile__ at the top of a file to force it to be precompiled (true), or # to be prevent it from being precompiled (false). __precompile__(true) is # ignored except within "require" call. +""" + __precompile__(isprecompilable::Bool=true) + +Specify whether the file calling this function is precompilable. If `isprecompilable` is +`true`, then `__precompile__` throws an exception when the file is loaded by +`using`/`import`/`require` *unless* the file is being precompiled, and in a module file it +causes the module to be automatically precompiled when it is imported. Typically, +`__precompile__()` should occur before the `module` declaration in the file, or better yet +`VERSION >= v"0.4" && __precompile__()` in order to be backward-compatible with Julia 0.3. + +If a module or file is *not* safely precompilable, it should call `__precompile__(false)` in +order to throw an error if Julia attempts to precompile it. + +`__precompile__()` should *not* be used in a module unless all of its dependencies are also +using `__precompile__()`. Failure to do so can result in a runtime error when loading the module. +""" function __precompile__(isprecompilable::Bool=true) if myid() == 1 && isprecompilable != (0 != ccall(:jl_generating_output, Cint, ())) && !(isprecompilable && toplevel_load::Bool) diff --git a/doc/manual/modules.rst b/doc/manual/modules.rst index 6b988f50d80ad..4800f89a882e6 100644 --- a/doc/manual/modules.rst +++ b/doc/manual/modules.rst @@ -282,6 +282,10 @@ therein. If you know that it is *not* safe to precompile your module throw an error (and thereby prevent the module from being imported by any other precompiled module). +``__precompile__()`` should *not* be used in a module unless all of its +dependencies are also using ``__precompile__()``. Failure to do so can result +in a runtime error when loading the module. + In order to make your module work with precompilation, however, you may need to change your module to explicitly separate any initialization steps that must occur at *runtime* from steps that can diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index 2ee5940f72443..60f734871edf3 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -142,6 +142,8 @@ Getting Around If a module or file is *not* safely precompilable, it should call ``__precompile__(false)`` in order to throw an error if Julia attempts to precompile it. + ``__precompile__()`` should *not* be used in a module unless all of its dependencies are also using ``__precompile__()``\ . Failure to do so can result in a runtime error when loading the module. + .. function:: include(path::AbstractString) .. Docstring generated from Julia source diff --git a/doc/stdlib/io-network.rst b/doc/stdlib/io-network.rst index 4ce2cbe0ecd49..72929cc59087a 100644 --- a/doc/stdlib/io-network.rst +++ b/doc/stdlib/io-network.rst @@ -153,7 +153,7 @@ General I/O .. Docstring generated from Julia source - Read binary data from a stream, filling in the argument ``array``\ . + Read binary data from a stream or file, filling in the argument ``array``\ . .. function:: readbytes!(stream, b::Vector{UInt8}, nb=length(b); all=true) diff --git a/src/dump.c b/src/dump.c index 4a783780084db..e888f980aec09 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1632,7 +1632,11 @@ int jl_deserialize_verify_mod_list(ios_t *s) jl_errorf("invalid module path (%s does not name a module)", name); } if (m->uuid != uuid) { - jl_printf(JL_STDERR, "WARNING: Module %s uuid did not match cache file\n", name); + jl_printf(JL_STDERR, + "WARNING: Module %s uuid did not match cache file\n" + " This is likely because module %s does not support" + " precompilation but is imported by a module that does.\n", + name, name); return 0; } }