start

MSYS2/MinGW-w64でWindows版QMPlay2をビルド

思う所があってマルチプラットフォームなメディアプレーヤーQMPlay2をWindowsで自前ビルドした。公式にWindows用ビルドが提供されているので、自前ビルドしようっていう物好きな人はそういないだろうけど、参考になればとメモがてら手順を書いておく。

  • Windows 10 (x64) 20H2
  • msys2
  • MinGW-w64
  • GCC 10.3.0
  • QMPlay2 21.06.07-gti-417708b8

とりあえずmsys2のインストールとパッケージ更新までは済ませておく。

以下の作業はMinGW-w64環境(MSYS2インストールディレクトリのmingw64.exe起動で出てくるシェル)で行う。

コンパイラ、開発環境類をインストール。

pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake

注意すべきはcmake。msys2リポジトリにもcmakeがあるが、こちらはファイルパスの扱いがUNIXスタイルとなるため、mingw-w64リポジトリのソフトで正しく扱えない。したがって、Windowsスタイルのファイルパス用のming-w64のcmakeを使う必要がある。

gitをインストール

pacman -S git

Qtをインストール

pacman -S mingw-w64-x86_64-qt5

FFmpegをインストール。これだけでビルドに必要な最低限のライブラリは殆ど自動で入った記憶。

pacman -S mingw-w64-x86_64-ffmpeg

PortAudioをビルド。MinGWにビルド済みパッケージがあるけど、WASAPIが有効になってないので自前ビルドする必要がある。tarballの取得と展開は割愛。

cd portaudio
/mingw64/bin/cmake .. -G"MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64 -DPA_USE_WMME=1 -DPA_USE_WASAPI=1 -DPA_USE_DS=1 -DPA_USE_WDMKS=1 -DMINGW=1
make -j8
make install

ここまででQMPlay2をビルドする環境が整った。

ソースコードとサブモジュールを取得。

git clone https://github.com/zaps166/QMPlay2.git
git submodule update --init

ビルドディレクトリを作ってcmake。cmakeは前述の通りmingw64のバイナリを明示的に使い、加えてMakefileを生成したいので-Gでオプションが必要。さもないとVisual Studio用のソリューションファイルが生成されてしまう。

cd QMPlay2
mkdir build
cd build
/mingw64/bin/cmake .. -DCMAKE_INSTALL_PREFIX=../install -G"MSYS Makefiles"

上手くいけば↓こんな感じでcmakeが成功する。

-- Could NOT find TAGLIB (missing: TAGLIB_LIBRARY TAGLIB_INCLUDE_DIR)
-- Could NOT find LIBGME (missing: LIBGME_LIBRARY LIBGME_INCLUDE_DIR)
-- Enabled features:
 * Updates, Build with software updates
 * OpenGL, Build with OpenGL support
 * Vulkan, Build with Vulkan support
 * libass, Build with libass support
 * Inputs, Build with Inputs module
 * Modplug, Build with Modplug module
 * Extensions, Build with Extensions module
 * MediaBrowser, Build with MediaBrowser support
 * LastFM, Build with LastFM support
 * Lyrics, Build with lyrics support
 * Radio, Build with Radio Browser support
 * YouTube, Build with YouTube support
 * Visualizations, Build with Visualizations module
 * AudioFilters, Build with AudioFilters module
 * VideoFilters, Build with VideoFilters module
 * PortAudio, Build with PortAudio module
 * DXVA2, Build D3D11VA acceleration into FFmpeg
 * CUVID, Build with CUVID module
 * Notifications, Build additional notifications module
 * Git version, Append Git HEAD to QMPlay2 version

-- Disabled features:
 * PCH, Use precompiled headers
 * CMD, Show CMD when running QMPlay2
 * GLSLC, Compile Vulkan shaders
 * TagLib, Build with tags editor
 * VAAPI, Build VAAPI acceleration into FFmpeg
 * VDPAU, Build VDPAU acceleration into FFmpeg
 * libavdevice, Build FFmpeg with libavdevice suport
 * AudioCD, Build with AudioCD module
 * ALSA, Build with ALSA module
 * Chiptune GME, Build Chiptune with GME support
 * Chiptune SIDPLAY, Build Chiptune with SIDPLAY support
 * PulseAudio, Build with PulseAudio module
 * PipeWire, Build with PipeWire module
 * XVideo, Build with XVideo module
 * Link Time Optimization, Enable link time optimization for release builds
 * Address Sanitizer, Use Address Sanitizer
 * Undefined Behavior Sanitizer, Use Undefined Behavior Sanitizer

-- Build type: Release
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Home/proj/QMPlay2/build

「TagLibとGMEがない」と怒られるが、必須ではないので問題なし。必要ならpacman -S mingw-w64-x86_64-taglib mingw-w64-x86_64-libgmeしとけばいいかと。

必須ライブラリがない場合、怒られてcmakeに失敗するので頑張って対処する。

makeとインストール。

make -j8
make install

上手くいけば、CMAKE_INSTALL_PREFIXで指定したフォルダ、ここでは../installにQMPlay2.exeなどがコピーされる。

PATHの関係でエクスプローラからexeダブルクリックでは起動できないため、ビルドしたシェルに../install/QMPlay2.exeと打ち込んで起動する。試してないけど、必要なDLLをexeと同じ場所に置いたり、PATHにmingw64/binを通せばエクスプローラからでも起動できると思う。

ラチェクラの「返品ポリシー」トロフィーは2周目序盤が簡単

ラチェット&クランク パラレル・トラブルのトロフィー「返品ポリシー」の取得は、2周目の序盤で挑戦するのが簡単だ。

はじめは先行の攻略サイトに倣ってスカルストゥのコロシアムでやってたんだけど、一向に取れる気がしなかった。んで、知人から以下の情報をゲット。

天才か。武器収集トロフィーのために少なくとも2周目序盤のプレイは必須なんだし、確かに1周目にこだわる必要もない罠。

試してみたところ、ネファリウスに襲われ駅に向かう指令が出た後、下図の場所がやりやすいように思う。

理由としては…

  1. 通路で安全、弾を集めやすい、狙いもつけやすい
  2. ヴォイドリアクターが弾切れになったらミセスズーコンで補給できる
  3. 敵が枯れたら落下死でリスポーンできる

ここに至るまでの戦闘でも、リターンショットは随時使える。それらも狙っていけば、さほど時間をかけずにトロフィーがゲットできるかと。少なくともコロシアムでやるより断然楽だろう。言わずもがな1周目の時点でヴォイドリパルサーをヴォイドリアクターまで進化させといてね。

各位のご武運を祈るざます!

代替データストリームの取得はNtQueryInformationFile一択

C#でNTFSの代替データストリーム(Alternate Data Stream)を読み書きしたくなったので調べたことをメモ。正確な部分は把握しきれてないが、非公開関数であるNtQueryInformationFileで列挙するのが確実のようだ。

代替データストリームの取得(列挙)には以下の3つの方法がある。

  1. BackupRead関数を使う
  2. FindFirstStreamW関数, FindNextStreamW関数を使う (Windows Vista以降)
  3. NtQueryInformationFile関数を使う (非公開関数)

正攻法は1, 2で、調べた限りADSの読み書きを行う既存のC#ライブラリは、1のBackupRead/BackupWriteを使っている。

ところがどう言う訳か、BackupReadでは列挙されないストリームが存在しうる。dir /rNirSoft AlternateStreamViewでは表示されるにも関わらずだ。NTFSによるアクセス権限の問題らしいが、詳しいことは分からない。

NtQueryInformationFileはアクセス権限を無視して情報を取得できるらしく、前述のdirやAlternateStreamViewはこのAPIを使っているのだろう。多分。

2の方法は試してないが、アクセス権を無視するオプションはないらしいので望み薄と思われる。

こちらの記事のC#でNtQueryInformationFileを使ったサンプルで、無事目的のADSが取得できることを確認。というわけで、非公開関数ではあるもののNtQueryInformationFileを使うのが確実っぽい。

TS2TSJ25M3の中身とベンチマーク

PS3のバックアップ用に急遽1TB以上のUSBなHDDが必要になった。手持ちのSATA-USB変換器とHDDの組み合わせは、ことごとくPS3で認識されなかったのだよ…。

今更外付けHDDに金掛けたくないなぁと思いつつ販売サイトを物色してると、じゃんぱらでTranscend StoreJet 25M3 TS2TSJ25M3の中古品が2980円だったので即購入。傷あり、USBケーブルなし、本体のみということで状態は期待できなかったが、USB 3.0で2TBのポータブルHDDがその値段なら、多少の瑕疵を差し引いても割安だろう。まぁ実物はそこまで悪くなかったんですけど。

能書きはこれくらいにして、CrystallDiskInfoの結果はこちら。

製品は2018年製造の個体で、中身はご覧のとおりSeagate ST2000LM007-1R8174だった。使用時間も少ないし大当たりだ。

CrystalDiskMarkの結果は以下の通り。64MBと1GBで計測してみた。

64MBの方はキャッシュが効いてるのか、ランダム4Kがそれなりの結果となっている。それ以外は特筆すべき点はないかな。

certbotでthe following renewal configurations were invalidが出た

吹き飛んだ家鯖の環境再構築の一環でcertbotを再設定し、証明書の更新テストを行ったところ「the following renewal configurations were invalid」なるエラーが発生した。

$ sudo certbot --dry-run renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /usr/local/etc/letsencrypt/renewal/hoge.example.com-0001.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
(略)
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/usr/local/etc/letsencrypt/live/hoge.example.com-0001/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /usr/local/etc/letsencrypt/renewal/hoge.example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/certbot/_internal/renewal.py", line 70, in _reconstitute
    renewal_candidate = storage.RenewableCert(full_path, config)
  File "/usr/local/lib/python3.8/site-packages/certbot/_internal/storage.py", line 468, in __init__
    self._check_symlinks()
  File "/usr/local/lib/python3.8/site-packages/certbot/_internal/storage.py", line 538, in _check_symlinks
    raise errors.CertStorageError(
certbot.errors.CertStorageError: expected /usr/local/etc/letsencrypt/live/hoge.example.com/cert.pem to be a symlink
Renewal configuration file /usr/local/etc/letsencrypt/renewal/hoge.example.com.conf is broken. Skipping.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /usr/local/etc/letsencrypt/live/hoge.example.com-0001/fullchain.pem (success)

Additionally, the following renewal configurations were invalid:
  /usr/local/etc/letsencrypt/renewal/hoge.example.com.conf (parsefail)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0 renew failure(s), 1 parse failure(s)

んん-?confファイルのパースエラー?というのは早計で、実際のエラーはその上に書いてある「certbot.errors.CertStorageError: expected /usr/local/etc/letsencrypt/live/hoge.example.com/cert.pem to be a symlink」というやつ。

要は/usr/local/etc/letsencrypt/live/ドメイン/以下のpemファイルは、/usr/local/etc/letsencrypt/archive/ドメイン/のpemファイルへのシンボリックリンクじゃないとダメらしい。liveの方を確認してみたら、確かにシンボリックリンクではなく実ファイルになっていた。

root@example:/usr/local/etc/letsencrypt/live/hoge.example.com # ls -al
total 32
drwxr-xr-x  2 root  wheel     7 Dec 21 08:06 .
drwx------  4 root  wheel     5 May  4 10:36 ..
-rw-r--r--  1 root  wheel   692 Aug 17  2019 README
-rw-r--r--  1 root  wheel  1834 Dec 21 08:06 cert.pem
-rw-r--r--  1 root  wheel  1586 Dec 21 08:06 chain.pem
-rw-r--r--  1 root  wheel  3420 Dec 21 08:06 fullchain.pem
-rw-------  1 root  wheel  1704 Dec 21 08:06 privkey.pem

確かな原因は分からないけど、Boot Environment環境への移行作業でやらかした線が濃厚。

となれば、シンボリックリンクにすれば解決するハズなんだけど、これまた「OpenSSL.crypto.Error」とかいうエラーが発生してダメだった。

そもそも同一ドメインに対して、何で「hoge.example.com.conf」と「hoge.example.com-0001.conf」の2つの設定があるんだ?というか、どちらのconfファイルも作った覚えはない。

色々試してみるとcertbot certonlyコマンドで証明書を取得すると、対応するconfファイルが自動で作られるっぽい。で、同名ファイル(同名ドメイン)が存在する場合、連番付きのconfになる模様。

それならばconfファイルと証明書を全部消し、証明書取得からやり直したところ、無事更新まで通った。confファイル置き場は/usr/local/etc/letsencrypt/renewal/ね。

  • start.txt
  • 最終更新: 2022-07-27 15:26
  • by Decomo