あるディストリビューションでバイナリをビルドして別のディストリビューションで実行する

あるディストリビューションでバイナリをビルドして別のディストリビューションで実行する

Dockerコンテナに非常に簡単なコマンドラインクライアントアプリケーションを構築して顧客に提供したいと思います。このアプリケーションは、PEAK(このアダプタを作成する会社)のCAN-USBアダプタを使用します。 PEAKは、アプリケーションがCANバスにアクセスするために使用するライブラリ(libpcanbasic)を提供します。

libpcanbasicライブラリをビルドするには、アダプタのドライバをインストールする必要があります。私はlibpcanbasic.soライブラリを最初に構築する段階的なドッカーコンテナを使用します。次に、2番目の手順を使用して、更新されたGCC(gcc:12.1.0-bullseye)を含むコンテナを作成します。

いいえ、アプリの接続に問題があります。 libpcanbasic.soは、2段階のコンテナの一部ではなく、libcのバージョン/機能によって異なります。

# readelf -d /usr/lib/libpcanbasic.so

Dynamic section at offset 0x189b8 contains 25 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libc.musl-aarch64.so.1]
 0x000000000000000e (SONAME)             Library soname: [libpcanbasic.so]
 0x000000007ffffffd (AUXILIARY)          Auxiliary library: [visibility=hidden]
 0x000000000000000c (INIT)               0x3f38
 0x000000000000000d (FINI)               0x121f0
 0x0000000000000019 (INIT_ARRAY)         0x28998
 0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x289a8
 0x000000000000001c (FINI_ARRAYSZ)       16 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x190
 0x0000000000000005 (STRTAB)             0x1638
 0x0000000000000006 (SYMTAB)             0x558
 0x000000000000000a (STRSZ)              2719 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x28b88
 0x0000000000000002 (PLTRELSZ)           3096 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x3320
 0x0000000000000007 (RELA)               0x20d8
 0x0000000000000008 (RELASZ)             4680 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x0000000000000018 (BIND_NOW)           
 0x000000006ffffffb (FLAGS_1)            Flags: NOW
 0x000000006ffffff9 (RELACOUNT)          185
 0x0000000000000000 (NULL)               0x0

libcファイル(libc.musl-aarch64.so.1)を/lib2番目のステージコンテナにコピーしてリンクします。

# readelf -d ./build/client/bootloader_client 

    Dynamic section at offset 0x14da8 contains 29 entries:
      Tag        Type                         Name/Value
     0x0000000000000001 (NEEDED)             Shared library: [libpcanbasic.so]
     0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
     0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
     0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
     0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
     0x000000000000000c (INIT)               0x402d98
     0x000000000000000d (FINI)               0x40e670
     0x0000000000000019 (INIT_ARRAY)         0x424d78
     0x000000000000001b (INIT_ARRAYSZ)       16 (bytes)
     0x000000000000001a (FINI_ARRAY)         0x424d88
     0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
     0x0000000000000004 (HASH)               0x400278
     0x000000006ffffef5 (GNU_HASH)           0x4005d0
     0x0000000000000005 (STRTAB)             0x4010d0
     0x0000000000000006 (SYMTAB)             0x400620
     0x000000000000000a (STRSZ)              4274 (bytes)
     0x000000000000000b (SYMENT)             24 (bytes)
     0x0000000000000015 (DEBUG)              0x0
     0x0000000000000003 (PLTGOT)             0x424fe8
     0x0000000000000002 (PLTRELSZ)           2448 (bytes)
     0x0000000000000014 (PLTREL)             RELA
     0x0000000000000017 (JMPREL)             0x402408
     0x0000000000000007 (RELA)               0x402318
     0x0000000000000008 (RELASZ)             240 (bytes)
     0x0000000000000009 (RELAENT)            24 (bytes)
     0x000000006ffffffe (VERNEED)            0x402268
     0x000000006fffffff (VERNEEDNUM)         3
     0x000000006ffffff0 (VERSYM)             0x402182
     0x0000000000000000 (NULL)               0x0            

しかし、生成されたバイナリを別の場所で実行しようとすると問題が発生するようです。

なぜアプリケーションと共有オブジェクト(libpcanbasic.so)が単に依存していないのですかlibc.so?なぜ非常に具体的なバージョンですか?これは変わりますか?そして、クライアントにバイナリを提供したい場合のベストプラクティスは何ですか?

ありがとう、トストン

答え1

libc.soあなたのライブラリは以下を使用しているので、「ただ依存」することで終わりません。muslerlibc(最初のステップではAlpineベースのコンテナイメージを使用しているようです。)あなたのアプリケーションは誰libc.soにも依存しませんが、libc.so.6GNU Cライブラリ(Debianに基づいて構築されており、デフォルトではGNU Cライブラリを使用しています)。

コンテナの構築に精通しているため、顧客にバイナリを提供する最善の方法は、サポートするターゲットに対応するコンテナイメージを使用してバイナリを構築することです。私の知る限り、あなたのライブラリには特定の依存関係がないので、GNU Cライブラリに基づく古いディストリビューションを使ってビルドすることでメンテナンスの負担を簡単にすることができます(同じライブラリバージョンライブラリを使用するすべてのディストリビューションで動作するライブラリをビルドします。 ) 後で musl ベースのディストリビューションで使用) musl ベースのターゲットをサポートするには、musl ベースのディストリビューションを使用できます.

マルチレベルビルドを続行する場合は、少なくともすべてのステップが同じイメージ(または互換性のあるイメージ)に基づいていることを確認する必要があります。

関連情報