Luna Displayを買ったので、しばらく使ってみての感想

コンシューマーゲームをメインのディスプレイでやりながらPC作業もしたいなぁ。あとお絵描きもしたいなぁ」という感じのモチベでサブディスプレイ(液タブ)を買うか検討していたのですが、「手元のiPadがサブディスプレイになったら、ゲームもお絵描きもできるし完璧では?」と思い立って、10月半ばにLuna DisplayのHDMI版ドングルを買ってみました。

購入から一ヶ月くらい使ってみて、色々良いところ悪いところが見えたのですが、あまりレビュー等で書かれていないような内容だったので、自分で書いてみます。

※Luna DisplayはWiFi接続もサポートしてますが、我が家のWiFiはあんまりよろしくないので、基本的にUSB-Lightning接続で使っています。

 

良いところ

画質が良い!遅延が少ない!

これは公式でもアピールしてる部分ですが、Retina ResolutionをEnableにすると画質は素晴らしいです。普通にiPadの最大解像度で綺麗に見えます。

また、映像の遅延もメインディスプレイと比べて2F程度でほぼ気にならないレベルでした。

https://x.com/mogira_jubeat/status/1713782617508868271?s=20

https://x.com/mogira_jubeat/status/1713782617508868271?s=20

タッチ操作もApple Pencilも使える

これも公式でアピールしてる部分ですね。

ただ、Apple Pencilはmspaintで実験してみたところ正直お絵描きできるほどの反応速度ではないですね。(ちらっと適当に測った感じだと50msくらいです。)

遅延とか気にしないユースケースでタッチ操作したいだけなら問題はないですが、入力系の遅延はそこそこあるかなーという感じです。

なので、お絵描き用にWindowsで液タブ買おうと思っている人がこれで代替できるかというと微妙だと思います。素直に液タブ買うか、iPadで描いた方が良いと思います。

悪いところ

ここから長いです。

スタートアップ時に自動起動するオプションがない

スタートアップフォルダにショートカットをコピーしておいたら解決しましたが、個人的にはオプションで用意してほしかったですね。

接続が切れるタイミングが多い

接続中に急に途切れるという話ではなく、接続した状態でとあるアクションを行うと仕様的に必ず接続が切れるという話です。観測した限りでは以下の3つです。

  1. メインディスプレイの切断(接続先切り替えはOK)
  2. Windowsのロック
  3. iPadアプリの切り替え

1は表示モード:複製にしておいてメインディスプレイを別の映像入力に切り替えるのはOKみたいです。ただ、メインディスプレイの電源を落とせないので、夜寝る前に布団でiPadだけ~とかはできないですね。

そして2,3がかなりきついんですよね。。
2はよく使いますし、3は前述の通りWindowsでお絵描きは厳しいのでiPad側のお絵描きアプリに切り替えてお絵描きしようとすると、瞬時にというわけではないですが、しばらくしてLuna Displayアプリに戻ると切断されています。これが痛い……

再接続が面倒

初回接続時はまだいいんですが、上記1,2,3で切断した場合、iPadWindowsのアプリ再起動が必要になったり、最悪ドングルの再接続が必要になることがありました。

「なることがありました」と書いてますが、Windowsロックした場合はほぼ確実にどちらかのアプリを再起動する必要がありました。

ブラインドのままWindows側のロックを解除しても、上手く再接続されないことがあるのは痛いところです。

再接続後の設定が面倒

再接続が面倒とは言いましたが、再接続に伴って表示モードと拡大率の設定変更もしなくてはいけないので、これもかなり面倒です。

表示モード

表示モードはなぜか毎回『拡張』の状態で接続されます。毎回接続する度に『複製』に変更していますが一向に記憶されません。

しかも表示モードが『拡張』だと、ディスプレイの設定を変更しようとしてもプライマリディスプレイにしか設定ウィンドウが表示されないので、例えばメインディスプレイがプライマリでかつ既に別の接続先に切り替えていた場合、ブラインド状態でなんとかするか、再度メインディスプレイの接続先をPCに戻すみたいなことが必要です。控えめに言って最悪です。

一応複製モードへは、Win+Pの表示モード切り替えのポップアップを使うならWin+P→Tab→Home→↓キー→Enter、または『ファイル名を指定して実行』ダイアログを使ってWin+R→"DisplaySwitch /clone"と打つとブラインドでも切り替えられます。

拡大率

iPad接続時のLuna Displayの解像度は基本的にiPadの最大解像度になっていて、メインの4Kモニタと同じ拡大率だと細かすぎて見づらいので拡大率を上げたいところなんですが、メインディスプレイのみ使っているときは下げておきたいので、この辺の設定も毎回調整しています。
(メインのみ)150⇔(Luna)200~250%みたいな感じです。

 

という感じで、今のところサブディスプレイの代わりにも(Windows用の)液タブの代わりにもならないなぁというのが正直な感想です。

製品としては面白いですしスペック的にも十分だし、実際これで良いという人もいるとは思うんですが、個人的にはちょっと用途に合わないなぁという印象です。もう少し接続時のUXを上手いことしてくれると良いんですが。。

SEGGER emPower USB-Host+の紹介

これは何?

SEGGER社が開発したembOSというRTOSの上で動くemUSB-Hostという組み込み用のUSBプロトコルスタックを含むフレームワーク?の評価ボードみたいです。
簡単に言うとArduinoみたいな感じですね(全然違う)

開発元のSEGGERの日本国内代理店がEmbiTeKみたいです。私はEmbiTeKから2023年2月に¥4,290で購入しました。

このボードは呼び名がいっぱいあって正直よく分からないんですが、emPowerという評価ボードシリーズの廉価版がこれっぽいので、"emPower USB-Host+"というのが正式名称だと思っています。

開発はSEGGER Embedded Studioという専用のIDEで行い、書き込みとデバッグまでできます。

FWの更新はUSBメモリを使っても出来るらしいのですが、いまいちよく分からなかったので毎回IDEからコンパイルして書き込んでます。

電源&J-Link専用のMicroUSBポートと別で、USB 2.0のfull speed(12Mbps)とhigh speed(480Mbps)の2つのType-Aポートを備えています。ここにはUSBハブも繋げるようです。

LEDインジケータ

LED0~4の5つのLEDがユーザーからの任意操作が可能です。

(画像は公式ページより引用。LEDの配置を青枠で追記)

PWRのGreenLEDは電源投入中は常時点灯なので、ユーザー側からの操作は不可能です。

また、J-LinkのLEDもステータスインジケータになっているため、ユーザー側からの任意操作は不可能です。
J-Link LEDによるステータスの詳細はこちら。Bi-colorの方ですね → https://wiki.segger.com/UM08001_J-Link_/_J-Trace_User_Guide#Main_indicator

LED0&2 または 1&3 または(PWR Greenは常時点灯のため)4 を点灯させ、隣り合うGreen&Redを点灯させた状態にすると、Red LEDの影響でGreen LEDがOrangeに見えるので、実際はOrange&Redに見えます。

その他有用なリンク

よく公式のリンクが壊れてるので備忘録としてまとめておきます。

何ができるの?なんで買ったの?

USBホスト機能が使えます。

それだけならラズピコとかM5Stackとか色々選択肢はあるんですが、特筆すべき点としてAudio(USB Audio Class 1.0)を始めとした様々なデバイスクラスをデフォルトでサポートしています。
サポートしてるクラスドライバの詳細はこちら → emUSB-Host 対応クラスドライバ
また、こちらのリンク先にはサンプルが置いてあります → emUSB-Host Samples

USBホスト機能サポートと謳っててもデフォルトでサポートしてるのはキーボードやマウス等のHID程度なものが多く、特にオーディオサポートは探した限りこれしか見つかりませんでした。
さすがにオーディオのためだけに(raspi含めた)Linuxは使いたくないので、ワンボードなやつを探していました。

やりたかったのは、3.5mmでやり取りしてるアナログオーディオ信号をCreative BT-W3からBluetooth(aptX LL)で飛ばすことです。
スピーカーから出力してる音を、スピーカーとBTの両方で使えるようにしたかったんですよね。

一応調べたらそういう用途にピッタリなデバイスがプリンストンから出てるんですが、元々BT-W3はスマホに挿して使ってて、BTイヤホンの接続先切り替えって結構面倒だし、買うにも結構いい値段するし、BT-W3一個でどうにかなれ〜!というのが今回の主なモチベです。

なおCreative BT-W3は、ホストにUSBオーディオバイスとして接続され、ホストからUSBで受け取った音声信号をaptX LLやその他コーデックで圧縮してBluetoothで飛ばします。
なので、BT-W3経由で音声を飛ばしたいなら、まずはUSBホストとして音声データをUSBで渡せる必要があります。

実際に↑のやりたかったことは成功したので、その話はまた次回書きたいと思います。

今回はボードの紹介だけなのでこの辺で!

(この記事は、↑を3月に完成させたにも関わらず全然まとめ記事書く気が起きないまま半年以上経過したので、とりあえずボードだけでも紹介しておいて、本編を書くモチベを上げるための記事です。)

Arduino(for vscode)でM5Stack Core2の開発環境を整えようとしたら案外大変だった話

M5Stack Core2を買ったので、使いづらいArduino IDEを脱出して、Arduino for VSCodeで開発しようと思ったんですが、設定で結構手間取ったので、必要な項目をメモしておきます。

 

まず、Arduino IDEは普通のWindowsを入れましょう。Windows App版ではなくWindows版です。私はWindows App版を入れていたようなんですが、どうにもうまく設定できなかったので、Windows版を再インストールしました。
しなくてもいけたかもしれませんが、手元だとライブラリマネージャが使えなかったので諦めました。

 

VSCodeのsettings.jsonと<project>/.vscode/c_cpp_properties.jsonの設定

この辺が、調べれば調べるほど違う書き方が出てきて、よく分からなくなっていたところです。

(そもそも私がほぼvscodeを触っていなかったために勝手に混乱していたのですが)<project>/.vscode/c_cpp_properties.jsonはプロジェクト固有の設定で、settings.jsonは全体にかかる設定です。settings.jsonの設定を<project>/.vscode/c_cpp_properties.jsonオーバーロードしたり追加するような感じですね。

まず、VSCodeのsettings.jsonにはこの辺を書いておきましょう。

    "arduino.path""C:/Program Files (x86)/Arduino",
    "arduino.commandPath""arduino_debug.exe",
    "C_Cpp.intelliSenseEngine""Tag Parser",
    "C_Cpp.default.browse.path": [
        "${workspaceFolder}",
        "${config:arduino.path}/tools",
        "${config:arduino.path}/libraries",
        "${config:arduino.path}/tools",
        "${env:USERPROFILE}/Documents/Arduino/libraries"
    ]

arduino.pathとarduino.commandPathは設定必須ではないですが、その下のbrowse.pathの中で${config:arduino.path}と書くことで、arduino.pathを環境変数っぽく呼び出せるので、arduino.pathだけでも書いておくといいと思います。

また、browse.pathの最終行の${env:USERPROFILE}はお察しの通りWindows環境変数の%USERPROFILE%を呼び出しています。
Arduino用のライブラリはユーザーディレクトリ配下のドキュメント/Arduino/librariesに入っていたのでそこを指定しています。

この状態で一度.inoファイルを開いてArduino: Verifyを行うと、恐らく自動的に<project>/.vscode/c_cpp_properties.jsonが生成されます。

このままだと多分#include <M5Core2.h>がbrowse.pathにないとIntelliSenseが波線付けてくると思います。(IntelliSenseの話だけだとは思うのでコンパイルは通るかもしれません)

なので、波線の解決ヒントからIntelliSenseの構成画面を開き、構成名をArduinoに変更し、詳細設定の中の参照: パスのところに${default}と書いておきます。そうすると<project>/.vscode/c_cpp_properties.jsonが以下の内容になってると思います。

{
    "version"4,
    "configurations": [
...
        {
            "name""Arduino",
...
            "browse": {
                "path": [
                    "${default}"
                ]
            }
        }
]
}

ここまで書いておけば恐らくIntelliSenseやコンパイルで詰まることはないと思います。

シェルの設定ファイル読み込み順序についてメモ

bashrcとかbash_profileとかzshrcとかの話。

シェル起動時のプロファイルの読み込み時は大まかに『Interactive Shellかどうか』『Login Shellかどうか』によって分かれる。

bashzshの場合、以下のようなコマンドで挙動の確認ができる。
※ コマンドはbashで書いているが、zshも同様のオプション

  Login !Login
Interactive bash --login bash
!Interactive bash --login -c "" bash -c ""

 

ログを仕込んで実験してみたところ、bashzshでそれぞれ以下のようなログが得られた。

bash

# Login && Interactive
$ bash --login
/etc/profile
/etc/bash.bashrc
~/.bash_profile
~/.profile
~/.wsl_profile
~/.bashrc
~/.shrc
~/.wsl_shrc
~/.bash_aliases
~/.aliases
~/.wsl_aliases
# !Login && Interactive
$ bash
/etc/bash.bashrc
~/.bashrc
~/.shrc
~/.wsl_shrc
~/.bash_aliases
~/.aliases
~/.wsl_aliases
# Login && !Interactive
$ bash --login -c ""
/etc/profile
~/.bash_profile
~/.profile
~/.wsl_profile
# !Login && !Interactive
$ bash -c ""

zsh

# Login && Interactive
$ zsh --login
/etc/zsh/zshenv
~/.zshenv
/etc/zsh/zprofile
/etc/profile
~/.zprofile
/etc/zsh/zshrc
~/.zshrc
~/.shrc
~/.wsl_shrc
~/.zsh_aliases
~/.aliases
~/.wsl_aliases
~/.wsl_aliases:6: = not found
/etc/zsh/zlogin
~/.zlogin
# !Login && Interactive
$ zsh
/etc/zsh/zshenv
~/.zshenv
/etc/zsh/zshrc
~/.zshrc
~/.shrc
~/.wsl_shrc
~/.zsh_aliases
~/.aliases
~/.wsl_aliases
~/.wsl_aliases:6: = not found
# Login && !Interactive
$ zsh --login -c ""
/etc/zsh/zshenv
~/.zshenv
/etc/zsh/zprofile
/etc/profile
~/.zprofile
/etc/zsh/zlogin
~/.zlogin
# !Login && !Interactive
$ zsh -c ""
/etc/zsh/zshenv
~/.zshenv

 

詳細は後で。

色んな人のqmk_firmwareをGitでちゃんとまとめて管理する(改訂版)

先日、色んな人のqmk_firmwareをGitでちゃんとまとめて管理する - もぎらログを書いたところ、Twitterで色々コメントをもらったり教えてもらったりしたので、自分の手元でやり直しながら別記事で書き直してみました。
アドバイス頂いた瀬良さん(@shela_)とm.tei(@mtei)さんにはこの場を借りて感謝を申し上げます。

 

前回の反省&目標の再確認

まずは公式ドキュメントを読みましょう(自戒)。

やりたかったことは以下のページにほぼ書いてありますので、何はともあれこの1ページだけはとにかくちゃんと読みましょう。

https://docs.qmk.fm/#/ja/newbs_git_using_your_master_branch

 

あとはm.teiさんがQMKの追っかけ方やcontributionのやり方についてかなり詳しくまとめてくれていますので、興味がある方はこちらも参考にしてください。

qmk firmware の追いかけ方とプルリクのやり方 · GitHub

 

以上を踏まえて、私のやりたかったことを再確認しながらやってみます。

私がやりたかったのは『自分とその他キーボード作者のqmk_firmwareをローカルブランチとして切り替える』というものです。

前回は最初にQMK公式からcloneしたために、私が名前周りで混乱して、余計な設定がどんどん増えていきました。

(瀬良さんにも指摘頂きましたが)公式ドキュメントに書いてある通り、自分のリポジトリからcloneしてきて、そのままの設定を活かすようにしておくのが一番楽です。

なので、公式から自分のgithubにforkし、それをgit cloneしてきた場合は以下の2つの手順だけで私がやりたかった以下の図の状態が完成します。

  • QMK公式のqmk_firmwareをremoteとして追加
  • <任意の人>のqmk_firmwareをremoteとして追加&ローカルにcheckout

f:id:mogira_jubeat:20201024144446p:plain



 

実際のコマンドと解説

前回同様、実際のコマンドと共に説明していきます。今回は分かりやすいのでUMLはお休みです。

 

まずは自分のgithubからqmk_firmwareをgit cloneしてきます。
必要なブランチ(今回はmogidev)は適宜ローカルブランチを作成します。

$ git clone https://github.com/mogira/qmk_firmware.git
$ cd qmk_firmware
$ git switch -c mogidev origin/mogidev

 

次に公式のqmk_firmwareを、公式ドキュメントに書いてある通り、リモート名(?)upstreamとして追加します。
公式のmasterブランチは結構使うので、ついでにfetchだけしておきます。

$ git remote add upstream https://github.com/qmk/qmk_firmware.git
$ git fetch upstream master

なお、公式のqmk_firmwareは基本的に自分のmasterにpullするだけで、ローカルブランチとしてswitch -cする必要は(私には)無さそうなので、ローカルブランチは作ってません。

 

さらに前回抜けていたパートとして、任意のキーボード作者のqmk_firmwareも追加してみます。
今回は魔王様(@swan_match)のを例にやってみます(掲載許可済み)。

こちらはgit switchしてビルドしたりというのを想定しているので、必要なブランチは適宜fetchしてローカルブランチを作成します。

$ git remote add mao https://github.com/swanmatch/qmk_firmware.git
$ git fetch mao master
$ git switch -c mao-master mao/master

 

おしまい

はい、これで完了です。前回に比べてめちゃめちゃシンプルですが、本来この程度の内容でした。

普段主にpushするorigin/masterは、ブランチ名がそのままなのでpush.defaultの設定は不要です。
また、他人のgithubには許可を貰わないとpushできないらしいので、(githubを前提にするなら)基本的には誤pushを考慮したpush-urlの設定も不要らしいです。

 

今回色々やってみて、名前周りで混乱してたのとかがUML書いたら解消したり、アドバイスを貰って理解が深まったりしたので、書いて良かったなという感想です。

以上です。

色んな人のqmk_firmwareをGitでちゃんとまとめて管理する

改訂版を書きました。

https://mogira-jubeat.hatenadiary.org/entry/2020/10/24/172137


自作キーボードでよく使われるqmk_firmwareですが、キーボードの作者がforkしてQMK公式にmergeせず、個別に自分のリポジトリに持っていることがよくあります。

QMK公式にmergeするのって結構大変そうですし、他人のソースコードの管理に関してとやかく言う気はないですが、純粋にユーザーとして見ると、ほぼ同じソースコードを別のディレクトリで管理したり、新しくcloneしたらディレクトリ名変えてmake submodule~とかやってると「Gitとは…?」という気持ちが湧いてきます。

 

というわけで今回は『公式を含む色んな人のqmk_firmwareを、Gitの機能をちゃんと使ってまとめて管理しよう』という趣旨の記事です。

最終的に、色んな人のqmk_firmwareをブランチとしてgit switchで切り替えられるようになるのを目指します。また、ローカルに持ってきた時にmasterというブランチ名が被りまくって面倒なのでこの辺も弄って、あとは他人のリポジトリに誤pushしないように、とかも設定します。

私はあんまりGitに詳しくないので色々調べながらやってましたが、リポジトリとかブランチとかのremote/upstream/local辺りの話をちゃんと理解してる人なら悩むこともないと思います。(というか自作キーボードの人達はみんな既にやってそう……)

よく分からない人にはこの記事が分かりやすいです。

 

注:

この記事は『元々Gitはなんとなく使ってて、もう少しGitを便利に使ってみたくなった自作キーボード製作者』辺りを想定して書いていますので、比較的ハードルが高いと思います。
開発中のコードが消えても私は一切責任を取りません。自身が無い方は挑戦する前に必ずバックアップを取っておきましょう。

 

それではやっていきます。なお、執筆当時の私のGitはv2.28.0です。 

 

Part 1

まずは公式であるqmk/qmk_firmwareをcloneしてきて中に入ります。

$ git clone https://github.com/qmk/qmk_firmware.git
$ cd qmk_firmware

f:id:mogira_jubeat:20201013130323p:plain


次に「もう理解しないままgit pullなんてしないぞ!」という強い意志と共にqmk/qmk_firmwareをoriginの座から引きずり下ろします。※この操作後もgit pullは普通にできます。
リモート名(originとかのことって何て呼ぶんですかね?)は、origin改めofficialとでもしておきましょう。

$ git remote
origin
$ git remote rename origin official
$ git remote
official

f:id:mogira_jubeat:20201013130520p:plain



ついでにローカルのmasterというブランチ名が非常にややこしいので、QMK公式のmasterなのでofficial_masterとでも変えておきます。

$ git branch
* master
$ git branch --move master official_master
$ git branch
* official_master

f:id:mogira_jubeat:20201013130645p:plain



ここに自分のgithubリポジトリ(mogira/qmk_firmware)を新しくリモートリポジトリとして追加します。リモート名(?)はmogiraとでもしておきます。

$ git remote
official
$ git remote add mogira https://github.com/mogira/qmk_firmware.git
$ git remote
official
mogira

f:id:mogira_jubeat:20201013130946p:plain


この状態でgit fetch --allしてからbranchを一覧すると、official(qmk/qmk_firmware)とmogira(mogira/qmk_firmware)に含まれる全branchが表示されます。

$ git fetch --all
$ git branch --all
remotes/mogira/~
...
remotes/official/~
...

f:id:mogira_jubeat:20201013131434p:plain



ここまで来たら、弄りたいブランチをローカルにswitch -c(checkout -b)しましょう。ここではmogira/masterをmogira_masterというブランチ名でswitch -cします。

$ git branch
* official_master
$ git switch -c mogira_master mogira/master
$ git branch
* mogira_master
  official_master

f:id:mogira_jubeat:20201013131637p:plain



↑でgit switch -cしたときに上流ブランチ(upstream branch)を指定しているので、git branch -vvで確認してもmogira_masterにはきちんと上流ブランチが設定されていると思いますが、この段階のmogira_master上で何気なくgit pushしようとすると「上流ブランチとブランチ名が違うよ!」と怒られてpushできないはずです。
これはGit 2.0からpush.default(push時のデフォルト動作に関する設定項目)のデフォルト値が"simple"(設定されている上流ブランチと現在のブランチ名が合っているときのみpush)になっているのが原因なので、これを"upstream"(ブランチ名をチェックせずに、設定されている上流ブランチにpush)に変更します。

$ git branch -vv
* mogira_master ~ [mogira/master] ~~
  official_master ~ [official/master] ~~
$ git push
fatal: The upstream branch of your current branch does not match the name of your current branch.
...
$ git config push.config upstream
$ git push
Username for 'https://github.com': mogira
Password for 'https://mogira@github.com':
Everything up-to-date

 

↑で設定したpush.defaultはこのgit全体にかかってしまっています。この設定を忘れて他人のリポジトリに誤pushすると辛いので、pushする予定のないリモートリポジトリはpush時のurlを適当な値(↓の例では"no-push")に変更しておきます。こうすることで間違って他人のリモートリポジトリを指定したままpushしても、エラーになるだけで済みます。

$ git remote -v
mogira  https://github.com/mogira/qmk_firmware.git (fetch)
mogira  https://github.com/mogira/qmk_firmware.git (push)
official        https://github.com/qmk/qmk_firmware.git (fetch)
official        https://github.com/qmk/qmk_firmware.git (push)
$ git remote set-url --push "no-push"
$ git remote -v
mogira  https://github.com/mogira/qmk_firmware.git (fetch)
mogira  https://github.com/mogira/qmk_firmware.git (push)
official        https://github.com/qmk/qmk_firmware.git (fetch)
official        no-push (push)
$ git switch official_master
$ git push -v
Pushing to no-push
fatal: 'no-push' does not appear to be a git repository

f:id:mogira_jubeat:20201013131911p:plain


 

最後に、push-urlを変更したリポジトリに対してもgit fetch/pullは可能なことと、自分のリポジトリに対しては問題なくgit push/fetch/pullができることを確認しておきましょう。

$ git switch official_master
$ git fetch -v
From https://github.com/qmk/qmk_firmware
...
$ git pull -v
...
From https://github.com/qmk/qmk_firmware
...
$ git switch mogira_master
$ git push -v
Pushing to https://github.com/mogira/qmk_firmware.git
Username for 'https://github.com': mogira
Password for 'https://mogira@github.com':
To https://github.com/mogira/qmk_firmware.git
 = [up to date]          mogira_master -> master
updating local tracking ref 'refs/remotes/mogira/master'
Everything up-to-date
$ git fetch -v
From https://github.com/qmk/qmk_firmware
...
$ git pull -v
...
From https://github.com/qmk/qmk_firmware
...

 

というわけで完成です。

これで、git switchで色んな人のqmk_firmwareを切り替えられて、自分のブランチにswitchした後pushすればいつも通り自分のリポジトリに反映でき、他人のリポジトリには操作を間違えてもpushされない状態にできました。あとは適宜ブランチを切り替えて使えばいいと思います。

分かってる人なら.git/configを直接エディタで編集しても良いのですが、説明が面倒なので今回は全部コマンドでやりました。一応以下に全コマンド打ち終わった後の.git/configを置いておきますので、設定漏れのチェックにでも使ってください。

[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "official"]
	url = https://github.com/qmk/qmk_firmware.git
	fetch = +refs/heads/*:refs/remotes/official/*
	pushurl = no-push
[branch "official_master"]
	remote = official
	merge = refs/heads/master
[remote "mogira"]
	url = https://github.com/mogira/qmk_firmware.git
	fetch = +refs/heads/*:refs/remotes/mogira/*
[branch "mogira_master"]
	remote = mogira
	merge = refs/heads/master
[push]
	default = upstream

 

Part 2

Twitterで「私はこんな感じで管理してるよ」というのを教えてもらったので、紹介してみます。

f:id:mogira_jubeat:20201014080241p:plain

私のと違う点を挙げてみます。

  1. qmk/masterをローカルにcheckoutしていない
  2. masterブランチは自分のリポジトリのmasterを指すようにして、その他のリポジトリでmasterがあっても、別の名前でcheckoutする
  3. masterブランチは基本的にqmk/masterをmergeするためだけに使う
  4. 編集/開発作業は開発用のブランチ上(↑では適当にhogeとしている)で行う

まず1ですが、実は私の方でも要りません。なぜPart 1でわざわざ作ってたかというと、qmkと自分以外のレポジトリから持ってくることも想定して、"<remote name>_<branch name>"というローカルブランチの命名規則を説明するために、敢えてcheckoutしていました。

次の2がシンプルで良いなと思ったのでこれを紹介するに至りました。
私はこの作業をやり始めた時に「今ローカルにあるmasterってどこのリモートリポジトリのmasterだ!?」と混乱したので、Part 1のやり方をやって頭を整理してましたが、2の案を採用すると、ローカルブランチ名がmasterになるので、push.defaultについて特別な設定をする必要がなくなります。

3,4は割と当たり前というか、よく見かけるGitのワークフローです。私は全然理解していないので各自git-flowとかGitHub Flowとかでちゃんと調べて欲しいのですが、てきとーに説明すると『masterブランチというのは即時利用可能な状態にしておくべきなので、masterブランチには開発中のコードのコミットを入れずに、別途開発用のブランチを作れ』という運用のルールがあります。私は(小規模開発で使うくらいならいいんじゃないの…)とか思ってしまっているので、多分ちゃんと理解できていないです。

※ 3,4 については「masterブランチには直接コミットするな。別に開発ブランチを作れ」(意訳)というQMK公式の運用ルールがありました。なお、qmk/developブランチはQMKコアへの破壊的な変更を含むPRを投げるためのブランチらしいので、個人の開発用ブランチ(図中のhogeブランチ)はdevelop以外の名前が良いそうです。

あとは、他人のGitHubリポジトリはそもそもPermissionをもらわないとPushできないので基本的には誤Pushは気にしなくていいそうです。私も試したことはなかったので予防策として設定していましたが、無くても良さそうですね。

 

おしまい

そういえばTwitterで別の方から言われてハッとしたのが、『そもそも自作キーボード界隈ってGitよく分からん人が結構いるから、こういう複雑なことすると事故るのでは?』という懸念です。言われてみれば、自作キーボード界隈はガリガリにコードを書いてGitをバリバリ使いこなす人から、「黒い画面いじるの怖いから、あのキーボードはやめて半田付けだけで作れるこっちのにしよ!」って人まで、幅広い層の人がいます。

そう考えると、(冒頭にも注意書きを追記しましたが)この記事は自作キーボード界隈では割とハードルが高いものかもしれません。普通に別ディレクトリで持っていれば安全なので無理にやる必要はないです。Gitは開発を便利にするためのものであって、Git自体が開発の足枷になるのであればやらない方がいいと思います。それこそGitの操作ミスって開発中のコードが消えたとか目も当てられないですからね……

あと、Part 2追加したときに「この図に至るまでのコマンド全部書こうか。でも元の図から移行するためのコマンドもあったほうが良いな。でも両方書くと混乱するかな…(私みたいに説明書読まない奴だと)事故るのかも…」みたいな葛藤があったので、コマンドの記載はやめました。必要なコマンド(ブランチ名の変更、リモート名?の変更等)は既に紹介しているので、話を理解してくれた人なら図を見て出来るでしょう……

MacOS Catalinaでislをダウングレードした話

 

概要

isl(Integer Set Library)のバージョンが0.22に上がってしまい、avr-gccが動かなくなった件についてサポートした際のログになります。

対症療法としてislを0.21にダウングレードすることにしましたが、私自身CatalinaどころかそもそもMacを触ったことが無いので、「Homebrewってなんだ」というところから勉強した次第です。とりあえず今の理解で記事を書いていくので間違ってたらご指摘いただけるとありがたいです。

なお今回やってもらった環境がCatalina 19C57(10.15.2)だったので、但し書きがない限りこのバージョンについての話です。

 

参考リンク

  1. Homebrewメモ - Qiita

  2. Homebrewで過去バージョンをインストールしたいぞ - Qiita

 

事の発端 ~QMKビルドできない~

qmk_firmwareに含まれるキーボードのFWをビルドしている最中に以下のようなエラーが発生しました。

Compiling: keyboards/hifumi/keymaps/test/keymap.c                                                  dyld: Library not loaded: /usr/local/opt/isl/lib/libisl.21.dylib
  Referenced from: /usr/local/Cellar/avr-gcc@8/8.3.0/libexec/gcc/avr/8.3.0/cc1
  Reason: image not found
avr-gcc: internal compiler error: Abort trap: 6 signal terminated program cc1
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
 [ERRORS]
 | 
 | 
 | 
make[1]: *** [.build/obj_hifumi_test/keyboards/hifumi/keymaps/test/keymap.o] Error 1
make: *** [hifumi:test] Error 1
Make finished with errors

これが今回問題のコアになっていたエラーです。hifumiというキーボードのFWのビルド中に出たエラーでしたが、他のキーボードでも同様のエラーが出ました。

メッセージを見る限り、コンパイル時にavr-gcc/usr/local/opt/isl/lib/libisl.21.dylibをロードしようとしているけど、ファイルが見つからないのでabortという状態のようです。

以下のコマンドで確認してもらったところ、確かにファイルがないです。というか明らかにバージョンが違いますね。

$ find /usr/local | grep libisl
/usr/local/lib/libisl.22.dylib
/usr/local/lib/libisl.a
/usr/local/lib/libisl.dylib
/usr/local/Cellar/isl/0.22/lib/libisl.22.dylib
/usr/local/Cellar/isl/0.22/lib/libisl.a
/usr/local/Cellar/isl/0.22/lib/libisl.dylib
/usr/local/Cellar/isl/0.22/share/gdb/auto-load/libisl.22.dylib-gdb.py

適当にシンボリックリンク貼ってあげれば良いのかなと思ったのですが、貼ってみても同じエラーでabortしました。

そんなことあるのかという感じですが、どうやらlibisl.21.dylibもといislの0.21しか受け付けないようです。brew upgradeした際にislのバージョンが上がってしまって、このような事態になったようです。avr-gccさんlibisl.dylib使ってくれたら良かったのでは?(素人並感)

初めはlibislのバージョンを指定している箇所がavr-gccにあるだろうしそこ直せばいいかなと思ったのですが、しばらく探しても見つからなかったので諦めてislをダウングレードすることにしました。

 

Homebrewについてのお勉強

Homebrewについて

HomebrewというのはMacOS向けのパッケージマネージャらしいです。ただ、標準で入っているものではなく、ユーザーがインストールして初めてbrewコマンドとして使えるようになるらしいです。詳しくは参考リンク1辺りを参考にしてください。

Formulaによるパッケージのバージョン管理について

Formulaはパッケージをインストール/アップグレード等するためのRubyスクリプトです。パッケージ名.rbの名前でどこかのディレクトリに置かれています。バージョンによって変わることがあるようです。
今回は/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/でした。

brew install パッケージ名と打つと、指定したパッケージのFormula(Rubyスクリプト)が走ってインストールが行われます。

また、このFormula達は上記パスのhomebrew-core以下をまとめるローカルなgitリポジトリでバージョン管理されています。

恐らくですが、brew updateするとこのリポジトリを通してFormulaが更新され、brew upgradeするとupgrade可能=インストールされているパッケージのバージョンが最新でないFormulaが走るようです。

それからこのhomebrew-coreリポジトリは『今まで更新を取得してきたログ』になっているようで、brew cleanupすると、このリポジトリの歴史が白紙に戻ります。
ただし既に更新されたFormula本体が消されるわけではなく、Formulaを更新してきた歴史のみが消えます。これは後ほど実ケースが出てきます。

 

本題 ~islのダウングレード~

さて本題のislのダウングレード方法です。

上で説明した通りbrew install時の一連のインストールコマンドは該当パッケージのFormulaに書いてあるので、ざっくり言うと『Formulaの内容を指定のバージョンへダウングレードした上でbrew install』してあげればダウングレードができます。

Formulaの内容を指定バージョンへダウングレードといっても、Formulaは所詮テキストなので、以下のどちらかの操作で十分です。

  • git checkout 指定バージョンのコミット 該当Formula
  • 指定バージョンのFormulaの内容をどこかから拾ってきてローカルのFormulaにコピペする

前者の手法の場合は、git log 該当Formulaすると該当Formulaの歴史が辿れるので、問題のあったバージョンの一つ前辺りのコミット番号を控えてgit checkoutすれば良いと思います。
ただし、上で少し説明したようにbrew cleanupしてしまうとFormulaに関する歴史が消えてしまうのでgit checkoutできなくなります。また、あくまでローカルなgitなので、次で出てくる公式リポジトリのコミット番号を入れても意味がないです。ローカルなgitというのは私の勘違いです。ローカルなgitリポジトリではありますが、以下の公式リポジトリとコミット番号が一緒だったので、公式リポジトリと繋がってはいるようです。単純に残っている分の歴史から消えてしまっているからgit checkoutできないようです。

2の手法はとても簡単です。以下に公式リポジトリがあり、Formulaの更新履歴を作ってくれてるので、ここから指定バージョンのFormulaの中身を拾ってきます。

GitHub - Homebrew/homebrew-core: 🍻 Default formulae for the missing package manager for macOS

このリポジトリはファイルのHistoryとかがうまく表示されないようなので、手元にgit cloneしてあげないとダメそうですね。

isl 0.21のlatestのFormulaは以下のものなので、この内容をローカルのislのFormulaにコピペしてあげます。

homebrew-core/isl.rb at 5784f67552d1b73f404d88504209578a8d388ac0 · Homebrew/homebrew-core · GitHub

これでダウングレードの準備は整ったので、あとは参考リンク2にある通り、以下のコマンドでインストールします。

$ brew unlink isl
$ HOMEBREW_NO_AUTO_UPDATE=1 brew install isl

※HOMEBRE_NO_AUTO_UPDATEなくてもいいかなと思ったのですが、brew updatebrew install前に走って、Formulaが更新されたら水の泡なので付けておきましょう

さてこれでインストールされたはずです。成功していると以下のコマンドで以下のような出力が得られるらしいです。

$ brew info isl
isl: stable 0.21 (bottled), HEAD [pinned at 0.22]
Integer Set Library for the polyhedral model
https://isl.gforge.inria.fr
/usr/local/Cellar/isl/0.21 (72 files, 4.3MB) *
Poured from bottle on 2020-01-01 at 01:30:43
/usr/local/Cellar/isl/0.22 (72 files, 4.7MB)
Poured from bottle on 2019-12-31 at 12:51:27
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/isl.rb
==> Dependencies
Required: gmp ✔
==> Options
--HEAD
Install HEAD version
==> Analytics
install: 51,824 (30 days), 174,648 (90 days), 700,354 (365 days)
install-on-request: 578 (30 days), 1,413 (90 days), 7,621 (365 days)
build-error: 0 (30 days)
$ find /usr/local | grep libisl
/usr/local/lib/libisl.a
/usr/local/lib/libisl.21.dylib
/usr/local/lib/libisl.dylib
/usr/local/Cellar/isl/0.22/lib/libisl.22.dylib
/usr/local/Cellar/isl/0.22/lib/libisl.a
/usr/local/Cellar/isl/0.22/lib/libisl.dylib
/usr/local/Cellar/isl/0.22/share/gdb/auto-load/libisl.22.dylib-gdb.py
/usr/local/Cellar/isl/0.21/lib/libisl.a
/usr/local/Cellar/isl/0.21/lib/libisl.21.dylib
/usr/local/Cellar/isl/0.21/lib/libisl.dylib
/usr/local/Cellar/isl/0.21/share/gdb/auto-load/libisl.21.dylib-gdb.py

 

おわりに

はい、これでislのダウングレード完了です。QMKのビルドも通るようになってると思います。
dylibのパスが違う?細かいことは気にしたら負けです。ライブラリとしてパスが通ったところに置いてあればいいんじゃないでしょうか(思考停止)。

本当は直るまでislのバージョン固定とかbrew switchの挙動確認とかやりたいんですが、手元にMacがないので細かい挙動確認もできずぐぬぬな感じではありますが、まぁ目的は達成したので良しとしましょう。

なおこの『Mac上でislを最新版(0.22)にするとavr-gccがエラーを吐く件』については、QMKでよくお世話になっているdrashnaさんが、avr-gccのFormulaリポジトリにIssueを上げてくれています。そのうち直ると思うので気長に待ちましょう。直ったようです。公開前夜にFormulaのgit辺りの勘違いに気づいてお恥ずかしい限りですが、これはこれで誰かの勉強になるかもしれないのでそのまま残しておきます。

何かあればこちらのコメントかTwitterの方までお願いします。