distutils 如何确定要复制哪些二进制文件?
How does distutils determine what binary files to copy?
我有一个像这样为 distutils 定义的 setup
命令(使用 py2app 作为 Mac OS X,如果重要的话):
setup(...,
extensions=Extension('tracking_funcs',
['tracking_funcs/tracking_funcs.pyx'],
include_dirs=[numpyincludedirs,]),
Extension('_psutil_osx',
sources = ['psutil/_psutil_osx.c',
'psutil/_psutil_common.c',
'psutil/arch/osx/process_info.c'],
define_macros=[('PSUTIL_VERSION', int(get_psutilver().replace('.', '')))],
extra_link_args=['-framework', 'CoreFoundation',
'-framework', 'IOKit']),
Extension('_psutil_posix',
sources = ['psutil/_psutil_posix.c'])],
...)
它正确构建了所有三个扩展:
...
building 'tracking_funcs' extension
creating build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c tracking_funcs/tracking_funcs.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs/tracking_funcs.o
... (some compiler warnings) ...
42 warnings generated.
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs/tracking_funcs.o -o build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/tracking_funcs.so
building '_psutil_osx' extension
creating build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil
... (some compiler warnings) ...
2 warnings generated.
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DPSUTIL_VERSION=400 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/_psutil_common.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_common.o
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DPSUTIL_VERSION=400 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/arch/osx/process_info.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/arch/osx/process_info.o
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_osx.o build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_osx.so -framework CoreFoundation -framework IOKit
building '_psutil_posix' extension
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/_psutil_posix.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_posix.o
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_posix.o -o build/dist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_posix.so
...
然后它将构建的二进制文件复制到包目的地,但它只复制三个扩展中的两个:
...
copying file /.../build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/tracking_funcs.so -> /.../dist/my.app/Contents/Resources/lib/python2.7/lib-dynload/tracking_funcs.so
copying file /.../build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_posix.so -> /.../dist/my.app/Contents/Resources/lib/python2.7/lib-dynload/_psutil_posix.so
...
然后我的应用程序崩溃了,因为它在运行时找不到第三个扩展。
我该如何调试它?如果不是从我定义的扩展列表中,distutils 从哪里获取它的依赖树?也许错误在 py2app 而不是 distutils 本身?
允许您浏览模块图形内容的 Py2app uses modulegraph to recursively build a source tree containing all the dependencies of all the dependencies of your project. Running py2app with the debug-modulegraph
flag set will print a bunch of debugging information to the console and drop into a breakpoint:
$ python setup.py py2app --debug-modulegraph
...
(Pdb) for item in mf.flatten(): print item
这可能会在其输出中显示类似于 (MissingModule) psutil._psutil_osx
的内容,这意味着 modulegraph 无法找到该扩展的导入路径。
Modulegraph 公开了一个名为 addPackagePath
的 public 函数,它允许您向它提供额外的提示,告诉它应该在哪里查找特定包中的文件。在这种情况下,在 setup.py
中添加类似的内容应该可以解决问题:
from modulegraph import modulegraph
modulegraph.addPackagePath('psutil', 'build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/psutil/')
我有一个像这样为 distutils 定义的 setup
命令(使用 py2app 作为 Mac OS X,如果重要的话):
setup(...,
extensions=Extension('tracking_funcs',
['tracking_funcs/tracking_funcs.pyx'],
include_dirs=[numpyincludedirs,]),
Extension('_psutil_osx',
sources = ['psutil/_psutil_osx.c',
'psutil/_psutil_common.c',
'psutil/arch/osx/process_info.c'],
define_macros=[('PSUTIL_VERSION', int(get_psutilver().replace('.', '')))],
extra_link_args=['-framework', 'CoreFoundation',
'-framework', 'IOKit']),
Extension('_psutil_posix',
sources = ['psutil/_psutil_posix.c'])],
...)
它正确构建了所有三个扩展:
...
building 'tracking_funcs' extension
creating build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/numpy/core/include -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c tracking_funcs/tracking_funcs.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs/tracking_funcs.o
... (some compiler warnings) ...
42 warnings generated.
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/tracking_funcs/tracking_funcs.o -o build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/tracking_funcs.so
building '_psutil_osx' extension
creating build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil
... (some compiler warnings) ...
2 warnings generated.
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DPSUTIL_VERSION=400 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/_psutil_common.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_common.o
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -DPSUTIL_VERSION=400 -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/arch/osx/process_info.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/arch/osx/process_info.o
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_osx.o build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_osx.so -framework CoreFoundation -framework IOKit
building '_psutil_posix' extension
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c psutil/_psutil_posix.c -o build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_posix.o
/usr/bin/clang -bundle -undefined dynamic_lookup -arch i386 -arch x86_64 -g build/bdist.macosx-10.6-x86_64/temp.macosx-10.6-x86_64-2.7/psutil/_psutil_posix.o -o build/dist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_posix.so
...
然后它将构建的二进制文件复制到包目的地,但它只复制三个扩展中的两个:
...
copying file /.../build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/tracking_funcs.so -> /.../dist/my.app/Contents/Resources/lib/python2.7/lib-dynload/tracking_funcs.so
copying file /.../build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/_psutil_posix.so -> /.../dist/my.app/Contents/Resources/lib/python2.7/lib-dynload/_psutil_posix.so
...
然后我的应用程序崩溃了,因为它在运行时找不到第三个扩展。
我该如何调试它?如果不是从我定义的扩展列表中,distutils 从哪里获取它的依赖树?也许错误在 py2app 而不是 distutils 本身?
允许您浏览模块图形内容的 Py2app uses modulegraph to recursively build a source tree containing all the dependencies of all the dependencies of your project. Running py2app with the debug-modulegraph
flag set will print a bunch of debugging information to the console and drop into a breakpoint:
$ python setup.py py2app --debug-modulegraph
...
(Pdb) for item in mf.flatten(): print item
这可能会在其输出中显示类似于 (MissingModule) psutil._psutil_osx
的内容,这意味着 modulegraph 无法找到该扩展的导入路径。
Modulegraph 公开了一个名为 addPackagePath
的 public 函数,它允许您向它提供额外的提示,告诉它应该在哪里查找特定包中的文件。在这种情况下,在 setup.py
中添加类似的内容应该可以解决问题:
from modulegraph import modulegraph
modulegraph.addPackagePath('psutil', 'build/bdist.macosx-10.6-x86_64/lib.macosx-10.6-x86_64-2.7/psutil/')