我有一个 Distutils setup.py 脚本,它使用 new_compiler().compile() 来编译测试程序以确保某些功能(例如 MPI)在系统上可用。
我的问题是在一种情况下 compile() 调用会导致编译器错误,但手动编译相同的小测试程序却不会。错误位于标准头文件 (mpi.h) 内。我所有的实际源文件也包含这个头文件,但它们编译得很好!这个特殊的检查非常有用,但我需要弄清楚为什么它不应该失败。
所以我的问题是,如何获得 ccompiler.compile() 使用的实际命令?
最佳答案
Adam (Wagner) 的评论是正确的起点:您必须搜索 Distutils 源代码。有很多抽象级别,因此您必须通过几个不同的文件来跟踪执行,但这里是要点:
distutils.ccompiler
包包含一个抽象类 CCompiler
,它处理调用实际编译器。它具有编译器需要执行的各种任务的方法: preprocess
、 compile
和 link
。除了 CCompiler
, compile
本身没有实现任何这些方法,但即使在那里,它也将实际的编译器调用委托(delegate)给方法 _compile
。因此,您需要检查平台上使用的 CCompiler
的子类,并查看其 _compile
的实现。 CCompiler
有几个不同的子类,每个子类都在自己的包中实现,但“两大类”是 distutils.unixccompiler.UnixCCompiler
(在类 UNIX 系统上调用 native 编译器)和 distutils.msvccompiler.MSVCCompiler
(调用 Visual Studio)。这两个都使用函数 distutils.spawn.spawn
来实际运行外部进程。 distutils.spawn.spawn
的源代码中,您会注意到每个命令在运行之前都记录在 INFO
级别。但问题是,这不使用 Python 的内置日志系统;相反,它使用在 distutils.log
中实现的 Distutils 的自定义记录器。 distutils.log
的源代码,您将看到有一个函数 set_verbosity
用于设置日志记录级别。不幸的是,它没有绑定(bind)到 Distutils 中的任何其他调试基础设施(例如 DISTUTILS_DEBUG
环境变量),因此您需要手动调用distutils.log.set_verbosity(1)
在运行任何编译命令之前,在安装脚本中的某处。一旦你这样做了,所有编译命令(以及谁知道其他信息)都应该打印到标准输出。
关于python - 如何获取 Distutils compile() 函数使用的实际命令?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7924420/