我正在尝试为cgal绑定创建setup.py。要安装它,用户需要至少拥有特定版本的CGAL。此外,如果用户有一些库(如Eigen3),则CGAL有一些可选目标。Python中是否有跨平台的方法来检查这一点?
我可以在<--事实上,这并不是一直有效的,有些库只包含头,比如一个C++模板库的eigen3。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
这样,您就不需要在分发中添加额外的文件。即使您不能在编译时根据版本号失败编译,您也应该能够从临时目录运行生成的程序,并检查退出值和/或输出。