yesodアプリのketerへの切り替えを試しましたが,icuライブラリのバージョンが一致せず,静的リンクもできなかったので,切り替えができませんでした

問題解決を目指したログですが,問題は解決できませんでした.

keterへの切り替えを試してみる

自作のyesodアプリケーションが度々落ちる状況にあり,これがとてもストレスになり,死にたい.

haskell - Applications written by Yesod sometimes stop responding - Stack Overflow

試しにnginxとsystemdを使った構成からketerを使った自前ビルドをしない構成に切り替えを試してみることにしました.

nginxを介さずにwarpが通信をすることで負荷が軽減されたり想定通りの動きになるかもしれません,期待します.

そしてketerの環境を整えてstack exec -- yesod keterでデプロイしてみたらエラー.ログを見ると,

/opt/keter/temp/application-2/dist/bin/application: error while loading shared libraries: libicuuc.so.58: cannot open shared object file: No such file or directory

なるほどicuが足りない.

アプリケーションでbos/text-icu: This package provides the Haskell Data.Text.ICU library, for performing complex manipulation of Unicode text.を使っているからですね.

ubuntuにicuパッケージを入れられない

sudo apt install libicu-devで解決するかと思いましたがそんなことはありませんでした.

icu package : Ubuntuによるとubuntuのicuパッケージのバージョンバージョン上限は57です.

dev-libs/icu – Gentoo Packagesによるとgentooのicuパッケージのバージョンは58のみです.

手元で生成したバイナリのダイナミックリンクを見てみます.

% ldd application
        linux-vdso.so.1 (0x00007ffd9831f000)
        libicuuc.so.58 => /usr/lib64/libicuuc.so.58 (0x00007f0c936dd000)
        libicui18n.so.58 => /usr/lib64/libicui18n.so.58 (0x00007f0c93267000)
        libicudata.so.58 => /usr/lib64/libicudata.so.58 (0x00007f0c91765000)
        libcrypto.so.1.0.0 => /usr/lib64/libcrypto.so.1.0.0 (0x00007f0c91328000)
        libssl.so.1.0.0 => /usr/lib64/libssl.so.1.0.0 (0x00007f0c910b9000)
        libpq.so.5 => /usr/lib64/libpq.so.5 (0x00007f0c90e89000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f0c90c72000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f0c90a6a000)
        libutil.so.1 => /lib64/libutil.so.1 (0x00007f0c90867000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f0c90663000)
        libgmp.so.10 => /usr/lib64/libgmp.so.10 (0x00007f0c903eb000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f0c900dc000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0c8febc000)
        libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/libgcc_s.so.1 (0x00007f0c8fca5000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f0c8f8f4000)
        libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/libstdc++.so.6 (0x00007f0c8f4f3000)
        libldap_r-2.4.so.2 => /usr/lib64/libldap_r-2.4.so.2 (0x00007f0c8f2a1000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0c93a87000)
        liblber-2.4.so.2 => /usr/lib64/liblber-2.4.so.2 (0x00007f0c8f092000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f0c8ee7b000)

バージョンの不一致でライブラリが動的リンクできません.

ubuntuにicu 58をなんとかねじ込むことも考えましたが,PPAも無いようですし,icuとアプリケーションもサーバ側でビルドしないといけなくなるのでやめました.

gentooにあるicuのバイナリをそのままubuntuサーバにコピーするというのはあまりにもダーティハックすぎるのでやめました.

静的リンクが出来ない

動的リンクがどうやってもダメなら静的リンクして1つのバイナリにしてしまえば良いと思いました.方法を調べてghc-options-optl-static,-optl-pthreadを追加します.

そしてstack buildすると以下のエラー.

/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -licuuc が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -licui18n が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -licudata が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -lcrypto が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -lssl が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -lpq が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -lz が見つかりません
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: -lz が見つかりません
/mnt/data/.stack/programs/x86_64-linux/ghc-8.0.2/lib/ghc-8.0.2/rts/libHSrts_thr.a(Linker.thr_o): 関数 `internal_dlopen' 内:

gentoo側ではstatic-libsを有効にしてないから,staticライブラリが存在しないので当然ですね.

というわけでworld USEでstatic-libsを有効にしてビルドし直そうとすると以下のエラー.

% eix -IU static-libs --only-names|xargs sudo emerge -1

These are the packages that would be merged, in reverse order:

Calculating dependencies \

!!! Problem resolving dependencies for app-text/mupdf
... done!

!!! The ebuild selected to satisfy "app-text/mupdf" has unmet requirements.
- app-text/mupdf-1.11-r2::gentoo USE="X curl opengl openssl static-libs -javascript -libressl -static -vanilla" ABI_X86="(64)"

  The following REQUIRED_USE flag constraints are unsatisfied:
    opengl? ( !static-libs )

  The above constraints are a subset of the following complete expression:
    opengl? ( !static !static-libs )

何故か知らないけれどmupdfではopenglstatic-libsは共存できないらしいです.

なのでstatic-libsが必要なものだけに最小限付加してみます.

# required by haskell optl-static
dev-libs/gmp static-libs
dev-libs/icu static-libs
dev-libs/openssl static-libs
dev-db/postgresql static-libs
sys-libs/zlib static-libs

そしてstack buildしてみたら大量のリンクエラー定義されていない参照ですが発生しました.

/mnt/data/.stack/programs/x86_64-linux/ghc-8.0.2/lib/ghc-8.0.2/rts/libHSrts.a(Linker.o): 関数 `internal_dlopen' 内:

/home/ben/bin-dist-8.0.2-Linux/ghc/rts/Linker.c:959:0: error:
     警告: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib64/postgresql-9.6/lib64/libpq.a(thread.o): 関数 `pqGetpwuid' 内:
(.text+0x11): 警告: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(HsNet.o): 関数 `hsnet_getaddrinfo' 内:
(.text+0x21): 警告: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xffad): 警告: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x1033c): 警告: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xf89f): 警告: Using 'gethostent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xe720): 警告: Using 'sethostent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xdfdf): 警告: Using 'endhostent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xf397): 警告: Using 'getnetbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xf5a2): 警告: Using 'getnetbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xed2f): 警告: Using 'getnetent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xe608): 警告: Using 'setnetent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xe087): 警告: Using 'endnetent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x10e9e): 警告: Using 'getprotobynumber' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x106d7): 警告: Using 'getprotoent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xe838): 警告: Using 'setprotoent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xdf37): 警告: Using 'endprotoent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x11112): 警告: Using 'getprotobyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x11e4f): 警告: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x11b47): 警告: Using 'getservbyport' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0x11497): 警告: Using 'getservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xe950): 警告: Using 'setservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/mnt/data/.stack/snapshots/x86_64-linux/lts-9.0/8.0.2/lib/x86_64-linux-ghc-8.0.2/network-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz/libHSnetwork-2.6.3.2-IsLM4TXcLoRI0fmmBYVyQz.a(BSD.o):(.text+0xde8f): 警告: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicuuc.a(uresbund.ao):(.eh_frame+0x463): `__gxx_personality_v0' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao): 関数 `icu::Collator::makeInstance(icu::Locale const&, UErrorCode&)' 内:
(.text+0x8d3): `icu::SharedObject::removeRef(signed char) const' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao): 関数 `icu::initAvailableLocaleList(UErrorCode&)' 内:
(.text+0x15da): `__cxa_throw_bad_array_new_length' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu8CollatorE[_ZTIN3icu8CollatorE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu15CollatorFactoryE[_ZTIN3icu15CollatorFactoryE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu18ICUCollatorFactoryE[_ZTIN3icu18ICUCollatorFactoryE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu18ICUCollatorServiceE[_ZTIN3icu18ICUCollatorServiceE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu8CFactoryE[_ZTIN3icu8CFactoryE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照です
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../lib64/libicui18n.a(coll.ao):(.rodata._ZTIN3icu30CollationLocaleListEnumerationE[_ZTIN3icu30CollationLocaleListEnumerationE]+0x0): `vtable for __cxxabiv1::__si_class_type_info' に対する定義されていない参照がさらに続いています

上記のようなエラーが数ページ続きます.

applicationのghc-optionだけ弄ってるのがよくないのかと思い,全体に付加してみようとstack build --ghc-options='-optl-static -optl-pthread'してみましたが,以下のようなエラーが出てダメでした.

[ 1 of 26] Compiling Settings         ( src/Settings.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings.o )
[ 2 of 26] Compiling Settings.StaticFiles ( src/Settings/StaticFiles.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings/StaticFiles.o )
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
/usr/lib/gcc/x86_64-pc-linux-gnu/6.4.0/../../../../x86_64-pc-linux-gnu/bin/ld: 最終リンクに失敗しました: 出力に対応するセクションがありません
collect2: エラー: ld はステータス 1 で終了しました
`gcc' failed in phase `Linker'. (Exit code: 1)

調べてみたらstackoverflowで同じような状況になっている人が居るようですね.gcc - Haskell Stack Static Binary relocation R_X86_64_32 against TMC_END can not be used when making a shared object - Stack Overflowこのページを参考にして色々やってみましたが,解決しませんでした.

試しに最適化を外してみましたが,ダメでした.

リンクするライブラリがPIC有効無効で行き違いを起こしているのではないかと思ったので,一度rm -rf ~/.stack/*して,--ghc-options="-fPIC -shared"付きでstack buildしてみましたが,-fPIC を付けて再コンパイルしてください。というエラーが大量に発生しました.付けてるのに…

-sharedのせいかなと思い-fPICだけにしてみましたが,やはり定義されていない参照ですが大量発生してダメでした.

静的リンクが出来ない問題は解決しませんでした.困っています.

icuライブラリはノーマライズ用途で使っているのでharendra-kumar/unicode-transforms: Fast Unicode normalization in Haskellに移行して依存を取り除くのが良いのかもしれません.

それか,keterを使うことを諦めるか,どちらかですね.