WPP
pipenv で setup.py のパッケージをインストールする方法

pipenv の仮想環境で setup.py をインストールする方法です。

KivyMD の最新を git から持ってくると setup.py でのインストールを求められますが、やり方を知らなかったのでメモします。

pipenv の公式に載っているのですが run pip install すればいいらしい。

$ pipenv run pip install -e .

ちなみに、git で取ってきた KivyMD の example を動作させるには、プロジェクトのルートで python example/xxx.py のように実行するか、PYTHONPATH に追加する必要がある。インストールしても仮想環境にコピーされないので注意。

ついでに requirements.txt でインストールする場合は以下のようになる

$ pipenv install -r ./requirements.txt

参考

pipenv · PyPI

kivymd/KivyMD: KivyMD is a collection of Material Design compliant widgets for use with Kivy

git のパスワードをキャッシュする

仕事先の環境からは ssh が通らないため、自宅 gitサーバ(forgejo) には https 接続している。

https/http 接続ではそのままだといちいちユーザーID、パスワードを聞いてきてなかなかしんどい。
なので、キャッシュ設定をする。

環境は linux です、mac や Windows は参考リンクに載ってます。

$ git  config credential.credntialStore plaintext

$ cat ~/.git-credentials
https://xxxxxxxx@xxxxxxx

参考

git パスワードを毎回聞かれる問題をHTTPSでも解決 #Git – Qiita
ここの git config credential.helper store も実行する必要があるかもしれない。

Caching your GitHub credentials in Git – GitHub Docs

git-credential-manager/docs/credstores.md at release · git-ecosystem/git-credential-manager

vscode Code Coverage プラグイン

前回は、coverage をタスクに登録して vscode から抜けずにカバレッジを計測できるようにしました。

ネット上では Covergage Gutters が人気のようですが、今回は「Code Coverage」というプラグインを使ってみます。見てみると lcov 形式をサポートする大体同じような感じのもののようです。

Code Coverage はインストールした後、settings.json に設定を記述する必要があります。

{
    ......
    "markiscodecoverage.searchCriteria": "*.lcov",
    "markiscodecoverage.enableOnStartup": true
}

serchCrieria で探すパスとファイルをしていします。今回は *.lcov としています。

enableOnStartup を true にしておくと自動起動するようです。

実行するとこんか感じでテストでカバーできていないコードに青波線が引かれます。

これでいい感じに進めそう。

vscode で unittest の coverage 計測するために task を使う

表題通りですみません。今、python でちょっとしたツールを作っているのですが、ユニットテストも書いています。世間では pytest が人気みたいですが、何もインストールしなくて良いという安直な理由で unittest を使っています。

vscode では unittest も認識してくれていい感じで discover でテストをたどってくれているようです。

ただカバレッジは計測できないようで、愚直にターミナルから実行するのも良いのですが、coverage のコマンドをいつも忘れてしまいます。

そこで、vscode の task 機能? で予めタスクを登録することにしました。

task 機能の説明は参考ページが詳しいです。が手順だけリストアップすると

タスクを登録するには

  1. Ctrl +p でコマンドパレット開く
  2. tasks: configure task
  3. 何か適当に選ぶと tasks.json が開く
  4. 追加したいタスクを記述する

こんな感じです。今回は、以下のコマンドを記述しました。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "echo Hello"
        },
        //  ここから追加
       //  カバレッジの計測
        {
            "label": "coverage",
            "type": "shell",
            "command": "coverage run --source . -m unittest discover",
            "options": {
                "cwd": "${workspaceFolder}"
            }
        },
        // lcov 形式に変換 (Code Coverage という vscode extension で使用するため)
        {
            "label": "coverage lcov",
            "type": "shell",
            "command": "coverage lcov",
            "options": {
                "cwd": "${workspaceFolder}"
            },
            "dependsOn": "coverage"
        }
    ]
}

今回は、計測のためのタスクと lcov に変換する 2つのタスクを登録しました。

タスクの実行

  1. Ctrl +p でコマンドパレット開く
  2. tasks: run task
  3. 実行したいタスクを選ぶ

これで面倒なく実行できる。

が、考えてみると makefile の方が楽な気もする。というのも tasks.json はワークスペースの .vscode に作成されるので個人的には git に入れず削除することが多い。悩ましい。

参考

【初心者でも分かる】VSCodeのtasks.jsonでタスク自動化する方法を解説 | Inno-Tech-Life

edk2 参考サイト

引き続き Mikan 本をやっているわけですが、edk2 のいいサンプルを見つけたのでメモ。

edk2 のセットアップの方法を解説したページは多くありますが、でどう書けばいいのよっていうサンプルはあまり見つかりません。

edk2 は、UEFI のための開発キットという位置づけなのですが、そのドキュメントには edk2 自身の使い方しか記述していません。UEFI は公式を見てねというスタンスになっているようです。

参考

Kostr/UEFI-Lessons: Lessons to get to know UEFI programming in Linux with the help of EDKII
ここのチュートリアルはわかりやすい

Specifications | Unified Extensible Firmware Interface Forum
UEFI 本家、仕様書をダウンロードできる。

FreeDict で英和、和英をターミナルで辞書引き

ふと英和辞書を引きたく状況になって、ちょっとブラウザで検索するの面倒と思い調べてみる。

どうやら FreeDict ってプロジェクトがあってそこの辞書を使えるらしい。(Ubuntu系のリポジトリには含まれると思う。)

$ sudo apt install dictd dict

; 英和辞書と和英辞書をインストール
$ sudo apt install dict-freedict-eng-jpn dict-freedict-jpn-eng

$ dict はてな
1 definition found

From Japanese-English FreeDict Dictionary ver. 0.1 [fd-jpn-eng]:

  はて /hˈäte̞/, はてな /hätˈe̞nä/
  1. (interjection (kandoushi))
  Dear me!, Good gracious!
  2. well ... (used before sentences expressing a doubt), let me see, now ...


; gui ツール
$ sudo apt install goldendict

ネット上の解説では dictd なしでも行けるっぽいことを見つけられるが、挙動の遅さからどうもインターネット上の辞書を検索しているっぽい。dictd をインストールするとローカルの辞書を引いてくるようだ。

GUI ツールは色々あるが goldendict がいいかもしれない。goldendict-ng というのもあって見た目はいい感じだが例題の 「はてな」が見つからない事例があった。一方の goldendict ではきちんと検索できたので一旦はこちらを使用することにしよう。

goldendict では検索結果を Favorites に保存できるのでそこが採用ポイント。

参考

dictd – ArchWiki
dict と dictd の使い方などがのっている。

Linux のコマンドラインでオフライン英和辞書 #Linux – Qiita
GENE95 という辞書テキストを shell から引く方法を解説している。

Documentation — FreeDict
FreeDictプロジェクトのサイト

Mikan 本の環境構築

先日の edk2 のエントリもそうだが、Mikan本 を今さらやっているところです。

本の通りに環境構築すれば何も難しいことはないのですが、フォルダ構成を好みな状態に変更するために行ったよもやまの記録です。。

環境構築で躓いたので3週間位経っているのに未だ 3 日目、4 日目あたりをうろうろしているがようやくスピードアップできそうだ。

Mikan 本からの変更点

  • edk2 は最新版(詳細は、前回のエントリ)
  • edk2 フォルダの配置先
  • day01 とかの日付で作業フォルダを区切っていく
  • devenv フォルダのスクリプトを makefile に直接書いていく

Mikan 本では、edk2 を ホームディレクトリ(~) に置いているのですが、自分としてはあまり好みでないのでプロジェクトフォルダ内に配置するようにした。

というのも、 github から取ってきた os のソースファイルは checkout して作業時点の日付を切り替えるようになっている。このスタイルだととても変更作業がやりにくいのでローカルにスナップショットを残す形にしようと思う。

前回(前日)分の作業内容は残して参照しながら進めたいので、日付で作業フォルダを区切ってその中からビルドできるようにしていく。それにともなって MikanLoader も日付フォルダの中に入れ込むことにした。

devenv フォルダのスクリプトの分割のしかたが自分にはどうしてもすっと入ってこないので、いっそ makefile に直接書いていくことにした。

まとめるとプロジェクトフォルダはこんなイメージになる。

  • [プロジェクトフォルダのトップ]
    • env フォルダ ひとまず、 .fd だけ置いている。
    • edk2 フォルダ
    • day03 のような日付フォルダ
      • MikanLoader03Pkg フォルダ
      • … その他

ちょうど kernel フォルダが新たに登場したのでそのうち追加しようと思う。後ろの章に進むとフォントファイルや画像リソース、newLib が追加されるようだが、それはまたその時考える。ことにする。

MikanLoaderPkg

Mikan 本では、UEFI で動く bootloader を MikanLoader と呼んでいるが、本の中では、プロジェクトフォルダの MikanLoaderPkg フォルダを edk2 フォルダ内にリンクすることで edk2 のビルドを実行するようにしている。

今回は本と異なり、day03 等の日付名のフォルダで作業をしたいので MikanLoader03Pkg のように日付の数字を埋め込んで名前の衝突を回避することにした。

それに伴い、 Mikanloarder の MikanLoader.dsc を書き換える必要がある。

6 行目: ビルド出力先を指定し直している。
23 行目: 最新の edk2 に対応するために追加。
26 行目: 使用する Loader.inf を指定している。

[Defines]
PLATFORM_NAME           = MikanLoaderPkg
PLATFORM_GUID           = 1b6bbd8c-686c-11ef-b861-b30cfa469952
PLATFORM_VERSION        = 0.2
DSC_SPECIFICATION       = 0x00010005
OUTPUT_DIRECTORY        = Build/MikanLoader03$(ARCH)
SUPPORTED_ARCHITECTURES = X64
BUILD_TARGETS           = DEBUG|RELEASE|NOOPT

[LibraryClasses]
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf

BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf

[Components]
MikanLoader03Pkg/Loader.inf

[Components] 節は注意が必要だ。どうも Components で指定されたものがパッケージに含まれるようなしくみらしく、MikanLoader.dsc が他のフォルダの Loader.inf を読み込んでもビルドは問題なく通る。
この場合だとビルドされるソースは他のフォルダのものが MikanLoader03Pkg として生成される。

はじめこのことに気づかず、もともの MikanLoaderPkg の挙動になってしまい原因究明に時間がかかった。

また、Loader.inf も最新の edks2 を使うために変更している。RegisterFilterLib が必要なので追加した。

[Defines]
INF_VERSION     = 0x00010006
BASE_NAME       = Loader
FILE_GUID       = c9d0d202-71e9-11e8-9e52-cfbfd0063fbf
MODULE_TYPE     = UEFI_APPLICATION
VERSION_STRING  = 0.2
ENTRY_POINT     = UefiMain

# VALID_ARCHITECTURES = X64

[Sources]
Main.c

[Packages]
MdePkg/MdePkg.dec

[LibraryClasses]
UefiLib
UefiApplicationEntryPoint
RegisterFilterLib

[Guids]
gEfiFileInfoGuid

[Protocols]
gEfiLoadedImageProtocolGuid
gEfiLoadFileProtocolGuid
gEfiSimpleFileSystemProtocolGuid

makefile

本で進められる 環境では、 devenv フォルダに必要なスクリプトが全部入っている形になっている。が、makefile に書き直している。読み取って書き直す時間はかかるが、この方が自分には何をやっているか理解できるのであえてそうしている。

3日目の時点で使用できる makefile はこんな感じになる。

PWD 		:=$(shell pwd)
MNT_POINT	:=mnt
DISK_IMG	    :=disk.img
EDK_DIR		:=../edk2
EDK_OUT		:=Build/MikanLoader03X64/DEBUG_CLANGDWARF/X64/Loader.efi
ENV_DIR		:=../env  # 本でいうところの devenv フォルダ、ここに .fd がある。

CXXFLAGS	:=-O2 -Wall -g --target=x86_64 -ffreestanding -mno-red-zone -fno-exceptions -std=c++17
LDFLAGS		:=--entry KernelMain -z norelro --image-base 0x100000 --static


.PHONY: help
help:
	@echo "avilable targets"
	@echo "loader: build bootloader with edk2"
	@echo "kernel: build kernel"
	@echo "image: build bootddisk image"
	@echo "run: boot diskimage on QEMU"
	@echo "help: display this message"


# source edk2/edk-setup.sh はエラーになるので、予め実行する必要があるかも。
# ここの挙動はいまいちよくわかっていない。
.PHONY: loader
loader:
	ln -sf $(PWD)/MikanLoader03Pkg ../edk2
	cd $(EDK_DIR) && \
	# source edksetup.sh && \
	build -p MikanLoader03Pkg/MikanLoaderPkg.dsc && \
	cd $(PWD)

.PHONY: kernel
kernel:
	@echo "building kernel..."
	clang++ $(CXXFLAGS) -c main.cpp 
	ld.lld $(LDFLAGS) -o kernel.elf main.o

.PHONY: image
image: 
	mkdir -p $(MNT_POINT)
	sudo umount $(MNT_POINT) || :
	qemu-img create -f raw $(DISK_IMG) 200M
	mkfs.fat -n MIKAN -s 2 -f 2 -R 32 -F 32 $(DISK_IMG)
	sudo mount -o loop $(DISK_IMG) $(MNT_POINT)
	sudo mkdir -p $(MNT_POINT)/EFI/BOOT
	sudo cp $(EDK_DIR)/$(EDK_OUT) $(MNT_POINT)/EFI/BOOT/BOOTX64.EFI
	sudo cp kernel.elf $(MNT_POINT)/
	sleep 0.5
	# sudo umount $(MNT_POINT)


.PHONY: run
run:
	@echo "launch bootdisk on QEMU!!"
	qemu-system-x86_64 -m 1G \
	-drive if=pflash,format=raw,readonly=on,file=$(ENV_DIR)/OVMF_CODE.fd \
	-drive if=pflash,format=raw,file=$(ENV_DIR)/OVMF_VARS.fd \
	-drive if=ide,index=0,media=disk,format=raw,file=$(DISK_IMG) \
	-device nec-usb-xhci,id=xhci \
	-device usb-mouse -device usb-kbd \
	-monitor stdio

.PHONY: clean
clean:
	@echo "do cleaning"
	rm kernel.elf
	rm -rf $(EDK_DIR)/Build/MikanLoader03X64

使用するには、ひとつずつ手で実行していく必要がある。

; boot loader のビルド
$ make loader

;  kernel のビルド
$ make kernel

; イメージファイルの生成
$ make image

; qemu で実行
$ make run

この makefile は全然だめだめなのはわかっているが、ここからすこしずつ直していこうと思う。

ぼちぼち続けていきます。

edk2 の Emulator を動かす

だいぶ前に買った Mikan 本の OS開発をするにあたり、edk2 環境を作った。 とりあえずエミュレータを動かしてみた。本と異なり edk2 は最新のものでやってみることにした。

2025-1-28 追記: BaseTools をビルドする必要があったのでそれを追加。

環境
OS: Liux Mint 22 (upstream: Ubuntu24.02)
GCC: 13.2.0
edk2 は b437b5C (2024-9-7にこの記事は作成してます。)

; インストールとモジュールのアップデート
$ git clone https://github.com/tianocore/edk2
$ cd edk2
$ git submodule update --init --recursive

; エミュレータを動かすには lixb11-dev が必要らしい
 $ sudo apt install libx11-dev

; ビルド
$ source edksetup.sh

; まずは BaseTools をビルド
$ make -C BaseTools

; エミュレータビルド
$ build -p EmluatorPkg/EmulatorPkg.dsc  -t GCC -a X64 

; エミュレータの実行、Host があるディレクトリで実行する必要がある。oo
$ cd Build/EmulatorX64/DEBUG_GCC5/X64/
$ ./Host

build 実行時のパラメータは edk2/Config フォルダの target.txt に記述してもいい。

ACTIVE_PLATFORM    = EmulatorPkg/EmulatorPkg.dsc
TARGET_ARCH           = X64
TOOL_CHAIN_TAG    = GCC

TARGET_ARCH や TOOL_CHAIN_TAG は Conf デイレクトリの tools_def.txt に例があるのでそこから取ってくる。 以前までは TOOL_CHAIN_TAG に GCC5 を指定したようだが deprecate なので GCC となるらしい。(EmulatorPkg の Readme.md にあるのだが、GCC でないとビルドできないらしい。clang で頑張っても無駄なので素直に諦める。)

実行するには、Build ディレクトリに移動する必要があるようだ。

公式のやり方は、 build.sh run とかで実行できるとあるがオレカンでは何故か実行できないようです。

$ cd Build/EmulatorX64/DEBUG_GCC5/X64
$ ./Host

実行するとコンソールの画面出力がおかしくなるのでそこは注意。

これから Mikan 本をなぞっていくが TOOL_CHAIN_TAG CLANG8 から CLANGDWARF に変更するといいらしい。

参考

EmulatorPkg · tianocore/tianocore.github.io Wiki
– ここに、 Ubuntu の依存ライブラリの記述あり、 EmulatorPkg/build.sh run では動作しなかった。

edk2/EmulatorPkg at master · tianocore/edk2
– ここの起動方法に従うとと動作した。

EDK II (最新版) のツールチェーンに大幅な仕様変更が入っています · Issue #147 · uchan-nos/os-from-zero
– ここに Mikan 本での Toolchain についてのイシューレポートがある。

Android color int の色の並び

超小ネタです。

アンドロイドの UI で Color( 0xd0203040 ) となっていた場合の色の並び

ARGB の順に並んでいる A は透明度で基本 FF でもかまわないと思う。