Python
Anaconda
HEASoft

anaconda の python で heasoft を make してエラーが出た時の原因と対処方法

anaconda の python で HEASOFT のコンパイル方法

最短のコンパイル方法

まずは理由はともかく anaconda の python で HEASOFT (https://heasarc.nasa.gov/lheasoft/) を動かしたい人向けに、最短経路を示す。(Bourne Shell 環境で記載する。)

前提条件

  • heasoft : 6.22.1 (2018/01/19時点での最新)。
  • macbookpro : 10.11.6
  • anaconda : conda 4.4.4
  • python : version 2.7

上記のバージョンが違くても、python が HEASOFTに組み込まれてからはエラーが発生すると思われる。

(1) コンパイル環境の設定

export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
export PERL=/usr/bin/perl
export PYTHON=/Users/syamada/anaconda/bin/python
export FC=/usr/local/bin/gfortran

ここで、python だけは anaconda の python に設定した。他は公式のマニュアルページと同じ。(https://heasarc.gsfc.nasa.gov/lheasoft/macosx.html)

(2) make を実行する

make build > build.log 2>&1 & 

そうすると、下記のエラーがでて途中で止まる。

/usr/bin/clang++ -c  -o ./heasp_wrap.o -O2 -Wall --pedantic -Wno-comment -Wno-long-long -g  -arch i386 -arch x86_64 -I./ -I/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/BLD/x86_64-apple-darwin15.6.0/include -I/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/x86_64-apple-darwin15.6.0/include -DPACKAGE_NAME="" -DPACKAGE_TARNAME="" -DPACKAGE_VERSION="" -DPACKAGE_STRING="" -DPACKAGE_BUGREPORT="" -DPACKAGE_URL="" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_EXECINFO_H=1 -DHAVE_CONNECT=1 -DHAVE_ACCEPT=1 -DHAVE_LIBM=1 -DHAVE_LIBDL=1 -DHAVE_LIBNCURSES=1 -DSIZEOF_LONG=8 -I/Users/syamada/anaconda/include -I/Users/syamada/anaconda/include/python2.7 heasp_wrap.cxx
/usr/bin/clang++ -dynamiclib -flat_namespace -undefined suppress -O2  -arch i386 -arch x86_64 -rpath /Users/syamada/work/software/heasoft/heasoft-6.22.1/x86_64-apple-darwin15.6.0/lib -o lib_heasp.dylib     heasp_wrap.o    -L./ -L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/BLD/x86_64-apple-darwin15.6.0/lib -L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/x86_64-apple-darwin15.6.0/lib -lhdsp_2.8 -lhdutils_2.7 -lape_2.9 -lCCfits_2.5 -lcfitsio.5.3.42 -lreadline.6.3 -lhdio_2.7 -L/Users/syamada/anaconda/lib -lpython2.7 -lncurses -ldl -lm 
ld: warning: directory not found for option '-L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/x86_64-apple-darwin15.6.0/lib'
ld: warning: ignoring file /Users/syamada/anaconda/lib/libpython2.7.dylib, file was built for x86_64 which is not the architecture being linked (i386): /Users/syamada/anaconda/lib/libpython2.7.dylib
ld: warning: ignoring file /Users/syamada/anaconda/lib/libc++.dylib, file was built for x86_64 which is not the architecture being linked (i386): /Users/syamada/anaconda/lib/libc++.dylib
ld: in '/Users/syamada/anaconda/lib/libc++.1.dylib', file was built for x86_64 which is not the architecture being linked (i386): /Users/syamada/anaconda/lib/libc++.1.dylib for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

(3) heasoft/heasoft-6.22.1/heacore/heasp/python/heasp_wrap.cxx のみ手動でコンパイルする。

heasp_wrap.cxx というファイルは、SWIG(http://www.swig.org/Doc3.0/SWIGDocumentation.html#CONTENTS) で自動生成されたCのコードで、ここでエラーが発生する。

まずは、heasp_wrap.cxxのファイルがある場所に移動する。(見つからなければfinderでファイルを検索する。)

cd heasoft-6.22.1/heacore/heasp/python 

移動したら、clang++ のオプションの -arch i386 を削除して、手動でコンパイルする。

/usr/bin/clang++ -dynamiclib -flat_namespace -undefined suppress -O2 -arch x86_64 -rpath /Users/syamada/work/software/heasoft/heasoft-6.22.1/x86_64-apple-darwin15.6.0/lib -o lib_heasp.dylib     heasp_wrap.o    -L./ -L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/BLD/x86_64-apple-darwin15.6.0/lib -L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/x86_64-apple-darwin15.6.0/lib -lhdsp_2.8 -lhdutils_2.7 -lape_2.9 -lCCfits_2.5 -lcfitsio.5.3.42 -lreadline.6.3 -lhdio_2.7 -L/Users/syamada/anaconda/lib -lpython2.7 -lncurses -ldl -lm 

ld: warning: directory not found for option '-L/Users/syamada/work/software/heasoft/heasoft-6.22.1/heacore/x86_64-apple-darwin15.6.0/lib'

warning は出るが、下記のlib_heasp.dylib が生成されていればOK。

> ls                                                                             
Makefile        heasp.i         heasp.py        heasp_wrap.cxx  heasp_wrap.o    lib_heasp.dylib

(4) 再度、make して、make install する。

make > build2.log 2>&1 & 
make install > install.log 2>&1 & 

でエラーがなくコンパイルできた。

export HEADAS=/Users/syamada/work/software/heasoft/heasoft-6.22.1/x86_64-apple-darwin15.6.0
source $HEADAS/headas-init.sh

でPATHを通して、headas-init.sh を実行して、xspec や xselect が立ち上がることを確認する。

make でエラーが発生する理由

anaconda の libpython の architecture の問題

HEASOFT はデフォルトで、32bitでも64bitでも動くようにコンパイルする仕様である。そのため、

CFLAGS = -Wall --pedantic -Wno-comment -Wno-long-long -g -arch i386 -arch x86_64 -Dunix -fPIC -fno-
CXXFLAGS = -Wall --pedantic -Wno-comment -Wno-long-long -g -arch i386 -arch x86_64

のように、アーキテクチャのオプションを2つ、"-arch i386" と "-arch x86_64" を指定して、intel の 32 bit, 64 bit のどちらでも動くようにコンパイルする設計となっている。

python はどうかというと、mac 純正のpython は、

> lipo -info /System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib 
Architectures in the fat file: /System/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib are: i386 x86_64 ```

fat ファイルになっており、32bitと64bitのライブラリを合体させたものになっているのに対して、anaconda の python は、

```bash:
> lipo -info /Users/syamada/anaconda/lib/libpython2.7.dylib
Non-fat file: /Users/syamada/anaconda/lib/libpython2.7.dylib is architecture: x86_64

64bit のみである。そのため、anaconda の python を使ってコンパイルするときに、-arch i386 をつけてしまうとコンパイルでエラーが発生する。

参考文献