の gitmaster
ブランチのクローンmatplotlib
を作成し、Mac OSX でビルドする必要がありました。x86_64 GNU/Linux で同じことをしようとすると、次の出力とエラーが表示されます。
BUILDING MATPLOTLIB
matplotlib: yes [1.3.x]
python: yes [3.3.1 (default, May 7 2013, 17:57:31) [GCC
4.8.0]]
platform: yes [linux]
REQUIRED DEPENDENCIES AND EXTENSIONS
numpy: yes [version 1.7.1]
dateutil: yes [using dateutil version 2.1]
tornado: yes [using tornado version 3.0.1]
pyparsing: yes [using pyparsing version 2.0.0]
pycxx: yes [Official versions of PyCXX are not compatible
with Python 3.x. Using local copy]
libagg: yes [pkg-config information for 'libagg' could not
be found. Using local copy.]
freetype: yes [version 9.22.3]
Traceback (most recent call last):
File "./setup.py", line 133, in <module>
result = package.check()
File "/home/khyox/matplotlib/setupext.py", line 808, in check
min_version='1.2')
File "/home/khyox/matplotlib/setupext.py", line 429, in _check_for_pkg_config
ext = self.get_extension()
File "/home/khyox/matplotlib/setupext.py", line 821, in get_extension
CXX().add_flags(ext)
File "/home/khyox/matplotlib/setupext.py", line 716, in add_flags
ext.sources.extend(glob.glob('CXX/*.cxx'))
AttributeError: 'map' object has no attribute 'extend'
エラーを PNG ( libpng
) パッケージの解析にたどり着きました。このライブラリのいくつかのバージョン (1.2.49、1.5.16、および 1.6.2) を試してみましたが、すべてサポートされていmatplotlib
ます (のバージョンは 1.2 以降である必要がありますlibpng
) が、これで問題は解決しませんでした。違いを助けようとして、Mac OSX で Python3.3 を Clang 4.1 (GCC 4.2 と互換性があると言われています) でコンパイルし、この x86_64 GNU/Linux マシンで GCC 4.8.0 を使用しましたが、問題が関連しているとは思えません。これとともに...
どんな手掛かり?事前にどうもありがとうございました!
解決策: 以下のコメントで @DSM によって提案されているように、回避策はsetupext.pyを編集し、関数に次のmake_extension(name, files, *args, **kwargs)
行を追加することです。
ext.sources = list(ext.sources)
行の後:
ext = Extension(name, files, *args, **kwargs)
一方、@tcaswell は問題の容疑者を指摘しました: distutils
. 要するに、matplotlib
私が使用したすべての依存関係をインストールするためにdistribute3
、その最後のリリースはクラスをオーバーライドし、そのメンバーを aではなくa にdistutils.core.Extension
変換します ( docs.python.orgに記載されているように、文字列のリストであることが期待されます)。sources
map
list
詳細を入力すると、デバッグ用のものを追加すると、出力は次のようになります。
BUILDING MATPLOTLIB
matplotlib: yes [1.3.x]
python: yes [3.3.1 (default, May 7 2013, 17:57:31) [GCC
4.8.0]]
platform: yes [linux]
REQUIRED DEPENDENCIES AND EXTENSIONS
Call distutils.core.Extension constructor with name=test and files=[]
Printing (ext = distutils.core.Extension).sources : <map object at 0x7f920c869e50>
The map object is empty!
numpy: yes [version 1.7.1]
dateutil: yes [using dateutil version 2.1]
tornado: yes [using tornado version 3.0.1]
pyparsing: yes [using pyparsing version 2.0.0]
pycxx: yes [Official versions of PyCXX are not compatible
with Python 3.x. Using local copy]
libagg: yes [pkg-config information for 'libagg' could not
be found. Using local copy.]
Call distutils.core.Extension constructor with name=test and files=[]
Printing (ext = distutils.core.Extension).sources : <map object at 0x7f9208e81490>
The map object is empty!
freetype: yes [version 9.22.3]
Call distutils.core.Extension constructor with name=matplotlib._png and files=['src/_png.cpp', 'src/mplutils.cpp']
Printing (ext = distutils.core.Extension).sources : <map object at 0x7f9208e81510>
The map object is empty!
Traceback (most recent call last):
File "setup.py", line 133, in <module>
result = package.check()
File "/home/khyox/matplotlib/setupext.py", line 817, in check
min_version='1.2')
File "/home/khyox/matplotlib/setupext.py", line 438, in _check_for_pkg_config
ext = self.get_extension()
File "/home/khyox/matplotlib/setupext.py", line 830, in get_extension
CXX().add_flags(ext)
File "/home/khyox/matplotlib/setupext.py", line 725, in add_flags
ext.sources.extend(glob.glob('CXX/*.cxx'))
AttributeError: 'map' object has no attribute 'extend'
list
したがって、のsources
メンバーはではなくext
として表示されますmap
。さらに、コンストラクターに渡されるとき、つまり拡張子matplotlib._png
を処理するときのように、ソース ファイルを含めることができません。libpng
このような奇妙な動作の原因を、提供されたのファイルextension.pyにたどりました(最後の行を参照):setuptools
distribute3
class Extension(_Extension):
"""Extension that uses '.c' files in place of '.pyx' files"""
def __init__(self, *args, **kw):
_Extension.__init__(self, *args, **kw)
if not have_pyrex():
self._convert_pyx_sources_to_c()
def _convert_pyx_sources_to_c(self):
"convert .pyx extensions to .c"
def pyx_to_c(source):
if source.endswith('.pyx'):
source = source[:-4] + '.c'
return source
self.sources = map(pyx_to_c, self.sources)
それにもかかわらず、最後のdistribute
コミット (の最後のコミットよりも新しいdistribute3
) では、解決されたようです:
class Extension(_Extension):
"""Extension that uses '.c' files in place of '.pyx' files"""
if not have_pyrex:
# convert .pyx extensions to .c
def __init__(self,*args,**kw):
_Extension.__init__(self,*args,**kw)
sources = []
for s in self.sources:
if s.endswith('.pyx'):
sources.append(s[:-3]+'c')
else:
sources.append(s)
self.sources = sources
ですので、一度distribute3
同期してしまえばdistribute
この問題はおそらく無くなるでしょう。それまでは、@DSM が提案するハックが有効です。