洋食の日記

洋食のことではなく、技術メモを書きます。たまにどうでも良いことも書きます。

pipでuwsgiのインストールに失敗したのはPythonの共有ライブラリがなかったため

Debianのパッケージとは別で、独自にビルドしたPythonを、/usr/localに置いている。 この状態で、uwsgiをpipでインストールしようとしたら、ビルドで失敗した。

$ sudo /usr/local/bin/pip install uwsgi
...
  *** uWSGI linking ***
...
  /tmp/ccDFvj9Y.ltrans6.ltrans.o: 関数 `posix_tempnam.lto_priv.375' 内:
  ccDFvj9Y.ltrans6.o:(.text+0x3578): 警告: the use of `tempnam' is dangerous, better use `mkstemp'
  /tmp/ccDFvj9Y.ltrans6.ltrans.o: 関数 `posix_tmpnam.lto_priv.376' 内:
  ccDFvj9Y.ltrans6.o:(.text+0x36a5): 警告: the use of `tmpnam_r' is dangerous, better use `mkstemp'
  /tmp/ccDFvj9Y.ltrans0.ltrans.o:(.data+0x2a640): `.L1' に対する定義されていない参照です
  /tmp/ccDFvj9Y.ltrans0.ltrans.o:(.data+0x2a648): `.L2' に対する定義されていない参照です
...

gccコンパイルには問題がなく、リンクの段階でコケている。tempnamの警告は直接的な原因ではなさそう。 試行錯誤が必要そうなので、uwsgiのソースを落としてきてビルドすることにした。

$ wget https://projects.unbit.it/downloads/uwsgi-latest.tar.gz
$ tar xzf uwsgi-latest.tar.gz
$ cd uwsgi-2.0.14/
$ make
...
同様のエラーで失敗する

コケるリンクの部分をグ〜っと見ると、ライブラリの指定に静的ライブラリ「libpython2.7.a」がある。そのパスが/usr/local/libからさらに階層を下っていてちょっとおかしい。

*** uWSGI linking ***
gcc -pthread -o uwsgi ...うわ〜といっぱいファイルが並んでて...
-lm /usr/local/lib/python2.7/config/libpython2.7.a -lutil -lcrypt

これを修正しようと思い、Makefileを見ると、uwsgiconfig.pyを叩いているだけだったので、uwsgiconfig.pyを編集する。 ちょっと強引だけど、uwsgiconfig.pyの752行目のライブラリ指定している部分に、/usr/local/lib/libpython2.7.aをぶっこむ。

self.libs = ['-lpthread', '-lm', '-rdynamic', '/usr/local/lib/libpython2.7.a']

これでmakeするとスッと動いた。

$ make
...
############## end of uWSGI configuration #############
total build time: 4 seconds
*** uWSGI is ready, launch it with ./uwsgi ***

独自にPythonをビルドする際に、configureで「–enable-shared」を指定せず、共有ライブラリを作らなかった。 Pythonを共有ライブラリを作るように、再ビルドおよびインストールした状態で、pipでuwsgiをインストールする。

$ sudo /usr/local/bin/pip install uwsgi
...
Successfully built uwsgi
Installing collected packages: uwsgi
Successfully installed uwsgi-2.0.14

共有ライブラリがあれば、Pythonライブラリのリンクが混乱せず、無事にインストールされる。