我有一个 Distutils setup.py 脚本,它使用 new_compiler().compile() 来编译测试程序以确保某些功能(例如 MPI)在系统上可用。

我的问题是在一种情况下 compile() 调用会导致编译器错误,但手动编译相同的小测试程序却不会。错误位于标准头文件 (mpi.h) 内。我所有的实际源文件也包含这个头文件,但它们编译得很好!这个特殊的检查非常有用,但我需要弄清楚为什么它不应该失败。

所以我的问题是,如何获得 ccompiler.compile() 使用的实际命令?

最佳答案

Adam (Wagner) 的评论是正确的起点:您必须搜索 Distutils 源代码。有很多抽象级别,因此您必须通过几个不同的文件来跟踪执行,但这里是要点:

  • distutils.ccompiler 包包含一个抽象类 CCompiler,它处理调用实际编译器。它具有编译器需要执行的各种任务的方法: preprocesscompilelink 。除了 CCompilercompile 本身没有实现任何这些方法,但即使在那里,它也将实际的编译器调用委托(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/

    10-12 16:57