@@ -48,6 +48,7 @@ class JuliaModule(ModuleType):
48
48
pass
49
49
50
50
51
+
51
52
# add custom import behavior for the julia "module"
52
53
class JuliaImporter (object ):
53
54
def __init__ (self , julia ):
@@ -192,6 +193,15 @@ def module_functions(julia, module):
192
193
pass
193
194
return bases
194
195
196
+ def determine_if_statically_linked ():
197
+ """Determines if this python executable is statically linked"""
198
+ # Windows and OS X are generally always dynamically linked
199
+ if not sys .platform .startswith ('linux' ):
200
+ return False
201
+ lddoutput = subprocess .check_output (["ldd" ,sys .executable ])
202
+ return not ("libpython" in lddoutput )
203
+
204
+
195
205
_julia_runtime = [False ]
196
206
197
207
class Julia (object ):
@@ -246,9 +256,20 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None,
246
256
[runtime , "-e" ,
247
257
"""
248
258
println(JULIA_HOME)
249
- println(Libdl.dlpath("libjulia"))
259
+ println(Libdl.dlpath(string("lib",Base.julia_exename())))
260
+ PyCall_depsfile = Pkg.dir("PyCall","deps","deps.jl")
261
+ if isfile(PyCall_depsfile)
262
+ eval(Module(:__anon__),
263
+ Expr(:toplevel,
264
+ :(using Compat),
265
+ :(Main.Base.include($PyCall_depsfile)),
266
+ :(println(python))))
267
+ else
268
+ println("nowhere")
269
+ end
250
270
""" ])
251
- JULIA_HOME , libjulia_path = juliainfo .decode ("utf-8" ).rstrip ().split ("\n " )
271
+ JULIA_HOME , libjulia_path , depsjlexe = juliainfo .decode ("utf-8" ).rstrip ().split ("\n " )
272
+ exe_differs = not depsjlexe == sys .executable
252
273
self ._debug ("JULIA_HOME = %s, libjulia_path = %s" % (JULIA_HOME , libjulia_path ))
253
274
if not os .path .exists (libjulia_path ):
254
275
raise JuliaError ("Julia library (\" libjulia\" ) not found! {}" .format (libjulia_path ))
@@ -297,14 +318,37 @@ def __init__(self, init_julia=True, jl_runtime_path=None, jl_init_path=None,
297
318
self .api .jl_exception_clear ()
298
319
299
320
if init_julia :
300
- # Replace the cache directory with a private one. PyCall needs a different
301
- # configuration and so do any packages that depend on it. Ideally, we could
302
- # detect packages that depend on PyCall and only use LOAD_CACHE_PATH for them
303
- # but that would be significantly more complicated and brittle, and may not
304
- # be worth it.
305
- self ._call (u"empty!(Base.LOAD_CACHE_PATH)" )
306
- self ._call (u"push!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot()," +
307
- "\" lib\" , \" pyjulia-v$(VERSION.major).$(VERSION.minor)\" ))" )
321
+ use_separate_cache = exe_differs or determine_if_statically_linked ()
322
+ if use_separate_cache :
323
+ # First check that this is supported
324
+ self ._call ("""
325
+ if VERSION < v"0.5-"
326
+ error(\" ""Using pyjulia with a statically-compiled version
327
+ of python or with a version of python that
328
+ differs from that used by PyCall.jl is not
329
+ supported on julia 0.4""\" )
330
+ end
331
+ """ )
332
+ # Intercept precompilation
333
+ os .environ ["PYCALL_PYTHON_EXE" ] = sys .executable
334
+ PYCALL_JULIA_HOME = os .path .join (
335
+ os .path .dirname (os .path .realpath (__file__ )),".." ,"fake-julia" ).replace ("\\ " ,"\\ \\ " )
336
+ os .environ ["PYCALL_JULIA_HOME" ] = PYCALL_JULIA_HOME
337
+ os .environ ["PYCALL_LIBJULIA_PATH" ] = os .path .dirname (libjulia_path )
338
+ self ._call (u"eval(Base,:(JULIA_HOME=\" " + PYCALL_JULIA_HOME + "\" ))" )
339
+ # Add a private cache directory. PyCall needs a different
340
+ # configuration and so do any packages that depend on it.
341
+ self ._call (u"unshift!(Base.LOAD_CACHE_PATH, abspath(Pkg.Dir._pkgroot()," +
342
+ "\" lib\" , \" pyjulia%s-v$(VERSION.major).$(VERSION.minor)\" ))" % sys .version_info [0 ])
343
+ # If PyCall.ji does not exist, create an empty file to force
344
+ # recompilation
345
+ self ._call (u"""
346
+ isdir(Base.LOAD_CACHE_PATH[1]) ||
347
+ mkpath(Base.LOAD_CACHE_PATH[1])
348
+ depsfile = joinpath(Base.LOAD_CACHE_PATH[1],"PyCall.ji")
349
+ isfile(depsfile) || touch(depsfile)
350
+ """ )
351
+
308
352
self ._call (u"using PyCall" )
309
353
# Whether we initialized Julia or not, we MUST create at least one
310
354
# instance of PyObject and the convert function. Since these will be
0 commit comments