获取 Python 的 LIB 路径
Get Python's LIB path
我可以看到 INCLUDE
路径是 sysconfig.get_path('include')
。
但我没有看到 LIB
的任何相似值。
NumPy outright hardcodes it as os.path.join(sys.prefix, "libs")
在 Windows 和 get_config_var('LIBDIR')
中(未记录且在 Windows 中缺失)否则。
有没有更支持的方式?
下面是(相当长的)subroutine in skbuild.cmaker
that locates libpythonxx.so
/pythonxx.lib
for the running Python. In CMake, 350-line Modules/FindPythonLibs.cmake
专用于此任务。
前者中仅获取目录的部分要简单得多:
libdir = dustutils.sysconfig.get_config_var('LIBDIR')
if sysconfig.get_config_var('MULTIARCH'):
masd = sysconfig.get_config_var('multiarchsubdir')
if masd:
if masd.startswith(os.sep):
masd = masd[len(os.sep):]
libdir = os.path.join(libdir, masd)
if libdir is None:
libdir = os.path.abspath(os.path.join(
sysconfig.get_config_var('LIBDEST'), "..", "libs"))
def get_python_library(python_version):
"""Get path to the python library associated with the current python
interpreter."""
# determine direct path to libpython
python_library = sysconfig.get_config_var('LIBRARY')
# if static (or nonexistent), try to find a suitable dynamic libpython
if (python_library is None or
os.path.splitext(python_library)[1][-2:] == '.a'):
candidate_lib_prefixes = ['', 'lib']
candidate_extensions = ['.lib', '.so', '.a']
if sysconfig.get_config_var('WITH_DYLD'):
candidate_extensions.insert(0, '.dylib')
candidate_versions = [python_version]
if python_version:
candidate_versions.append('')
candidate_versions.insert(
0, "".join(python_version.split(".")[:2]))
abiflags = getattr(sys, 'abiflags', '')
candidate_abiflags = [abiflags]
if abiflags:
candidate_abiflags.append('')
# Ensure the value injected by virtualenv is
# returned on windows.
# Because calling `sysconfig.get_config_var('multiarchsubdir')`
# returns an empty string on Linux, `du_sysconfig` is only used to
# get the value of `LIBDIR`.
libdir = du_sysconfig.get_config_var('LIBDIR')
if sysconfig.get_config_var('MULTIARCH'):
masd = sysconfig.get_config_var('multiarchsubdir')
if masd:
if masd.startswith(os.sep):
masd = masd[len(os.sep):]
libdir = os.path.join(libdir, masd)
if libdir is None:
libdir = os.path.abspath(os.path.join(
sysconfig.get_config_var('LIBDEST'), "..", "libs"))
candidates = (
os.path.join(
libdir,
''.join((pre, 'python', ver, abi, ext))
)
for (pre, ext, ver, abi) in itertools.product(
candidate_lib_prefixes,
candidate_extensions,
candidate_versions,
candidate_abiflags
)
)
for candidate in candidates:
if os.path.exists(candidate):
# we found a (likely alternate) libpython
python_library = candidate
break
# TODO(opadron): what happens if we don't find a libpython?
return python_library
因为它不是任何官方 spec/doc 的一部分,而且 答案,在某些情况下 none 来自 sysconfig
/[=12 的适当变量=] .get_config_var()
已设置,
在所有情况下可靠地获得它的唯一方法,完全作为构建(例如,即使对于 Python在sourcetree)是委托给参考实现。
在distutils
中,为编译器设置库路径的逻辑is located in distutils.commands.build_ext.finalize_options()
。因此,这段代码将在构建时没有副作用:
import distutils.command.build_ext #imports distutils.core, too
d = distutils.core.Distribution()
b = distutils.command.build_ext.build_ext(d) #or `d.get_command_class('build_ext')(d)',
# then it's enough to import distutils.core
b.finalize_options()
print b.library_dirs
注意:
- 并非结果列表中的所有位置都一定存在。
- 如果您的
setup.py
是基于 setuptools
的,请相应地使用 setuptools.Distribution
和 setuptools.command.build_ext
。
- 如果您将影响结果的任何值传递给
setup()
,您也必须在此处将它们传递给 Distribution
。
由于无法保证您需要传递的附加值集会保持不变,并且只有在构建扩展时才需要该值,
- 似乎你根本不应该独立获得这个值:
- 如果您正在使用其他构建工具,您应该继承
build_ext
并在构建过程中从基本方法中获取值。
我可以看到 INCLUDE
路径是 sysconfig.get_path('include')
。
但我没有看到 LIB
的任何相似值。
NumPy outright hardcodes it as os.path.join(sys.prefix, "libs")
在 Windows 和 get_config_var('LIBDIR')
中(未记录且在 Windows 中缺失)否则。
有没有更支持的方式?
下面是(相当长的)subroutine in skbuild.cmaker
that locates libpythonxx.so
/pythonxx.lib
for the running Python. In CMake, 350-line Modules/FindPythonLibs.cmake
专用于此任务。
前者中仅获取目录的部分要简单得多:
libdir = dustutils.sysconfig.get_config_var('LIBDIR')
if sysconfig.get_config_var('MULTIARCH'):
masd = sysconfig.get_config_var('multiarchsubdir')
if masd:
if masd.startswith(os.sep):
masd = masd[len(os.sep):]
libdir = os.path.join(libdir, masd)
if libdir is None:
libdir = os.path.abspath(os.path.join(
sysconfig.get_config_var('LIBDEST'), "..", "libs"))
def get_python_library(python_version):
"""Get path to the python library associated with the current python
interpreter."""
# determine direct path to libpython
python_library = sysconfig.get_config_var('LIBRARY')
# if static (or nonexistent), try to find a suitable dynamic libpython
if (python_library is None or
os.path.splitext(python_library)[1][-2:] == '.a'):
candidate_lib_prefixes = ['', 'lib']
candidate_extensions = ['.lib', '.so', '.a']
if sysconfig.get_config_var('WITH_DYLD'):
candidate_extensions.insert(0, '.dylib')
candidate_versions = [python_version]
if python_version:
candidate_versions.append('')
candidate_versions.insert(
0, "".join(python_version.split(".")[:2]))
abiflags = getattr(sys, 'abiflags', '')
candidate_abiflags = [abiflags]
if abiflags:
candidate_abiflags.append('')
# Ensure the value injected by virtualenv is
# returned on windows.
# Because calling `sysconfig.get_config_var('multiarchsubdir')`
# returns an empty string on Linux, `du_sysconfig` is only used to
# get the value of `LIBDIR`.
libdir = du_sysconfig.get_config_var('LIBDIR')
if sysconfig.get_config_var('MULTIARCH'):
masd = sysconfig.get_config_var('multiarchsubdir')
if masd:
if masd.startswith(os.sep):
masd = masd[len(os.sep):]
libdir = os.path.join(libdir, masd)
if libdir is None:
libdir = os.path.abspath(os.path.join(
sysconfig.get_config_var('LIBDEST'), "..", "libs"))
candidates = (
os.path.join(
libdir,
''.join((pre, 'python', ver, abi, ext))
)
for (pre, ext, ver, abi) in itertools.product(
candidate_lib_prefixes,
candidate_extensions,
candidate_versions,
candidate_abiflags
)
)
for candidate in candidates:
if os.path.exists(candidate):
# we found a (likely alternate) libpython
python_library = candidate
break
# TODO(opadron): what happens if we don't find a libpython?
return python_library
因为它不是任何官方 spec/doc 的一部分,而且 sysconfig
/[=12 的适当变量=] .get_config_var()
已设置,
在所有情况下可靠地获得它的唯一方法,完全作为构建(例如,即使对于 Python在sourcetree)是委托给参考实现。
在distutils
中,为编译器设置库路径的逻辑is located in distutils.commands.build_ext.finalize_options()
。因此,这段代码将在构建时没有副作用:
import distutils.command.build_ext #imports distutils.core, too
d = distutils.core.Distribution()
b = distutils.command.build_ext.build_ext(d) #or `d.get_command_class('build_ext')(d)',
# then it's enough to import distutils.core
b.finalize_options()
print b.library_dirs
注意:
- 并非结果列表中的所有位置都一定存在。
- 如果您的
setup.py
是基于setuptools
的,请相应地使用setuptools.Distribution
和setuptools.command.build_ext
。 - 如果您将影响结果的任何值传递给
setup()
,您也必须在此处将它们传递给Distribution
。
由于无法保证您需要传递的附加值集会保持不变,并且只有在构建扩展时才需要该值,
- 似乎你根本不应该独立获得这个值:
- 如果您正在使用其他构建工具,您应该继承
build_ext
并在构建过程中从基本方法中获取值。
- 如果您正在使用其他构建工具,您应该继承