Return Python 中的包含和运行时库目录

Return the include and runtime lib directories from within Python

假设我想从命令行使用 gcc 来编译 Python 的 C 扩展。我会像这样构造调用:

gcc -o applesauce.pyd -I C:/Python35/include -L C:/Python35/libs -l python35 applesauce.c

我注意到 -I-L-l 选项是绝对必要的,否则您会收到类似于 this 的错误。这些命令告诉 gcc 在哪里寻找头文件 (-I),在哪里寻找静态库 (-L),以及实际使用哪个静态库 (python35,它实际上翻译至 libpython35.a).

现在,如果您的机器是 libsinclude 目录,这显然非常容易,因为如果您不希望它们改变,它们永远不会改变。但是,我正在编写一个从命令行调用 gcc 的程序,其他人将使用 。发生此调用的行看起来像这样:

from subprocess import call
import sys
filename = applesauce.c
include_directory = os.path.join(sys.exec_prefix, 'include')
libs_directory = os.path.join(sys.exec_prefix, 'libs')

call(['gcc', ..., '-I', include_direcory, '-L', libs_directory, ...])

但是,其他人会有不同的平台和不同的Python安装结构,所以仅仅加入路径并不总是有效。

相反,我需要 Python 中的一个解决方案 ,它将可靠地 return includelibs 目录。

编辑:

我查看了模块 distutils.ccompiler,发现了很多有用的函数,它们部分使用了 distutils,但为我定制了它,使我的编译器完全跨平台。唯一的问题是,我需要将包含库和运行时库传递给它...

编辑 2:

我查看了 distutils.sysconfig,我能够可靠地 return 'include' 包含所有头文件的目录。我仍然不知道如何获取运行时库。

distutils.ccompiler 文档是 here

需要此功能的程序名为 Cyther

编译扩展最简单的方法是使用distutilslike this

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

请记住,与 unix/linux、compiling extensions on ms-windows is not straightforward because different versions of the ms compiler are tightly coupled with the corresponding C library. So on ms-windows you have to compile extensions for Python x.y with the same compiler that Python x.y was compiled with. This means using old and unsupported tools for e.g. Python 2.7, 3.3 and 3.4. The situation is changing (part 1, part 2) 和 Python 相比,3.5.

编辑: 更多地研究了这个问题,我怀疑你想要的是 100% 可以实现的。鉴于编译和链接所需的工具根据定义在 Python 之外,并且它们甚至不一定是 Python 编译时使用的工具,sys 和 [=13 中的信息=] 不能保证 Python 实际安装的系统的准确表示。例如。大多数 ms-windows 机器不会安装开发者工具。即使在 POSIX 平台上,安装的 C 编译器和构建 Python 的编译器之间也可能存在差异,尤其是当它作为二进制包安装时。

如果您在方法 distutils 中查看 build_ext.py 的源代码,您会发现用于定位库的不同平台的代码。