Pythonには縁もゆかりもないC/C++をdistutilsでビルドするなんてことをやってると、よくお目にかかる@linux。
メッセージの通りで、C++ なのに -Wstrict-prototypes
つけてると出る警告。「外せばいいじゃん」。その通り。
distutils は、原則として「Python にゆかりのあるものをビルドするため」に最適なもの。Python C 拡張は、API も C だし、C で書く方が主流なので、「C++ 愛してる」とちょいとアレだ。(Cython と C++ をミックスするときも同じ。)
何かというと、
1 from distutils import sysconfig
2 from distutils import ccompiler
3
4 cc = ccompiler.new_compiler()
5 sysconfig.customize_compiler(cc)
という具合に customize_compiler
すると、「煩雑なコンパイルオプションを色々自動でくっつけてくれて幸せ」なわけなんだけれど、「「Python にゆかりのあるものをビルドするため」に最適」が仇となるわけである。それが-Wstrict-prototypes
。
結構前から気にはなってはいたのだけれど、警告だし全く致命傷じゃないもんだからほったらかしにしていた。けどこれ、コンパイルするファイル数が何十・何百になってくると、煩くてしょうがない。ちゃんとしよ、と思った。
要するにこれ、
1 >>> from distutils import sysconfig
2 >>> import json
3 >>> print(json.dumps(sysconfig.get_config_vars(), indent=1))
4 {
5 "AST_H_DIR": "Include",
6 "HAVE_INET_PTON": 1,
7 "HAVE_GETPEERNAME": 1,
8 "HAVE_GETC_UNLOCKED": 1,
9 # ...(snip)...
10 "CC": "gcc -pthread",
11 # ...(snip)...
12 "CFLAGS": "-fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes",
13 # ...(snip)...
これ(sysconfig.get_config_vars()
)に従う、ということ。この設定は Python 本体のコンパイル時に決まる。「Python本体のビルド方法と全くおんなじにせねばならぬ」から、というのが「Python にゆかりのある」場合の話。
けどゆかりがあろうがなかろうが、C++ するのに-Wstrict-prototypes
はどっちみちいらない。
どうしたら一撃で回避出来るかなぁ、と探ってみたが、ちょっと乱暴だけれどこんなんでオッケー:
1 from distutils import sysconfig
2 if sys.platform == 'linux2':
3 sysconfig.get_config_vars()["CC"] = "g++ -pthread"
4 v = sysconfig.get_config_vars()["CFLAGS"]
5 v = v.replace(" -Wstrict-prototypes", "")
6 sysconfig.get_config_vars()["CFLAGS"] = v
setup.py の先頭でこんなことしておけば、あらゆるものがこれに従ってくれる。(Python 2.7 の話です。Python 3.x でどうかは調べてない。)