<p dir="auto">I am getting an "access to undefined reference" in code that used to work, and that I believe is valid.  It takes a very specific combination of details to trigger the problem, so I think it is related to optimization.</p>
<p dir="auto">As far as I can tell from Travis (assuming they update 0.3 regularly) this behaviour started in the last day or two.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="andrew@laptop:~/project/CRC&gt; julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type &quot;help()&quot; to list help topics
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.3.0-prerelease+2697 (2014-04-22 02:46 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit 9dc5e3f* (0 days old master)
|__/                   |  x86_64-suse-linux

julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           make_tables(tables{Uint8}())
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc()
ERROR: access to undefined reference
 in crc at none:2"><pre class="notranslate"><code class="notranslate">andrew@laptop:~/project/CRC&gt; julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
   _ _   _| |_  __ _   |  Type "help()" to list help topics
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.3.0-prerelease+2697 (2014-04-22 02:46 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit 9dc5e3f* (0 days old master)
|__/                   |  x86_64-suse-linux

julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           make_tables(tables{Uint8}())
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc()
ERROR: access to undefined reference
 in crc at none:2
</code></pre></div>
<p dir="auto">I believe this is valid code - undefined members of a type seem to be supported in general, as long as they are created before reading.</p>
<p dir="auto">Note that much of the "mess" above is necessary in order to trigger this. Below I'll add some minimally modified versions that work to illustrate this:</p>
<p dir="auto">The type parameterization is needed:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; type Single
           table::Vector{Uint8}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           make_tables(tables())
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc()
0x00"><pre class="notranslate"><code class="notranslate">julia&gt; type Single
           table::Vector{Uint8}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           make_tables(tables())
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc()
0x00
</code></pre></div>
<p dir="auto">The default argument is needed:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables)
           make_tables(tables{Uint8}())
       end
crc (generic function with 1 method)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc(Single)
0x00"><pre class="notranslate"><code class="notranslate">julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables)
           make_tables(tables{Uint8}())
       end
crc (generic function with 1 method)

julia&gt; 

julia&gt; function make_tables(tables::Single)
           tables.table = Array(Uint8, 256)
           tables.table[1] = 0x0
       end
make_tables (generic function with 1 method)

julia&gt; 

julia&gt; crc(Single)
0x00
</code></pre></div>
<p dir="auto">The separate routine to set the value is needed:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           t = tables{Uint8}()
           t.table = Array(Uint8, 256)
           t.table[1] = 0x0
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; crc()
0x00"><pre class="notranslate"><code class="notranslate">julia&gt; type Single{A}
           table::Vector{A}
           Single() = new()
       end

julia&gt; 

julia&gt; function crc(tables=Single)
           t = tables{Uint8}()
           t.table = Array(Uint8, 256)
           t.table[1] = 0x0
       end
crc (generic function with 2 methods)

julia&gt; 

julia&gt; crc()
0x00
</code></pre></div>
<p dir="auto">Finally, the example to cut+paste:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="type Single{A}
    table::Vector{A}
    Single() = new()
end

function crc(tables=Single)
    make_tables(tables{Uint8}())
end

function make_tables(tables::Single)
    tables.table = Array(Uint8, 256)
    tables.table[1] = 0x0
end

crc()"><pre class="notranslate"><code class="notranslate">type Single{A}
    table::Vector{A}
    Single() = new()
end

function crc(tables=Single)
    make_tables(tables{Uint8}())
end

function make_tables(tables::Single)
    tables.table = Array(Uint8, 256)
    tables.table[1] = 0x0
end

crc()
</code></pre></div>
<p dir="auto">I'm moving the discussion from <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="346340046" data-permission-text="Title is private" data-url="https://github.com/JuliaPy/pyjulia/issues/173" data-hovercard-type="issue" data-hovercard-url="/JuliaPy/pyjulia/issues/173/hovercard" href="https://github.com/JuliaPy/pyjulia/issues/173">JuliaPy/pyjulia#173</a> to gather more attention.  I also describe in the last paragraphs how it may help not only PyJulia users but also other Julia users.</p>
<p dir="auto">(<a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/stevengj/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/stevengj">@stevengj</a>, <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/Keno/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/Keno">@Keno</a>, please correct me or add more details if I'm missing something)</p>
<p dir="auto">Prior to Julia 0.7, PyJulia users could use multiple Python interpreters without rebuilding PyCall.jl (PyJulia depends heavily on PyCall.jl) against each Python interpreters.  Considering it's a common practice to have multiple Python virtual environments (with venv/virtualenv/conda), being able to use PyJulia without recompiling PyCall.jl every time is an important feature.  However, supporting this feature in Julia ≥ 0.7 seems hard.</p>
<p dir="auto">(Some details: Just to be clear, not all PyJulia users will notice this effect.  Notably, Windows or macOS users only using Python 3 (or only using Python 2...) are unaffected.  Linux users only using dynamically linked Python 3 (or 2) are also fine.  However, Linux users using statically linked Python, such as the ones distributed by Ubuntu and Anaconda, will not be able to use PyJulia.  I think those platforms are popular enough to pay a special attention.)</p>
<p dir="auto">PyJulia relies on <code class="notranslate">Base.LOAD_CACHE_PATH</code> in Julia 0.6 to separate the cache of PyCall.jl.  It inserts a private path to <code class="notranslate">Base.LOAD_CACHE_PATH[1]</code> if the Python interpreter in which PyJulia is loaded is incompatible with the Python interpreter with which PyCall.jl is configured:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="# Add a private cache directory. PyCall needs a different
# configuration and so do any packages that depend on it.
self._call(u&quot;unshift!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot(),&quot; +
    &quot;\&quot;lib\&quot;, \&quot;pyjulia%s-v$(VERSION.major).$(VERSION.minor)\&quot;))&quot; % sys.version_info[0])"><pre class="notranslate"><span class="pl-c"># Add a private cache directory. PyCall needs a different</span>
<span class="pl-c"># configuration and so do any packages that depend on it.</span>
<span class="pl-s1">self</span>.<span class="pl-en">_call</span>(<span class="pl-s">u"unshift!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot(),"</span> <span class="pl-c1">+</span>
    <span class="pl-s">"<span class="pl-cce">\"</span>lib<span class="pl-cce">\"</span>, <span class="pl-cce">\"</span>pyjulia%s-v$(VERSION.major).$(VERSION.minor)<span class="pl-cce">\"</span>))"</span> <span class="pl-c1">%</span> <span class="pl-s1">sys</span>.<span class="pl-s1">version_info</span>[<span class="pl-c1">0</span>])</pre></div>
<p dir="auto">--- <a href="https://github.com/JuliaPy/pyjulia/blob/18d98e5b1b616a4d663273cc36cdd835ab0b33da/julia/core.py#L357-L360">https://github.com/JuliaPy/pyjulia/blob/18d98e5b1b616a4d663273cc36cdd835ab0b33da/julia/core.py#L357-L360</a></p>
<p dir="auto">This "hack" doesn't work in Julia ≥ 0.7 as <code class="notranslate">Base.LOAD_CACHE_PATH</code> is gone now.  Also, reading how <code class="notranslate">cache_file_entry</code> is used to locate the <code class="notranslate">.ji</code> files, I couldn't find a way to implement a new "hack" other than duplicating the whole <code class="notranslate">DEPOT_PATH[1]</code>.</p>
<p dir="auto"></p><div class="Box Box--condensed my-2">
  <div class="Box-header f6">
    <p class="mb-0 text-bold">
      <a href="https://github.com/JuliaLang/julia/blob/d038f2f4997e4a4544c790d05a7f54d316200bd6/base/loading.jl#L594-L608">julia/base/loading.jl</a>
    </p>
    <p class="mb-0 color-fg-muted">
        Lines 594 to 608
      in
      <a data-pjax="true" class="commit-tease-sha" href="/JuliaLang/julia/commit/d038f2f4997e4a4544c790d05a7f54d316200bd6">d038f2f</a>
    </p>
  </div>
  <div itemprop="text" class="Box-body p-0 blob-wrapper blob-wrapper-embedded data">
    <table class="highlight tab-size mb-0 js-file-line-container" data-tab-size="8" data-paste-markdown-skip="">

        <tbody><tr class="border-0">
          <td id="L594" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="594"></td>
          <td id="LC594" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-en">cache_file_entry</span>(pkg<span class="pl-k">::</span><span class="pl-c1">PkgId</span>) <span class="pl-k">=</span> <span class="pl-c1">joinpath</span>( </td>
        </tr>

        <tr class="border-0">
          <td id="L595" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="595"></td>
          <td id="LC595" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     <span class="pl-s"><span class="pl-pds">"</span>compiled<span class="pl-pds">"</span></span>, </td>
        </tr>

        <tr class="border-0">
          <td id="L596" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="596"></td>
          <td id="LC596" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     <span class="pl-s"><span class="pl-pds">"</span>v<span class="pl-v">$(<span class="pl-c1">VERSION</span><span class="pl-k">.</span>major)</span>.<span class="pl-v">$(<span class="pl-c1">VERSION</span><span class="pl-k">.</span>minor)</span><span class="pl-pds">"</span></span>, </td>
        </tr>

        <tr class="border-0">
          <td id="L597" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="597"></td>
          <td id="LC597" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     pkg<span class="pl-k">.</span>uuid <span class="pl-k">===</span> <span class="pl-c1">nothing</span> <span class="pl-k">?</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-v">$(pkg<span class="pl-k">.</span>name)</span>.ji<span class="pl-pds">"</span></span> <span class="pl-k">:</span> <span class="pl-c1">joinpath</span>(pkg<span class="pl-k">.</span>name, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-v">$(<span class="pl-c1">package_slug</span>(pkg<span class="pl-k">.</span>uuid))</span>.ji<span class="pl-pds">"</span></span>) </td>
        </tr>

        <tr class="border-0">
          <td id="L598" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="598"></td>
          <td id="LC598" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> ) </td>
        </tr>

        <tr class="border-0">
          <td id="L599" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="599"></td>
          <td id="LC599" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">  </td>
        </tr>

        <tr class="border-0">
          <td id="L600" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="600"></td>
          <td id="LC600" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-k">function</span> <span class="pl-en">find_all_in_cache_path</span>(pkg<span class="pl-k">::</span><span class="pl-c1">PkgId</span>) </td>
        </tr>

        <tr class="border-0">
          <td id="L601" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="601"></td>
          <td id="LC601" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     paths <span class="pl-k">=</span> String[] </td>
        </tr>

        <tr class="border-0">
          <td id="L602" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="602"></td>
          <td id="LC602" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     entry <span class="pl-k">=</span> <span class="pl-c1">cache_file_entry</span>(pkg) </td>
        </tr>

        <tr class="border-0">
          <td id="L603" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="603"></td>
          <td id="LC603" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     <span class="pl-k">for</span> depot <span class="pl-k">in</span> <span class="pl-c1">DEPOT_PATH</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L604" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="604"></td>
          <td id="LC604" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">         path <span class="pl-k">=</span> <span class="pl-c1">joinpath</span>(depot, entry) </td>
        </tr>

        <tr class="border-0">
          <td id="L605" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="605"></td>
          <td id="LC605" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">         <span class="pl-c1">isfile_casesensitive</span>(path) <span class="pl-k">&amp;&amp;</span> <span class="pl-c1">push!</span>(paths, path) </td>
        </tr>

        <tr class="border-0">
          <td id="L606" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="606"></td>
          <td id="LC606" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     <span class="pl-k">end</span> </td>
        </tr>

        <tr class="border-0">
          <td id="L607" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="607"></td>
          <td id="LC607" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line">     <span class="pl-k">return</span> paths </td>
        </tr>

        <tr class="border-0">
          <td id="L608" class="blob-num border-0 px-3 py-0 color-bg-default" data-line-number="608"></td>
          <td id="LC608" class="blob-code border-0 px-3 py-0 color-bg-default blob-code-inner js-file-line"> <span class="pl-k">end</span> </td>
        </tr>
    </tbody></table>
  </div>
</div>
<p></p>
<p dir="auto">But creating a new <code class="notranslate">DEPOT_PATH[1]</code> for each incompatible Python interpreter type is rather overkill and ignores Pkg3 working hard to de-duplicate resources.  It would be really nice to have a direct support from Julia and Pkg3, if it is feasible.</p>
<h3 dir="auto">An idea: "build option" support</h3>
<p dir="auto">I think one way to directly support it is to add "build option" support in Julia and Pkg3.  What I mean by "build option" is something that altering it changes the precompilation cache.  Currently Julia packages do this via environment variables.  Concrete examples are <code class="notranslate">PYTHON</code> of PyCall.jl and <code class="notranslate">CONDA_JL_HOME</code> of Conda.jl.  If those options can be directly configured by <code class="notranslate">Project.toml</code> file, and if compilation cache paths depend on such options, PyJulia can just create a new <code class="notranslate">Project.toml</code> with appropriate options and launch a new Julia interpreter.  Importantly, the compilation cache path of a package has to depend also on the build options of all its (direct and indirect) dependencies.</p>
<p dir="auto">I think the "build option" support can help other Julia users (who do not use PyJulia) too.  For example, you can change <code class="notranslate">CONDA_JL_HOME</code> for a particular <code class="notranslate">Project.toml</code> to tweak versions of external libraries provided via <code class="notranslate">Conda.jl</code> without contaminating other projects.  (Maybe similar benefits can be gained via BinaryProvider.jl too?)  I think supporting 32-bit and 64-bit Julia <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="285225439" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/Pkg.jl/issues/93" data-hovercard-type="issue" data-hovercard-url="/JuliaLang/Pkg.jl/issues/93/hovercard" href="https://github.com/JuliaLang/Pkg.jl/issues/93">JuliaLang/Pkg.jl#93</a> can also be done by changing "build option" of the "root" <code class="notranslate">julia</code> package.  I suppose then it makes sense for <code class="notranslate">deps</code> directories to depend on "build options" too (<a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="285225439" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/Pkg.jl/issues/93" data-hovercard-type="issue" data-hovercard-url="/JuliaLang/Pkg.jl/issues/93/hovercard?comment_id=354577967&amp;comment_type=issue_comment" href="https://github.com/JuliaLang/Pkg.jl/issues/93#issuecomment-354577967">JuliaLang/Pkg.jl#93 (comment)</a>).</p>