Mac で ngx_mruby 込みで nginx をビルドする際にいろいろハマってた
ちょっと前に解決した話なんですが備忘録的に書いておきます。 (2017/10/03 記述に漏れがあったので修正しました)
前提
最近の openssl の Formula は link を --force を付けたとしても禁止しています。理解はできるけどサクッとビルドしたい時にやや面倒・・・
$ brew link openssl --force Warning: Refusing to link: openssl Linking keg-only openssl means you may end up linking against the insecure, deprecated system OpenSSL while using the headers from Homebrew's openssl. Instead, pass the full include/library paths to your compiler e.g.: -I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib
Homebrew の Formula が入らないよ問題
nginx-full Formula はナイスなことにオプションで ngx_mruby を加えてビルドすることができるようになっています。 http://hb.matsumoto-r.jp/entry/2016/02/10/224532
しかし最近以下の点でハマるようになっていました。
- Homebrew がデフォルトで
sandbox-exec
してビルドするようになり、パーミッションの都合 --with-mruby-module ではビルドが通らなくなる- 一応 --no-sandbox すれば
sandbox-exec
しなくなるので回避できる
- 一応 --no-sandbox すれば
- ngx_mruby のリンク途中でコケる
前者の問題は本質的には mruby-nginx-module の Formula の構成の問題です。 Homebrew で sandbox-exec
してビルドする際、ビルド対象の Formula のディレクトリや /tmp などに書き込み権限を絞ってしまうため、現状の "nginx-full Formula から mruby-nginx-module Formula のビルドを行なう" ような操作が通らなくなります。
これは根が深い問題なので、今回はひとまず後者の問題を回避できるようにしました。
https://github.com/Homebrew/homebrew-nginx/pull/324
これで以下のようにすれば引き続き Homebrew で ngx_mruby をらくらくインストールすることができます。
# 残念ながら --no-sandbox は今のところ必要。しかたないね $ brew install nginx-full --with-mruby-module --no-sandbox
ngx_mruby をソースからビルドする時困るよ問題
前述の通り openssl のインクルードパスなどを、 ngx_mruby の場合は nginx や mruby のビルド時にも渡るようにしてやらなければならないので一工夫がいります。 幸いにも ngx_mruby の configure, Makefile ではいくつか nginx, mruby のビルド時に任意のオプションを渡すための記述がされているのでそれらを駆使するのが良さそうです。
(2017/10/03 追記・修正) nginx の ビルド時には難ありです。
openssl のソースコードを手元に用意して、 ngx_mruby の --with-ngx-src-root
にパスを渡すのがひとつのビルド方法に思われます。
./configure --with-ngx-src-root=/path/to/ngx_mruby/build/nginx_src --with-ngx_config_opt="--with-debug --with-http_stub_status_module --with-http_ssl_module --with-openssl=/path/to/openssl" ...
自分は面倒に感じてしまったので、 nginx の configure に以下のようなパッチを当てて、 Homebrew でインストールした openssl を参照するようにしてしまいました。。。
113a114,129 > if [ $ngx_found = no ]; then > > # Homebrew > > ngx_feature="OpenSSL library in /usr/local/opt/" > ngx_feature_path="/usr/local/opt/openssl/include" > > if [ $NGX_RPATH = YES ]; then > ngx_feature_libs="-R/usr/local/opt/openssl/lib -L/usr/local/opt/openssl/lib -lssl -lcrypto $NGX_LIBDL" > else > ngx_feature_libs="-L/usr/local/opt/openssl/lib -lssl -lcrypto $NGX_LIBDL" > fi > > . auto/feature > fi >
これを利用すれば以下の通りにビルドできます
$ ./configure --with-ngx-src-root=/path/to/ngx_mruby/build/nginx_src --with-ngx_config_opt="--with-debug --with-http_stub_status_module --with-http_ssl_module ... $ NGX_MRUBY_CFLAGS="-I/usr/local/opt/openssl/include" NGX_MRUBY_LDFLAGS="-L/usr/local/opt/openssl/lib -lcrypto" make ... checking for OpenSSL library ... not found checking for OpenSSL library in /usr/local/ ... not found checking for OpenSSL library in /usr/pkg/ ... not found checking for OpenSSL library in /opt/local/ ... not found checking for OpenSSL library in /usr/local/opt/ ... found ...
かなり遠回り感が出てしまいますが、自分の環境ではこれで無事ビルドできました
ところで
High Sierra では OpenSSL が LibreSSL に置き換わるらしいですね。こんな問題にはもうハマらなくて済むのか、あるいは別のハマりどころに結局苦しめられるのか・・・