setup.py 检查是否存在非 python 库依赖
setup.py check if non-python library dependency exists
我正在尝试为 cgal-bindings 制作一个 setup.py。要安装它,用户至少需要有特定版本的 CGAL。此外,CGAL 有一些可选目标,如果用户有一些库(如 Eigen3),则应构建这些目标。 Python 中是否有跨平台的方式来检查这个?
我可以在 ctypes.util
中使用 find_library
来检查库是否存在,但我没有看到任何简单的方法来获取版本 。 <-- 这实际上并不总是有效,有些库只是头文件,如 eigen3,它是一个 C++ 模板库。
使用 setup()
的 install_requires
参数仅适用于 Python 库,而 CGAL 是一个 C/C++ 库。
是否应根据某些库版本的可用性编译特定扩展模块,可以通过在 setup.py
中动态生成 setup()
的 ext_modules
参数来实现。
对于 ruamel.yaml
的 _yaml.so
模块,只有当 libyaml
开发库已经安装在我的系统上时才应该编译:
import os
from textwrap import dedent
def check_extensions():
"""check if the C module can be build by trying to compile a small
program against the libyaml development library"""
import tempfile
import shutil
import distutils.sysconfig
import distutils.ccompiler
from distutils.errors import CompileError, LinkError
libraries = ['yaml']
# write a temporary .c file to compile
c_code = dedent("""
#include <yaml.h>
int main(int argc, char* argv[])
{
yaml_parser_t parser;
parser = parser; /* prevent warning */
return 0;
}
""")
tmp_dir = tempfile.mkdtemp(prefix = 'tmp_ruamel_yaml_')
bin_file_name = os.path.join(tmp_dir, 'test_yaml')
file_name = bin_file_name + '.c'
with open(file_name, 'w') as fp:
fp.write(c_code)
# and try to compile it
compiler = distutils.ccompiler.new_compiler()
assert isinstance(compiler, distutils.ccompiler.CCompiler)
distutils.sysconfig.customize_compiler(compiler)
try:
compiler.link_executable(
compiler.compile([file_name]),
bin_file_name,
libraries=libraries,
)
except CompileError:
print('libyaml compile error')
ret_val = None
except LinkError:
print('libyaml link error')
ret_val = None
else:
ret_val = [
Extension(
'_yaml',
sources=['ext/_yaml.c'],
libraries=libraries,
),
]
shutil.rmtree(tmp_dir)
return ret_val
这样您就不需要在分发中添加额外的文件。即使你不能在编译时根据版本号编译失败,你也应该
能够从临时目录运行生成程序并检查退出值and/or输出。
我正在尝试为 cgal-bindings 制作一个 setup.py。要安装它,用户至少需要有特定版本的 CGAL。此外,CGAL 有一些可选目标,如果用户有一些库(如 Eigen3),则应构建这些目标。 Python 中是否有跨平台的方式来检查这个?
我可以在 。 <-- 这实际上并不总是有效,有些库只是头文件,如 eigen3,它是一个 C++ 模板库。 ctypes.util
中使用 find_library
来检查库是否存在,但我没有看到任何简单的方法来获取版本
使用 setup()
的 install_requires
参数仅适用于 Python 库,而 CGAL 是一个 C/C++ 库。
是否应根据某些库版本的可用性编译特定扩展模块,可以通过在 setup.py
中动态生成 setup()
的 ext_modules
参数来实现。
对于 ruamel.yaml
的 _yaml.so
模块,只有当 libyaml
开发库已经安装在我的系统上时才应该编译:
import os
from textwrap import dedent
def check_extensions():
"""check if the C module can be build by trying to compile a small
program against the libyaml development library"""
import tempfile
import shutil
import distutils.sysconfig
import distutils.ccompiler
from distutils.errors import CompileError, LinkError
libraries = ['yaml']
# write a temporary .c file to compile
c_code = dedent("""
#include <yaml.h>
int main(int argc, char* argv[])
{
yaml_parser_t parser;
parser = parser; /* prevent warning */
return 0;
}
""")
tmp_dir = tempfile.mkdtemp(prefix = 'tmp_ruamel_yaml_')
bin_file_name = os.path.join(tmp_dir, 'test_yaml')
file_name = bin_file_name + '.c'
with open(file_name, 'w') as fp:
fp.write(c_code)
# and try to compile it
compiler = distutils.ccompiler.new_compiler()
assert isinstance(compiler, distutils.ccompiler.CCompiler)
distutils.sysconfig.customize_compiler(compiler)
try:
compiler.link_executable(
compiler.compile([file_name]),
bin_file_name,
libraries=libraries,
)
except CompileError:
print('libyaml compile error')
ret_val = None
except LinkError:
print('libyaml link error')
ret_val = None
else:
ret_val = [
Extension(
'_yaml',
sources=['ext/_yaml.c'],
libraries=libraries,
),
]
shutil.rmtree(tmp_dir)
return ret_val
这样您就不需要在分发中添加额外的文件。即使你不能在编译时根据版本号编译失败,你也应该 能够从临时目录运行生成程序并检查退出值and/or输出。