Alma8ベースのDockerコンテナにQt6を構築し、DockerホストはFedora 35です。
場合によっては(下記)、すべてのQtライブラリはロードされませんlibQt6Core.so[.6[.2.4]]
。ただし、ファイルが存在し、正しいディレクトリから検索されます。libQt6Dbus.so
たとえば、別のQtライブラリを見つけてロードします。
幅広いデバッグ、再構築、ウェブ検索では、根本的な原因が何であるか、どのように解決できるかについての手がかりを得ることができませんでした。
ポジショニングの問題
問題の範囲を次のシナリオに絞り込んだ。
- 私は2つの最小の仮想マシンを作成しました。 1つはcentos7を使用し、もう1つはalma8を使用しました。
- 公式リポジトリからDockerをインストールしました。
- 両方の仮想マシンで同じDockerイメージを実行し、同じqt6パッケージをインストールしています。
- Dockerホストがcentos7のときに競合が発生しました。
- Dockerホストがalma8のときに機能します。
理論と問題
- Qt6はAlma8に基づいて構築されており、Centos7が提供するものよりも最新のシステムライブラリにリンクされているため、Qt6はCentos7では実行されません(完全に期待されており、問題ありません)。しかしそれはしなければならないAlma8 Dockerコンテナ内のどこでも実行できます。
- コンテナイメージはどこでも実行できるはずですが、この場合、ホストOSの「何か」がコンテナにこっそり入って問題を引き起こす可能性があります。両方のコンテナがまったく同じ画像を使用しても同じです。
問題は、この「物事」とは何か、どうやってビルドを中断させるのかです。
私が試したこと
libQt6Gui.so
以下を使ってロードできるかlibQt6Core.so
、libQt6Core.so
偽に見えるか確認しました。
ldd
若干の違いがありますLD_DEBUG=libs ldd
(下記参照)。- 自由の木何の違いも見えません(しかし素晴らしい木です:))
- pyldd(conda-buildから)
readelf -d
私も次のことを試しました。
- 設定
LD_LIBRARY_PATH
(何も変更していません。正しいパスが常に検索されることを知っているので、それは驚くべきことではありません) - centos7ホストを持つalma8コンテナにQt6をビルド(「:ファイルを開けません」でビルドに失敗しました
libQt6Core.so.6
、ビルドされたライブラリと同じエラー) - centos7コンテナにQt6をビルドする(まだ修正できない他の問題が原因でビルドが失敗する)
違いは次のとおりです。ldd
以下のスクリーンショットでは、Centos7ホストのAlma8-Docker-Containerを見ることができます。左そして右のAlma8ホストの*Alma8-Docker-Container。
最初の2つの画像は結果を示していますldd /opt/emsconda/lib/libQt6Gui.so
。 libQt6Core
左には見つかりませんが、右には見つかります。
2番目のスクリーンショットは他のQtライブラリを示しています。はい見つけてロードしてください。左側のICUライブラリもありません。おそらくlibQt6Coreもロードされたときにのみロードされるのでしょうか?
このスクリーンショットは結果を示していますLD_DEBUG=libs ldd ...
。どちらの場合も、libQt6Core
検索が正しい場所(/opt/emsconda/lib
)にあることがわかります。ただし、正しいコンテナにのみロードできます。また、左側の `/opt/emsconda/lib/./ を確認し(ハハ)、静かに次のlibに移動します。
エラーメッセージが見つかりません。ファイルが開かないかロードされません。
これlibQt6Core.so
自体を調べてみると、手がかりを得ることができます。これはlinux-vdso.so.1
。
~によるとこの問題このファイルは、オペレーティングシステムのカーネルによってユーザースペースに注入された仮想ライブラリです。
Dockerコンテナは独自のカーネルを実行しないため、このファイルはホストオペレーティングシステムから来たと思われます。たぶんcentos7カーネルが提供できないいくつかの機能libQt6Core
に依存していますか?linux-vdso.so.1
全然知らない…
今まで試したことは何もエラーメッセージを生成していないので、実際の問題は何であるか、デバッグ方法を知りません。あなたが提供できるヒント、ヒント、または助けをいただきありがとうございます。
答え1
質問に回答しましたQtフォーラムで。
要約:
.so
必要な最小カーネルバージョンを表すABIタグが含まれています。でこれを確認できますobjdump -s -j .note.ABI-tag libQt6Core.so.6.2.4
。結果は最後の3ブロック(私の場合は0x03
0x11
0x00
->3.17.0
)にあります。- QTは最新のカーネルでのみ機能するいくつかのシステムコールを使用するため、この情報は意図的にここに配置されます。
- Glibcは共有オブジェクトをロードするときにこの情報を読み取り、それを現在のカーネルバージョンと比較します。一致しない場合、ファイルはロードされません。
- Dockerには独自のカーネルがないため、Dockerホストのカーネルバージョンが比較に使用されます。したがって、DockerイメージがAlma8であっても、私の場合、カーネルはまだCentos7ホストの古いv3.10.0です。
- あなたはそれを使用することができます
strip --remove-section=.note.ABI-tag libQt6Core.so.6.2.4
。 Qtには代替コードがあるようで、問題はありません。