forked from JuliaPy/PyCall.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuildutils.jl
80 lines (67 loc) · 2.84 KB
/
buildutils.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# Included from build.jl and ../test/test_build.jl
using VersionParsing
import Conda, Libdl
pyvar(python::AbstractString, mod::AbstractString, var::AbstractString) = chomp(read(pythonenv(`$python -c "import $mod; print($mod.$(var))"`), String))
pyconfigvar(python::AbstractString, var::AbstractString) = pyvar(python, "distutils.sysconfig", "get_config_var('$(var)')")
pyconfigvar(python, var, default) = let v = pyconfigvar(python, var)
v == "None" ? default : v
end
pysys(python::AbstractString, var::AbstractString) = pyvar(python, "sys", var)
#########################################################################
# print out extra info to help with remote debugging
const PYCALL_DEBUG_BUILD = "yes" == get(ENV, "PYCALL_DEBUG_BUILD", "no")
function exec_find_libpython(python::AbstractString, options)
# Do not inline `@__DIR__` into the backticks to expand correctly.
# See: https://github.com/JuliaLang/julia/issues/26323
script = joinpath(@__DIR__, "find_libpython.py")
cmd = `$python $script $options`
if PYCALL_DEBUG_BUILD
cmd = `$cmd --verbose`
end
return readlines(pythonenv(cmd))
end
function show_dlopen_error(lib, e)
if PYCALL_DEBUG_BUILD
println(stderr, "dlopen($lib) ==> ", e)
# Using STDERR since find_libpython.py prints debugging
# messages to STDERR too.
end
end
# return libpython name, libpython pointer
function find_libpython(python::AbstractString; _dlopen = Libdl.dlopen)
dlopen_flags = Libdl.RTLD_LAZY|Libdl.RTLD_DEEPBIND|Libdl.RTLD_GLOBAL
libpaths = exec_find_libpython(python, `--list-all`)
for lib in libpaths
try
return (_dlopen(lib, dlopen_flags), lib)
catch e
show_dlopen_error(lib, e)
end
end
# Try all candidate libpython names and let Libdl find the path.
# We do this *last* because the libpython in the system
# library path might be the wrong one if multiple python
# versions are installed (we prefer the one in LIBDIR):
libs = exec_find_libpython(python, `--candidate-names`)
for lib in libs
lib = splitext(lib)[1]
try
libpython = _dlopen(lib, dlopen_flags)
# Store the fullpath to libpython in deps.jl. This makes
# it easier for users to investigate Python setup
# PyCall.jl trying to use. It also helps PyJulia to
# compare libpython.
return (libpython, Libdl.dlpath(libpython))
catch e
show_dlopen_error(lib, e)
end
end
v = pyconfigvar(python, "VERSION", "unknown")
error("""
Couldn't find libpython; check your PYTHON environment variable.
The python executable we tried was $python (= version $v).
Re-building with
ENV["PYCALL_DEBUG_BUILD"] = "yes"
may provide extra information for why it failed.
""")
end