MacでOpenSSLを静的リンクしたnginxのビルドが失敗するときの対処法


nginxのビルドエラー

いつからだったか忘れたけどMacでnginx-buildを使ってOpenSSLを静的リンクしたnginxのビルドが通らなくなっていた。

$ nginx-build -d work -openssl
nginx-build: 0.2.0
Compiler: gc go1.4.1
2015/01/18 06:27:21 [warn]configure option is empty.
2015/01/18 06:27:21 Download nginx-1.7.9.....
2015/01/18 06:27:21 Download openssl-1.0.1k.....
2015/01/18 06:27:23 Extract nginx-1.7.9.tar.gz.....
2015/01/18 06:27:39 Extract openssl-1.0.1k.tar.gz.....
2015/01/18 06:27:40 Generate configure script for nginx-1.7.9.....
2015/01/18 06:27:40 Configure nginx-1.7.9.....
2015/01/18 06:27:46 Build nginx-1.7.9.....
exit status 2
2015/01/18 06:30:12 Failed to build nginx-1.7.9
$

直接ビルドするようにしてもやっぱりエラーになる。

$ cd nginx-1.7.9
$ ./configure ¥
 --with-http_ssl_module ¥
 --with-openssl=../openssl-1.0.1k
$ make
               ・
               ・
               ・
  "_sk_value", referenced from:
      _ngx_ssl_session_cache in ngx_event_openssl.o
      _ngx_ssl_check_host in ngx_event_openssl.o
      _ngx_ssl_stapling in ngx_event_openssl_stapling.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [objs/nginx] Error 1
make: *** [build] Error 2
$

OpenSSLのリンクに失敗しているようだ。makeの出力を眺めてるとOpenSSLのconfigure時にこんな警告が出ている。

Operating system: i686-apple-darwinDarwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64
WARNING! If you wish to build 64-bit library, then you have to
         invoke './Configure darwin64-x86_64-cc' *manually*.
         You have about 5 seconds to press Ctrl-C to abort.

OSが32bitって判定されてるけど、64bit環境向けに./Configure darwin64-x86_64-ccを実行しろ、とある。う〜ん、使ってるMacBook Proは64bit環境のはずなんだけどなぁ。

しかし、uname実行してみると、プロセッサアーキテクチャは32bitのものだった。原因はこれっぽい。(Core i7なんだけど、何でi386になるんだろ?)

$ uname -p # print the machine processor architecture name.
i386
$ uname -m # print the machine hardware name.
x86_64
$

nginxにテキトーなパッチをあててみる

diff -r e9effef98874 auto/lib/openssl/make
--- a/auto/lib/openssl/make     Fri Dec 26 16:22:59 2014 +0300
+++ b/auto/lib/openssl/make     Fri Jan 09 19:24:06 2015 +0900
@@ -56,7 +56,7 @@
 $OPENSSL/.openssl/include/openssl/ssl.h:       $NGX_MAKEFILE
         cd $OPENSSL \\
                 && if [ -f Makefile ]; then \$(MAKE) clean; fi \\
                 -       && ./config --prefix=$ngx_prefix no-shared
$OPENSSL_OPT \\
                 +       && ./Configure darwin64-x86_64-cc
--prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
                         && \$(MAKE) \\
                                 && \$(MAKE) install LIBDIR=lib

一応これをあてるとOpenSSLのリンクに成功する。しかし、そのためにnginxのビルドスクリプトを変更するのはまともなやり方ではないので、nginxのconfigureオプション等で外部から情報与えるようにして対処したい。

nginxのMLで聞いてみた

どうすればいいかnginxのMLで聞いてみた。

以下、nginxの開発者からの返信。

Defining KERNEL_BITS=64 in the environment will convince recent 
enough OpenSSL to build 64-bit library instead.

KERNEL_BIT=64をビルド時に付加してやればいい、とのこと。実際これでビルドが通るようになった。

nginx-build側の対応

nginx-buildの方はGOOSGOARCHで環境判別し、必要に応じてKERNEL_BIT=64を付加することで対応した。

Fixed a build failure when OpenSSL is static-linked on Mac.

これでMacでもOpenSSLを静的リンクしてnginxをビルドできるかテストできるようになった。めでたしめでたし。