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)を/lib
2番目のステージコンテナにコピーしてリンクします。
# 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.6
GNU Cライブラリ(Debianに基づいて構築されており、デフォルトではGNU Cライブラリを使用しています)。
コンテナの構築に精通しているため、顧客にバイナリを提供する最善の方法は、サポートするターゲットに対応するコンテナイメージを使用してバイナリを構築することです。私の知る限り、あなたのライブラリには特定の依存関係がないので、GNU Cライブラリに基づく古いディストリビューションを使ってビルドすることでメンテナンスの負担を簡単にすることができます(同じライブラリバージョンライブラリを使用するすべてのディストリビューションで動作するライブラリをビルドします。 ) 後で musl ベースのディストリビューションで使用) musl ベースのターゲットをサポートするには、musl ベースのディストリビューションを使用できます.
マルチレベルビルドを続行する場合は、少なくともすべてのステップが同じイメージ(または互換性のあるイメージ)に基づいていることを確認する必要があります。