31

私は Yesod を初めて使用し、Heroku にデプロイできるように Yesod を静的にビルドするのに苦労しています。

静的コンパイルを反映するようにデフォルトの .cabal ファイルを変更しました

if flag(production)
   cpp-options:   -DPRODUCTION
   ghc-options:   -Wall -threaded -O2 -static -optl-static
else
   ghc-options:   -Wall -threaded -O0

そして、それはもはや構築されません。大量の警告が表示された後、次のような未定義の参照が多数表示されます。

Linking dist/build/personal-website/personal-website ...
/usr/lib/ghc-7.0.3/libHSrts_thr.a(Linker.thr_o): In function
`internal_dlopen':
Linker.c:(.text+0x407): warning: Using 'dlopen' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwent':
HsUnix.c:(.text+0xa1): warning: Using 'getpwent' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In
function `__hsunix_getpwnam_r':
HsUnix.c:(.text+0xb1): warning: Using 'getpwnam_r' in statically
linked applications requires at runtime the shared libraries from the
glibc version used for linking
/usr/lib/libpq.a(thread.o): In function `pqGetpwuid':
(.text+0x15): warning: Using 'getpwuid_r' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(ip.o): In function `pg_getaddrinfo_all':
(.text+0x31): warning: Using 'getaddrinfo' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__63.o): In function `sD3z_info':
(.text+0xe4): warning: Using 'gethostbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__164.o): In function `sFKc_info':
(.text+0x12d): warning: Using 'getprotobyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/
libHSnetwork-2.3.0.2.a(BSD__155.o): In function `sFDs_info':
(.text+0x4c): warning: Using 'getservbyname' in statically linked
applications requires at runtime the shared libraries from the glibc
version used for linking
/usr/lib/libpq.a(fe-misc.o): In function `pqSocketCheck':
(.text+0xa2d): undefined reference to `SSL_pending'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x31): undefined reference to `ERR_get_error'
/usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage':
(.text+0x41): undefined reference to `ERR_reason_error_string'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x2f8): undefined reference to `SSL_check_private_key'
/usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL':
(.text+0x3c0): undefined reference to `SSL_CTX_load_verify_locations'
(... snip ...)

コンパイルするだけ-static-optl-static すべてが正常にビルドされますが、Heroku で起動しようとするとアプリケーションがクラッシュします。

2011-12-28T01:20:51+00:00 heroku[web.1]: Starting process with command
`./dist/build/personal-website/personal-website -p 41083`
2011-12-28T01:20:51+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: error while loading shared libraries: libgmp.so.10:
cannot open shared object file: No such file or directory
2011-12-28T01:20:52+00:00 heroku[web.1]: State changed from starting
to crashed

ここで提案されているように、libgmp.so.10 を LD_LIBRARY_PATH に追加しようとした ところ、次のエラーが発生しました。

2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by ./dist/build/personal-website/personal-website)
2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/
personal-website: /lib/libc.so.6: version `GLIBC_2.14' not found
(required by /app/dist/build/personal-website/libgmp.so.10)
2011-12-28T01:31:25+00:00 heroku[web.1]: State changed from starting
to crashed
2011-12-28T01:31:25+00:00 heroku[web.1]: Process exited

コンパイルしているlibcのバージョンが違うようです。libgmp の場合と同じ方法でライブラリのバッチに libc を追加しようとしましたが、Heroku 側でアプリケーションを起動するとセグメンテーション エラーが発生します。

私のPCではすべて正常に動作します。私はghc 7.0.3で64ビットのarchlinuxを実行しています。 公式の Yesod ブログのブログ投稿はかなり簡単に見えましたが、この時点で困惑しています。誰にもアイデアはありますか?静的にビルドせずにこのことを機能させる方法があれば、私もそれを受け入れます。

編集

回答ごとEmployed Russiansに、これを修正するために次のことを行いました。

まず、プロジェクト ディレクトリの下に新しいディレクトリを作成libし、不足している共有ライブラリをそこにコピーしました。この情報は、実行して出力を比較することで取得できldd path/to/executableますheroku run ldd path/to/executable

次にheroku config:add LD_LIBRARY_PATH=./lib、アプリケーションが開始されると、ダイナミック リンカは新しい lib ディレクトリでライブラリを探します。

最後に、ubuntu 11.10 仮想マシンを作成し、そこからビルドして Heroku にデプロイしました。これには、Heroku ホストで動作する十分に古い glibc があります。

編集: 私はそれ以来、Yesod wikiでチュートリアルを書いています。

4

3 に答える 3

63

Yesod が何であるかはわかりませんが、他のエラーのそれぞれが何を意味するかは正確に知っています。

まず、静的にリンクしようとしないでください。表示される警告は正確です。静的にリンクし、警告が表示されるルーチンの 1 つを使用する場合、システムとまったく同じバージョンの libc.so.6 を使用してシステムで実行するように調整する必要があります。ビルド時に使用しました。

一般に信じられていることとは反対に、静的リンクは、Linux でポータブルな実行可能ファイルを生成するのではなく、生成します。

他の (静的) リンク エラーはlibopenssl.a、リンク時の欠落が原因です。

しかし、「正気の」ルートに進み、動的リンクを使用すると仮定しましょう。

動的リンクについては、Linux (および他のほとんどの UNIX) は下位互換性をサポートしています。古いバイナリは新しいシステムでも引き続き動作します。ただし、上位互換性はサポートしていません (新しいシステムでビルドされたバイナリは、通常、古いシステムでは実行されません)。

しかし、それはあなたがやろうとしていることです: glibc-2.14 (またはそれ以降) でシステムを構築し、glibc-2.13 (またはそれ以前) でシステムを実行しています。

もう 1 つ知っておく必要があるのは、glibc は 200 以上のバイナリで構成されており、すべてが完全に一致する必要があるということです。2 つの主要なバイナリは/lib/ld-linux.soとです/lib/libc.so.6(ただし、他にも多数あります: libpthread.so.0libnsl.so.1など)。これらのバイナリの一部が異なるバージョンの glibc からのものである場合、通常はクラッシュします。glibc-2.14 を に配置しようとしたときに、まさにそれが得られlibc.so.6ましたLD_LIBRARY_PATH-- それはもはや system と一致しません/lib/ld-linux

では、解決策は何ですか?いくつかの可能性があります (難易度が高くなります):

  1. ld-2.14.so( /lib/ld-linuxsymlink のターゲット) をターゲット システムにコピーして、明示的に呼び出すことができます。

    /path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable
    

    これは通常は機能しますが、 を参照するアプリケーションを混乱させたり、argv[0]自分自身を再実行するアプリケーションを中断させたりする可能性があります。

  2. 古いシステム上に構築できます。

  3. 使用できますappgcc(このオプションはなくなりました。以前の説明については、こちらを参照してください)。

  4. ターゲット システムに一致する chroot 環境をセットアップし、その chroot 内でビルドできます。

  5. Linux から古い Linux へのクロスコンパイラを自分で構築できます

于 2011-12-28T16:23:29.047 に答える
5

いくつかの問題があります。

最先端のディストリビューションで本番バイナリを構築しないでください。本番システムのライブラリには上位互換性がありません。

glibcを静的にリンクしないでください。実行時に常に追加のライブラリをロードしようとします。たとえば、CPUベースのアセンブリ。それがあなたの最初の警告です。

最後のリンカエラーは、コマンドラインに不足しているopensslライブラリに関連しているように見えます。

しかし、全体として、ディストリビューションをダウングレードしてください。

于 2011-12-28T16:29:38.190 に答える
0

glibc-2.14 を必要とするアプリケーションを持っていた Heroku (glibc-2.11 を使用) を起動する際にも同様の問題がありましたが、ソースにアクセスできず、再ビルドできませんでした。私は多くのことを試しましたが、何もうまくいきませんでした。

私の回避策は、Amazon Elastic Beanstalk でサービスを起動し、API インターフェイスのみを提供することでした。

于 2013-07-12T21:38:54.757 に答える