Python distutils 在不同机器上构建不同的扩展
我一直在开发一个包含大量文件的 Python 扩展模块。在一台机器上构建时,python setup.py build
会很乐意检测更改的文件,仅构建这些文件,并将整个文件链接在一起,就像 make 一样。然而,在另一台机器上,对任何文件的一次更改都会触发所有源的重新编译。
只是要明确一点。两台机器都会检测包何时是最新的,并且不会执行任何操作。只有当单个文件发生更改时,它们的行为才会有所不同。
为什么第二台机器会这样做?
机器 1(执行正确的每个文件依赖性检查和构建。)
Python 2.6.4 (r264:75706, Feb 15 2010, 17:06:03)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
setuptools-0.6c11-py2.6
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description: CentOS release 5.4 (Final)
Release: 5.4
Codename: Final
机器 2(当单个源文件更改时重建所有内容。)
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
setuptools-0.6c11-py2.6
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 10.04 LTS
Release: 10.04
Codename: lucid
I have been working on a Python extension module with lots of files. While building on one machine, python setup.py build
will happily detect changed files, build just those files, and link the whole thing together, just like make. On another machine, however, a single change to any file triggers a recompile of all sources.
Just to be clear. Both machines detect when the package is up to date and won't do anything. It is only when a single file changes that their behavior diverges.
Why is the second machine doing this?
Machine 1 (Does proper per-file dependency check and build.)
Python 2.6.4 (r264:75706, Feb 15 2010, 17:06:03)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
setuptools-0.6c11-py2.6
LSB Version: :core-3.1-amd64:core-3.1-ia32:core-3.1-noarch:graphics-3.1-amd64:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: CentOS
Description: CentOS release 5.4 (Final)
Release: 5.4
Codename: Final
Machine 2 (Rebuilds everything when a single source file changes.)
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
setuptools-0.6c11-py2.6
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 10.04 LTS
Release: 10.04
Codename: lucid
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我查看了 Mercurial 存储库并发现了此更改:
Issue #5372: Drop the reuse of .o files in Distutils 的 c 编译器(因为扩展额外选项可能会更改输出而不更改 .c 文件)。
IOW,这是一个被删除的简单优化。
I looked into the Mercurial repo and found this change:
Issue #5372: Drop the reuse of .o files in Distutils' ccompiler (since Extension extra options may change the output without changing the .c file).
IOW, it was a simplistic optimization that was removed.
我已经追踪到 Python 2.6.4 和 Python 2.6.5 之间 distutils 的变化。
distutils.ccompiler.CCompiler
中的两个方法,即_setup_compile
和_prep_compile
,已删除相同的代码块:此代码检查每个源文件针对其目标对象,如果它比目标旧,则将其标记为跳过。我不知道为什么它被删除,但它解释了这种差异。当我将其放回测试时,编译器将恢复为按源依赖性分析。
I've tracked this down to a change in distutils between Python 2.6.4 and Python 2.6.5. Two methods in
distutils.ccompiler.CCompiler
, namely,_setup_compile
and_prep_compile
, have had the same chunk of code removed:This code checks each source file against its target object, and marks it to be skipped if it is older than the target. I don't know why it was removed, but it explains the discrepancy. When I put it back in as a test, the compiler reverts to per-source dependency analysis.