Python setuptools不包括C ++标准库标头 [英] Python setuptools not including C++ standard library headers

查看:136
本文介绍了Python setuptools不包括C ++标准库标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将Python包装器编译为我编写的小型C ++库.我编写了以下setup.py脚本,以尝试使用setuptools来编译包装器:

I'm trying to compile a Python wrapper to a small C++ library I've written. I've written the following setup.py script to try to use setuptools to compile the wrapper:

from setuptools import setup, Extension
import numpy as np
import os

atmcmodule = Extension(
    'atmc',
    include_dirs=[np.get_include(), '/usr/local/include'],
    libraries=['mcopt', 'c++'],  # my C++ library is at ./build/libmcopt.a
    library_dirs=[os.path.abspath('./build')],
    sources=['atmcmodule.cpp'],
    language='c++',
    extra_compile_args=['-std=c++11', '-v'],
    )

setup(name='tracking',
      version='0.1',
      description='Particle tracking and MC optimizer module',
      ext_modules=[atmcmodule],
      )

但是,当我在OS X El Capitan上运行python setup.py build时,clang抱怨找不到一些C ++标准库头文件:

However, when I run python setup.py build on OS X El Capitan, clang complains about not finding some C++ standard library headers:

In file included from atmcmodule.cpp:7:
In file included from ./mcopt.h:11:
In file included from ./arma_include.h:4:
/usr/local/include/armadillo:54:12: fatal error: 'initializer_list' file not found
  #include <initializer_list>
           ^
1 error generated.
error: command 'gcc' failed with exit status 1

-v标志传递给编译器表明它正在搜索以下包含路径:

Passing the -v flag to the compiler shows that it is searching the following include paths:

#include <...> search starts here:
 /Users/[username]/miniconda3/include
 /Users/[username]/miniconda3/lib/python3.4/site-packages/numpy/core/include
 /usr/local/include
 /Users/[username]/miniconda3/include/python3.4m
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/c++/4.2.1/backward
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/7.0.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks (framework directory)
End of search list.

这显然不包括C ++标准库标头的路径.如果我使用-v选项编译了一个小型测试C ++源代码,则可以看到clang++通常还会搜索路径/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1,并且如果我将此Extension的路径包含在include_dirs选项中,则setup.py脚本,则扩展模块将正确编译并工作.但是,将此路径硬编码到脚本中似乎不是一个好的解决方案,因为该模块也需要在Linux上工作.

This apparently doesn't include the path to the C++ standard library headers. If I compile a small test C++ source with the -v option, I can see that clang++ normally also searches the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1, and if I include this path in the include_dirs option for Extension in my setup.py script, then the extension module compiles correctly and works. However, hard-coding this path into the script doesn't seem like a good solution since this module also needs to work on Linux.

所以,我的问题是如何正确地使setuptools包含必需的标头?

So, my question is how do I properly make setuptools include the required headers?

setuptools尝试编译扩展时,它会打印正在运行的第一个命令:

As setuptools tries to compile the extension, it prints the first command it's running:

gcc -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/[username]/miniconda3/include -arch x86_64 -I/Users/[username]/miniconda3/lib/python3.4/site-packages/numpy/core/include -I/Users/[username]/Documents/Code/ar40-aug15/monte_carlo/mcopt -I/usr/local/include -I/Users/[username]/miniconda3/include/python3.4m -c /Users/[username]/Documents/Code/ar40-aug15/monte_carlo/atmc/atmcmodule.cpp -o build/temp.macosx-10.5-x86_64-3.4/Users/[username]/Documents/Code/ar40-aug15/monte_carlo/atmc/atmcmodule.o -std=c++11 -fopenmp -v

如果我将此命令粘贴到终端中并自己运行,则扩展名将成功编译.因此,我怀疑setuptools正在修改一些我不知道的环境变量,或者是它实际在运行的命令有些虚假.

If I paste this command into a terminal and run it myself, the extension compiles successfully. So I suspect either setuptools is modifying some environment variables I'm not aware of, or it's lying a little about the commands it's actually running.

推荐答案

Setuptools尝试使用检查标志后用来编译我的Python安装程序(来自Anaconda)时,我发现它正在针对Mac OS X最低版本10.5进行编译.这似乎使其使用GCC libstdc ++而不是clang的libc ++(支持C ++ 11 ).

Setuptools tries to compile C/C++ extension modules with the same flags used to compile the Python interpreter. After checking the flags used to compile my Python install (from Anaconda), I found it was compiling for a minimum Mac OS X version of 10.5. This seems to make it use the GCC libstdc++ instead of clang's libc++ (which supports C++11).

这可以通过将环境变量MACOSX_DEPLOYMENT_TARGET设置为10.9(或更高版本)或在extra_compile_args上添加'-mmacosx-version-min=10.9'来解决.

This can be fixed by either setting the environment variable MACOSX_DEPLOYMENT_TARGET to 10.9 (or later), or adding '-mmacosx-version-min=10.9' to extra_compile_args.

这篇关于Python setuptools不包括C ++标准库标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆