MSYSTEMはどこで設定する?

MSYS2 を今まで pacman でアップデートしてきたんですが、ちょっと apcupsd の apctray.exe をいじりたくて、make したら make がないとか言われたんで調べてみたら、構成がいろいろ変わっていて、/ucrt64 とかいろいろできていて、path を通さないといけないっぽい。ので、ちょっと調べてみました。

MSYS2 にある複数環境、C++ アプリ開発で簡単にまとめられていました。が、さてじゃあどれを使うのがいいのかというと、「自分がやりたいことができる環境にしなさい」らしいのですが……。

本家のドキュメントを見ると、Environments に、

If you are unsure, go with UCRT64.

とあるので、UCRT64 にしてみます。すると、

For example, in the UCRT64 environment the $PATH variable starts with /ucrt64/bin:/usr/bin so you get all ucrt64 based tools as well as all msys tools.

とあるように、UCRT64 環境を選ぶと、$PATH が /ucrt64/bin:/usr/bin というふうに変更されて、パスが通るようになっているようです。デフォルトでは bash が呼ばれるので、まずは /etc/profile が読み込まれるはず。そちらを見ると、

unset MINGW_MOUNT_POINT
. '/etc/msystem'
case "${MSYSTEM}" in
MINGW*|CLANG*|UCRT*)
  MINGW_MOUNT_POINT="${MINGW_PREFIX}"
  PATH="${MINGW_MOUNT_POINT}/bin:${MSYS2_PATH}${ORIGINAL_PATH:+:${ORIGINAL_PATH}}"
  PKG_CONFIG_PATH="${MINGW_MOUNT_POINT}/lib/pkgconfig:${MINGW_MOUNT_POINT}/share/pkgconfig"
  PKG_CONFIG_SYSTEM_INCLUDE_PATH="${MINGW_MOUNT_POINT}/include"
  PKG_CONFIG_SYSTEM_LIBRARY_PATH="${MINGW_MOUNT_POINT}/lib"
  ACLOCAL_PATH="${MINGW_MOUNT_POINT}/share/aclocal:/usr/share/aclocal"
  MANPATH="${MINGW_MOUNT_POINT}/local/man:${MINGW_MOUNT_POINT}/share/man:${MANPATH}"
  INFOPATH="${MINGW_MOUNT_POINT}/local/info:${MINGW_MOUNT_POINT}/share/info:${INFOPATH}"
  ;;
*)
  PATH="${MSYS2_PATH}:/opt/bin${ORIGINAL_PATH:+:${ORIGINAL_PATH}}"
  PKG_CONFIG_PATH="/usr/lib/pkgconfig:/usr/share/pkgconfig:/lib/pkgconfig"
esac

となっていて、2行目(ファイル中では48行目)で /etc/msystem をソースしています。長い行の改行がおかしな感じになってますが。

/etc/msystem を見ると、冒頭に

export MSYSTEM="${MSYSTEM:-MSYS}"

とあって、$MSYSTEM が定義されてなければ "MSYS" を設定するようになっています。

ということは、/etc/msystem が読まれる前に MSYSTEM を設定すれば、あとはドミノ倒しでうまくいきそうです。……なのですが、Shells には、

The launchers set the MSYSTEM variable and open a terminal window (mintty) with a proper shell (bash). Bash in turn sources /etc/profile which sets the environment depending on the value of MSYSTEM.

Without the correct environment, various things may and will (sometimes silently) break. The exception is using mingw subsystems from pure Windows, which shouldn't require any special environment apart from an entry in PATH. Do not set MSYSTEM outside of the shells, because that will also break things.

とあり、最後の行でなんだかよくわからないことが書いてあります。たぶん、ここは「shellが読み込んだ後に MSYSTEM を変えるな」ということだと思うのですが…。

ランチャが MSYSTEM 変数をセットしてから mintty を開くということなので、ランチャを見てみます。msys2_shell.cmd がそれです。すると37行目から、

rem Shell types
if "x%~1" == "x-msys" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-msys2" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MSYS& goto :checkparams
if "x%~1" == "x-mingw32" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW32& goto :checkparams
if "x%~1" == "x-mingw64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=MINGW64& goto :checkparams
if "x%~1" == "x-ucrt64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=UCRT64& goto :checkparams
if "x%~1" == "x-clang64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANG64& goto :checkparams
if "x%~1" == "x-clang32" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANG32& goto :checkparams
if "x%~1" == "x-clangarm64" shift& set /a msys2_shiftCounter+=1& set MSYSTEM=CLANGARM64& goto :checkparams
if "x%~1" == "x-mingw" shift& set /a msys2_shiftCounter+=1& (if exist "%WD%..\..\mingw64" (set MSYSTEM=MINGW64) else (set MSYSTEM=MINGW32))& goto :checkparams

などとなっています。どうやら、msys2_shell.cmd に続いてハイフンとシェルタイプを指定すればよいようです。

うちの場合、Windows Terminal を使って MSYS2 を開くので、今までは

C:/Apps/msys64/msys2_shell.cmd -no-start -defterm -msys2 -here -shell zsh

としていましたが、UCRT64環境にしたければ -msys2 を -ucrt64 にすればよいようです。てっきり /etc 以下のどこかのファイルかと思ってしまいました。

AstroNvimでtelescope.nvimがエラーを吐いたとき。

Windowsの環境でAstroNvimをインストールして、Find Fileしたらtelescopeがエラーを吐いてきました。


メッセージは、
Failed to run `config` for telescope.nvim
...a/lazy/telescope.nvim/lua/telescope/extensions/init.lua:10: 'fzf' extension doesn't exist or isn't installed: ...nvim-data/lazy/

なんて感じになってます。 

~/.local/share/nvim-data/lazy/telescope-fsf-native.nvim を見ると、Makefileがあってsrcディレクトリがありますから、AstroNvimのインストール時にコンパイルしようとしてずっこけているようです。

Makefileを見てみると、libfzf.dllを作成して配置してやればよさそうなので、msys64のコンソールを起動してMakefileのあるディレクトリに移動し、make一発。buildディレクトリが作成されて、無事libfzf.dllができあがりました。ちなみに他のディレクトリにインストールする必要はなく、このbuildディレクトにあることが必要なようです。

Neovimを起動してみると上記のエラーは消えていました。めでたしめでたし。

WesternDigitalこわれた。

たぶん寿命を過ぎてるのでクレームとまではいかないのだけれど。

WesternDigitalのWD60EFRXが壊れました。モノは2014年11月に購入。ところが3年で壊れ、RMAにより2017年11月に交換したものです。BlackBlazeでも故障率がそれなりに高かったので、そういうもんなんだろうな、という感じですが。

ちなみに症状は、PCをリブートしたらいきなりWindowsの起動画面で画面中央下のマルがくるくると永遠に回り続ける状態で、最悪ブートドライブ交換の再インストールコースかと覚悟し、m.2 ssdとかいろいろ準備してから取り掛かったらWDがおかしくて止まってたというオチ。スピンドルは回ってるようだけどヘッドの動く音がしないので、叩けば治るかもですが。

ただ、中のデータはそんなに大事なものではなく、さらに大容量の東芝16TBを導入してコピーしていたはずなので、暇を見てコンコンしてみます。

TeXLive2024がインストールできない。

TeX Live 2024がリリースされていたので、インストールしてみました。

BitTorrentでISOをダウンロードして、ISOイメージをダブルクリックすると自動でマウントされるので、そのままinstall-tl-windows.batを実行。するとエラーになります。


こんな感じ。もしかしたらPythonのtcl/tkとかち合ってるのかもしれません。

ぐぐってみるとError in Installation Processにあるのが同じ状態でした。

結論として、コマンドプロンプトを開いて

i:\install-tl-windows.bat -texdir c:\texlive\2024 -gui text

とすれば、GUIなしでインストーラを起動でき、無事にインストールできました。

QNAPで/etc以下のファイルを置き換える。

うちのQNAP NASはちょっと古いTS-669Lです。

[    0.017724] CPU0: Intel(R) Atom(TM) CPU D2701   @ 2.13GHz stepping 01

dmesgではx86アーキテクチャのAtom D2701を使っていることがわかります。
アプリケーションのアップデートに合わせて、時たまQTSのアップデートもありますが、

[  522.957235] ====== 2024-05-04 09:16:06 TS-669L (4.3.4.2675-20240131) boot finished.

バージョンは4.3.4。2017年にリリースされたものです。最新バージョンはQTS 5.2です。なのですでにサポート対象外です。一応、最新の筐体をディスクレスで持ってきて、HDDを順番通りに載せ替えれば使えるらしいですが、でもちゃんと使えてますので。16TBx6ですけど、使えてますので。

ところでこのQNAP、App Centerで提供されているアプリ以外にも、Linuxで利用できる色々なソフトウェアが利用できるようになっています。メールサーバやWikiサーバにすることもできます。そのためには、Entware-stdをインストールして、QPKGを使えるようにする必要があります。

Entware-stdは、以前にあったEntware-ng-3xとEntware-ngが1本化されたものです。インストール方法は、こちらにあります。このページにあるリンクからqpkgをダウンロードして、App Centerの右上にある田の字っぽいアイコンから手動インストールを行います。

次に、ユーザのホームディレクトリ($HOME)に、.profileを作成します。Entware-stdは/opt/etcにprofileファイルを作成し、opkgでインストールされるディレクトリへのパスなどを設定するようになっています。なので、Entwareをインストールしたら、$HOMEに以下の内容を記述した.profileを作成して、/opt/etc/profileをソースします。

source /opt/etc/profile

Entware-stdはGUIアプリではないので、いろいろとインストールするにはsshログインする必要があります。が、sshログインするためのいろいろは割愛で。

Entwareはopkgコマンドで管理します。sshログインしてopkgとタイプすると、ずらーっとコマンドオプションが表示されます。リポジトリのパッケージリストを取得するには、
opkg update

します。ちなみにパッケージリストはここにあるものと同じ内容みたいです。が、ここでroot(あるいはadmin)権限がないと、パッケージリストのxmlファイルを保存できずにエラーになります。もちろんadminアカウントでログインすればいいんですが、個人的セキュリティポリシーとしては通常ユーザでログインして、suなりsudoなりしたいです。使い勝手ならsudoがベスト。でも、sudoするにはsudoersにユーザの記述をしないといけません。標準で入っているsudoは、/usr/etcからsudoersを読み込んでいます。ところがこのディレクトリは、リブートのたびにリフレッシュされます。つまり、起動後にこのsudoersを編集しても、リブートするともとに戻ってしまいます。

リフレッシュするにはオリジナルが必要ですが、そのオリジナルは /mnt/HDA_ROOT/.config にあります。が、そこにはsudoersがありません。どこにあるのか調べようと思っても、ディレクトリツリーもいろいろあっちゃこっちゃしていて、探すのめんどくさい。こんなときこそlocate!……入ってません。しかたないからfindで……Permission denied。

じゃあどこかにファイルを作っておいて、起動時に自動で上書きコピーするしかないか、ということでぐぐってみると、Running Your Own Application at Startupなるページを見つけました。起動時にautorun.shを実行してくれるようです。

autorun.shを使用するには、QNAPのコントロールパネルから、「システム」➔「ハードウェア」➔一般タブの「起動時にユーザー定義処理を実行」にチェックを入れて、autorun.shを実行してくれるように設定します。


起動時のどのタイミングで実行されるのかがわからないので、そのあたりは試してみるしかなさそうです。が、ここにあらかじめ用意しておいたファイルをコピーするような指示を入れれば、うまくいきそうです。もっとも、パーミッションとかセキュリティ的に考えることがありそうなので、/mnt/HDA_ROOT/.autorunなどのフォルダを作ってsudoersなどを置き、それをコピーするようにすればよさそう。

なのですが、もうちょっとクレバーなやり方はないかな、と探してみたら、create-autorunというのを見つけました。これは、上記の方法で作成されたautorun.shをお仕着せで作成してくれるツールです。このツールを使うと、

/share/CACHEDEV1_DATA/.system/autorun/autorun.sh

を自動で作成してくれます。さらに、

/share/CACHEDEV1_DATA/.system/autorun/scripts/

以下に、rc.dスクリプトのように数字付きでスクリプトを置くことで、順番に実行してくれるようです。

このツールはインストールする必要はなく、adminアカウントで

curl -skL https://git.io/create-autorun | sudo bash

などとすればよさそう。

実行すると以下のようにメッセージが出力されます。幅が足りなくて改行が変ですが。

[/mnt/HDA_ROOT] # curl -skL https://git.io/create-autorun | sudo bash
create-autorun.sh 230527
info: NAS model: TS-669L
info: QTS version: 4.3.4 #20240131
info: default volume: /share/CACHEDEV1_DATA
info: autorun partition should be: /dev/sdg6
done: mounted: ext2 device: /dev/sdg6 -> /tmp/create-autorun.fh0ERU
info: confirmed partition tag-file exists: uLinux.conf (we're in the right place)
done: created autorun script processor: /share/CACHEDEV1_DATA/.system/autorun/autorun.sh
done: created script store: /share/CACHEDEV1_DATA/.system/autorun/scripts
done: created symlink from partition to autorun.sh
skip: autorun.sh is already enabled in OS
done: unmounted ext2 autorun partition
info: please place your startup scripts into: /share/CACHEDEV1_DATA/.system/autorun/scripts
info: your autorun.sh file is located at: /share/CACHEDEV1_DATA/.system/autorun/autorun.sh 

インストールしたら、/share/CACHEDEV1_DATA/.system/autorun/scriptsに必要なスクリプトを記述すればいいので、まずsudoersをコピーしてきます。
mkdir etc
/share/CACHEDEV1_DATA/.system/autorun/etc
cp /usr/etc/sudoers .

そしてsudoersを修正したあと、00_sudoersとでもしてscripts以下にファイルを作成します。

#!/usr/bin/env bash
ETC_DIR=/share/CACHEDEV1_DATA/.system/autorun/etc
cp -v ${ETC_DIR}/sudoers /usr/etc

これでsudoが使えるようになりました。

さっそくzshをインストール。

[kats@QNAP ~]$ opkg list zsh
zsh - 5.9-2 - Zsh is a UNIX command interpreter (shell) usable as an interactive
 login shell and as a shell script command processor. Of the standard
 shells, zsh most closely resembles ksh but includes many enhancements.
 Zsh has command line editing, builtin spelling correction, programmable
 command completion, shell functions (with autoloading), a history
 mechanism, and a host of other features.
[kats@QNAP ~]$ sudo opkg install zsh
Installing zsh (5.9-2) to root...
Downloading http://bin.entware.net/x64-k3.2/zsh_5.9-2_x64-3.2.ipk
Installing libcap (2.69-1) to root...
Downloading http://bin.entware.net/x64-k3.2/libcap_2.69-1_x64-3.2.ipk
Installing libncursesw (6.4-2a) to root...
Downloading http://bin.entware.net/x64-k3.2/libncursesw_6.4-2a_x64-3.2.ipk
Installing libncurses (6.4-2a) to root...
Downloading http://bin.entware.net/x64-k3.2/libncurses_6.4-2a_x64-3.2.ipk
Configuring libcap.
Configuring libncursesw.
Configuring libncurses.
Configuring zsh.
[kats@QNAP ~]$ which zsh
/opt/bin/zsh

めでたしめでたし。

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。

 busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv[0] を調べて、その名前によって動作を変える、ということをしたい、ということです。

まずは argtest.py というファイルを作ります。

import sys
import pathlib

f = pathlib.Path(sys.argv[0])
print(sys.argv)
print(f.name)
print(__file__)

これを実行すると、

C:\Users\kats\projects\argtest>argtest.py
['C:\\Users\\kats\\projects\\argtest\\argtest.py']
argtest.py
C:\Users\kats\projects\argtest\argtest.py

C:\Users\kats\projects\argtest>py argtest.py
['argtest.py']
argtest.py
C:\Users\kats\projects\argtest\argtest.py

C:\Users\kats\projects\argtest>python argtest.py
['argtest.py']
argtest.py

のようになります。py または python を指定して実行するとファイル名のみ、直接実行するとフルパス名が argv[0] に入っているようです。

次にショートカットを作成してみます。コマンドプロンプトから作るのは WSH を呼び出すスクリプトが必要なようなので、エクスプローラーから行います。

作成すると、 "argtest.py - ショートカット.lnk" というファイルが作成されます。サフィックスの ".lnk" は拡張子を表示する設定にしないと表示されませんが、ショートカットにつく拡張子です。余談ですが、".lnk" をリネームで削除してもショートカットとして使えるようです。

C:\Users\kats\projects\argtest>"argtest.py - ショートカット.lnk"
['C:\\Users\\kats\\projects\\argtest\\argtest.py']
argtest.py
C:\Users\kats\projects\argtest\argtest.py

C:\Users\kats\projects\argtest>py "argtest.py - ショートカット.lnk"
  File "C:\Users\kats\projects\argtest\argtest.py - ショートカット.lnk", line 1
    L
SyntaxError: source code cannot contain null bytes

C:\Users\kats\projects\argtest>python "argtest.py - ショートカット.lnk"
  File "C:\Users\kats\projects\argtest\argtest.py - ショートカット.lnk", line 1
    L
SyntaxError: source code cannot contain null bytes

実行するとショートカットをダイレクトに起動した場合以外はエラーになります。また、ダイレクトに起動した場合でも argv[0] には元ファイルのファイル名が入っているようです。これだと、呼び出しファイル名で動作を変えることができません。

ちなみに、エディタによっては、ショートカットファイルを編集すると、その元ファイルを開いてくれるものもあるようです。

ショートカットでは argv[0] に元ファイル名しか入っていないと、動作を変えることができません。UNIX系OSではシンボリックリンクを実行形式ファイルに張ると、ちゃんと argv[0] にシンボリックリンクの名前が入ってくるので、Windows上でシンボリックリンクが使えないか調べてみました。

Windowsには標準コマンドで mklink というのがあるようです。mklinkではハードリンクも作成できるようですが、同一のファイルシステム内にしか作成できないということで、ここではシンボリックリンクを試します。

ちなみにmklinkの実行は管理者権限が必要で、通常のコマンドプロンプトから実行すると怒られます。

C:\Users\kats\projects\argtest>mklink argtest2.py argtest.py
argtest2.py <<===>> argtest.py のシンボリック リンクが作成されました

シンボリックリンクを作成しました。早速実行してみると、

C:\Users\kats\projects\argtest>argtest2.py
['C:\\Users\\kats\\projects\\argtest\\argtest.py']
argtest.py
C:\Users\kats\projects\argtest\argtest.py

C:\Users\kats\projects\argtest>py argtest2.py
['argtest2.py']
argtest2.py
C:\Users\kats\projects\argtest\argtest2.py

C:\Users\kats\projects\argtest>python argtest2.py
['argtest2.py']
argtest2.py
C:\Users\kats\projects\argtest\argtest2.py

となります。今度は直接実行した場合に元ファイル名が出てきました。なかなかうまくいかないもんです。がっくし。

余談ですが、開発者モードというのを有効にしてやると、管理者モードのコマンドプロンプトでなくてもmklinkは実行できるようです。が、セキュリティ的によろしくないのでやめておきます。

ついでに、ものは試しでハードリンクもやってみます。

C:\Users\kats\projects\argtest>argtest3.py
['C:\\Users\\kats\\projects\\argtest\\argtest3.py']
argtest3.py
C:\Users\kats\projects\argtest\argtest3.py

C:\Users\kats\projects\argtest>py argtest3.py
['argtest3.py']
argtest3.py
C:\Users\kats\projects\argtest\argtest3.py

C:\Users\kats\projects\argtest>python argtest3.py
['argtest3.py']
argtest3.py
C:\Users\kats\projects\argtest\argtest3.py
これだとバッチリみたいですね。うーむ。

AstroNvimをインストールしてみる。

この2年ほどVS Codeを使っていたのだけれど、編集作業はVimのほうが馴染んでるというのもあって、ふと目にしたAstroNvimの記事に触発されて、またNeovimに戻ろうかな、などと思い立ち。

AstroNvimのGetting Startedの内容に従って進めていきます。

まず、事前に必要なもの。

  • Nerd Fonts (Optional with manual intervention: See Recipes/Customizing Icons) [1]
  • Neovim v0.8+ (Not including nightly)
  • Tree-sitter CLI (Note: This is only necessary if you want to use auto_install feature with Treesitter)
  • A clipboard tool is necessary for the integration with the system clipboard (see :help clipboard-tool for supported solutions)
  • Terminal with true color support (for the default theme, otherwise it is dependent on the theme you are using) [2]

Optional Requirements:

  • ripgrep - live grep telescope search (<leader>fw)
  • lazygit - git ui toggle terminal (<leader>tl or <leader>gg)
  • go DiskUsage() - disk usage toggle terminal (<leader>tu)
  • bottom - process viewer toggle terminal (<leader>tt)
  • Python - python repl toggle terminal (<leader>tp)
  • Node - Node is needed for a lot of the LSPs, and for the node repl toggle terminal (<leader>tn)

Neovimはリリースの一番新しい0.9.4をダウンロードして展開しました。

Nerd Fontは、すべて必要な記号フォントを含んでいるとのことで、自分好みのフォントを選択します。自分は普段はMyricaM Monoを使っているので、そのASCII文字フォントのベースとなっているInconsolataに近いNoto Nerd Fontを使ってみることにします。手間がかかりそうですが、記号部分だけを手持ちのフォントにマージして使うこともできるようですから、日本語を使う際にはそちらのほうがいいかもしれません。

Tre-sitter CLIはcargoまたはnpmでインストールできるようですが、pre-builtバイナリも提供されているようなので、そちらを使ってみます。pre-builtバイナリにはexe形式のバイナリが入っていますので、これを展開したnvim/binディレクトリに配置します。

フルカラーをサポートしたターミナルは、Windows Terminalを使えばいいかと思うのでそのままで。

クリップボードツールは、Windowsの場合にはwin32yankを使うようです。これはデフォルトでneovimのアーカイブに含まれているのでそのままで。

その他のオプションでは、ripgrepは常用しているのでOK、Pythonも常用しているのでOK、あとは追追という事にします。

次に、Installationに従って、古いNeovimの設定をバックアップしておきます。

Move-Item $env:LOCALAPPDATA\nvim $env:LOCALAPPDATA\nvim.bak

ただし、$XDG_CONFIG_HOMEが設定されていると、nvimディレクトリは $HOME/.config/nvimになります。

Move-Item $env:XDG_CONFIG_HOME\nvim $env:XDG_CONFIG_HOME\nvim.bak

nvim-dataもバックアップしておきます。

Move-Item $env:LOCALAPPDATA\nvim-data $env:LOCALAPPDATA\nvim-data.bak

最後に、AstroNvimのリポジトリをクローンします。

git clone --depth 1 https://github.com/AstroNvim/AstroNvim $env:LOCALAPPDATA\nvim

ここでも、$XDG_CONFIG_HOMEが設定されている場合には変更します。

git clone --depth 1 https://github.com/AstroNvim/AstroNvim $env:XDG_CONFIG_HOME\nvim

起動してもいいのですが、とりあえず使用したいLSPとしてpyrightを、またNeovimのPythonバインディングのpynvimをインストールします。

pip install pyright pynvim

そしてWindows TerminalのPowerShellプロンプトからnvimを起動すると、いろいろと裏で設定してくれます。

一部文字が化けているので、Windows TerminalでAstroNvim専用のプロファイルを作成し、インストールしたNerd Fontを使用するように設定を変更します。

それから、ccかgccかclangかなんかのCコンパイラが見つからない、と言われるので、Visual Studioはインストールしてあるのだけれどzigというのを入れてみました。ダウンロードしたアーカイブを展開してパスを通すだけですみます。

使い方は徐々に覚えねば。


SWDなら3線でいいとはいうものの。

 安価で優秀なデバッグプローブはないかしら、と探したら、 Raspberry Pi Debug Probe というのがあったんですが、これは3線がにゅるんと出てるだけです。 もちろんSWDなら3線を繋げばいいのではありますが、汎用的に考えるなら5x2のリボンケーブルコネクタが欲し...