はじめに
本記事は何でもすぐに忘れる筆者が次同じ問題にぶち当たったときのための備忘録です。
TL;DR
結論、flake.nixを以下のように設定して、uv add opencv-python すれば動くはず
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
};
in
{
devShells.x86_64-linux.default = pkgs.mkShell {
packages = with pkgs; [
uv
];
LD_LIBRARY_PATH =
pkgs.lib.makeLibraryPath
(with pkgs; [
stdenv.cc.cc.lib
libGL
glib
xorg.libSM
xorg.libICE
]);
shellHook = ''
export QT_PLUGIN_PATH=${pkgs.qt5.qtbase}/lib/qt5/plugins
export QT_QPA_PLATFORM=xcb
'';
};
};
}
本題
NixOSでOpenCVを使おうとしたところ以下のようなエラーが出ました。
qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins"
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: xcb.
一見すると簡単に解決しような見た目をしています。
一旦調べる
今はネットで調べれば大抵のことはわかる時代なので、google先生に聞いて見たところ、それっぽいNixOSのフォーラムやスレッドがヒットしました。
しかしながら中身をみるとわかる通り、多くは「まだ解決してないから解決したら教えてね」と言った感じのことが書かれています。どうやら色々な人が苦戦している問題のようです。
筆者は一旦、ここで詰みました。
詰んでいても仕方ないのでChatGPTとお話したところ、フォーラムにも書いてあった通り、shellHookにQt関連の環境変数をエクスポートすれば前に進めそうなことがわかりました。
早速、設定してみたところ、治りませんでした。
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
};
in
{
devShells.x86_64-linux.default = pkgs.mkShell {
packages = with pkgs; [
uv
];
LD_LIBRARY_PATH =
pkgs.lib.makeLibraryPath
(with pkgs; [
stdenv.cc.cc.lib
libGL
glib
]);
shellHook = ''
export QT_PLUGIN_PATH=${pkgs.qt5.qtbase}/lib/qt5/plugins
export QT_QPA_PLATFORM=xcb
'';
};
};
}
Qtのエラーを見る
もう一回ChatGPTに聞いて見たところ、今度はexport QT_DEBUG_PLUGINS=1を実行して、Qtがプラグインをどこに見へ行って、どう失敗しているか見れば良いと言われました。これをやって見た結果が以下になります。
QFactoryLoader::QFactoryLoader() checking directory path "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms" ...
QFactoryLoader::QFactoryLoader() looking at "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms/libqxcb.so"
Found metadata in lib /home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms/libqxcb.so, metadata=
{
"IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3",
"MetaData": {
"Keys": [
"xcb"
]
},
"archreq": 0,
"className": "QXcbIntegrationPlugin",
"debug": false,
"version": 331520
}
Got keys from plugin meta data ("xcb")
QFactoryLoader::QFactoryLoader() checking directory path "/home/.../.local/share/uv/python/cpython-3.10.18-linux-x86_64-gnu/bin/platforms" ...
qt.qpa.plugin: Could not find the Qt platform plugin "wayland" in "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins"
Cannot load library /home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms/libqxcb.so: (libSM.so.6: cannot open shared object file: No such file or directory)
QLibraryPrivate::loadPlugin failed on "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms/libqxcb.so" : "Cannot load library /home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins/platforms/libqxcb.so: (libSM.so.6: cannot open shared object file: No such file or directory)"
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/.../.venv/lib/python3.10/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
Available platform plugins are: xcb.
zsh: abort (core dumped) python src/test.py
エラーに書いてある通り、xcbのプラグインはしっかりと発見できており、ロードに失敗していることがわかりました。加えて、libSM.so.6なる共有ライブラリファイルが存在しないためにロードが失敗していることもわかりました。
そこで、libSM.soを提供してくれるパッケージである、xorg.libSMとその依存であるxorg.libICEをbuildInputsに追加してみました。
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = import nixpkgs {
inherit system;
config = {
allowUnfree = true;
};
};
in
{
devShells.x86_64-linux.default = pkgs.mkShell {
packages = with pkgs; [
uv
];
LD_LIBRARY_PATH =
pkgs.lib.makeLibraryPath
(with pkgs; [
stdenv.cc.cc.lib
libGL
glib
xorg.libSM
xorg.libICE
]);
shellHook = ''
export QT_PLUGIN_PATH=${pkgs.qt5.qtbase}/lib/qt5/plugins
export QT_QPA_PLATFORM=xcb
'';
};
};
}
これで実行してみたところ、エラーなく実行することができました!
終わりに
今回も突発的に書いた備忘録なせいで相変わらずの低品質な記事となってしまいましたが、同じ問題に遭遇して困っている人の役に立てば幸いです。
それではまた次の記事でお会いしましょうノシ