2022年1月19日水曜日

Yukari for Android をビルドしてみる

Windows 11 に Android アプリを実行する機能があるので、試しに Twitter/Mastodon クライアントである shibafu528/Yukari: Twitter/Mastodon Client for Android をビルドしてインストールしてみたいのだが、 Insider Program が必要のようだ。

メイン PC が Insider Program に入れないので試せないが、とりあえず APK をビルドするところまでやってみる。

前提

以下、インストール・設定済み。

  • OS: Windows 11 Pro 21H2 22000.434
  • Java: java version “1.8.0_201”
  • AndroidStudio: 2020.3.1 Patch 2
  • MSYS2 をインストールして、 sed.exe をパスにいれる
  • Docker: Docker version 20.10.12, build e91ed57

Yukari ビルドチャレンジ

ソース取得

git clone --recurse-submodules https://github.com/shibafu528/Yukari
cd Yukari

とりあえず gradlew build

> ./gradlew build
...(snip)
FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':gl-helpers'.
> SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at 'C:\Users\mikoto\project\Yukari\local.properties'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 1m 22s

…せやろな。 gl-helpers でエラー。環境変数 ANDROID_SDK_ROOT が必要なようだ。 追加して gradlew build

環境変数 ANDROID_SDK_ROOT を追加してビルド

> $Env:ANDROID_SDK_ROOT="C:\\Users\\mikoto\\AppData\\Local\\Android\\Sdk"
> ./gradlew build
...(snip)
> Task :twpfparser:test FAILED

info.shibafu528.twpfparser.TwiProfileImplTest > testGetTweetPerDay FAILED
    java.lang.AssertionError at TwiProfileImplTest.java:168

info.shibafu528.twpfparser.TwiProfileImplTest > testGetElapsed FAILED
    java.lang.NumberFormatException at TwiProfileImplTest.java:173

info.shibafu528.twpfparser.TwiProfileImplTest > testGetFavoritesCount FAILED
    java.lang.NullPointerException at TwiProfileImplTest.java:152

29 tests completed, 3 failed

> Task :Yukari:preAlphaDebugBuild FAILED

FAILURE: Build completed with 2 failures.

1: Task failed with an exception.

テスト失敗。とりあえずテスト無視してみようか。

テストをスキップしてビルド

> ./gradlew build -x test
...(snip)
> Task :gl-helpers:lint
Ran lint on variant debug: 1 issues found
Ran lint on variant release: 1 issues found
Wrote HTML report to file:///C:/Users/mikoto/project/Yukari/gl-helpers/build/reports/lint-results.html
Wrote XML report to file:///C:/Users/mikoto/project/Yukari/gl-helpers/build/reports/lint-results.xml

> Task :Yukari:preAlphaDebugBuild FAILED

FAILURE: Build failed with an exception.
...(snip)

lint でもエラーになるっぽい。これも無視。

lint をスキップしてビルド

> ./gradlew build -x test -x lint
...(snip)
  Errors found:

  C:\Users\mikoto\project\Yukari\gl-helpers\build.gradle:9: Error: Google Play requires that apps target API level 26 or higher.
   [ExpiredTargetSdkVersion]
          targetSdkVersion 19
...(snip)

ターゲットは 26 以上にしないといけないらしい。

これリリース時はどうやっているんだろうか?

無心で置換。

targetSdkVersion26 に更新してビルド

sed.exe -i -e "s/targetSdkVersion 26/targetSdkVersion 19/g" gl-helpers/build.gradle

そしてビルド。

> ./gradlew build -x test -x lint
...(snip)
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':Yukari:preAlphaDebugBuild'.
> Could not resolve all files for configuration ':Yukari:alphaDebugCompileClasspath'.
   > Could not find info.shibafu528.yukari:yukari-exvoice:20210923.011845.
     Required by:
         project :Yukari
...(snip)

yukari-exvoice をビルドする必要があるようだ。

yukari-exvoice ビルドチャレンジ

Yukari/gradle.properties を更新してビルド

yukari-exvoicegradle.properties で、ビルドする・しないを切り替えられるようになっている。

sed.exe -e "s/yukari.exvoice.build=false/yukari.exvoice.build=true/g" gradle.properties

またビルド。

> ./gradlew build -x test -x lint
...(snip)
NDK is missing a "platforms" directory.
If you are using NDK, verify the ndk.dir is set to a valid NDK directory.  It is currently set to C:\Users\mikoto\AppData
\Local\Android\Sdk\ndk-bundle.
If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning.


FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':yukari-exvoice'.
> java.lang.NullPointerException (no error message)
...(snip)

oh… java.lang.NullPointerException (no error message)

yukari-exvoice, よく見ると、 Dockerfile とか入っているし、 Gradle とは別にビルド手順がありそう。

Docker 環境で yukari-exvoice をビルド

多分 Dockerfile で作ったイメージからコンテナ作って、その中で gradlew build する感じ。

cd yukari-exvoice
docker build -t mikoto2000/y4a-buildkit .

…これ Yukari 自体のビルドもこのコンテナでやっちゃえるのでは???

後で試す。

> docker run -it --rm --mount type=bind,source=$(pwd),target=/work --mount type=bind,source=$HOME/.gradle,target=/root/.gradle --workdir /work mikoto2000/y4a-buildkit ./gradlew build
...(snip)
FAILURE: Build failed with an exception.

* What went wrong:
Could not create service of type FileHasher using GradleUserHomeScopeServices.createCachingFileHasher().
> java.io.IOException: Input/output error
...(snip)

Windows のキャッシュが悪さしている???

Windows 側の .gradle のバインドを止めてみる。

あと、試行錯誤しそうなので bash でコンテナを起動。

> docker run -it --rm --mount type=bind,source=$(pwd),target=/work --workdir /work mikoto2000/y4a-buildkit bash

起動したコンテナ内でビルド。

# ./gradlew build
...(snip)
> Task :mrubyBuild FAILED
build: [exec] ./bootstrap
./bootstrap: 3: exec: autoreconf: not found
rake aborted!
./bootstrap failed
...(snip)

autoconf をインストールして再挑戦。

# apt-get install -y autoconf
# ./gradlew build
configure.ac:56: error: possibly undefined macro: AC_PROG_LIBTOOL
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.
autoreconf: /usr/bin/autoconf failed with exit status: 1

libtool をインストールして再挑戦。

apt-get install -y libtool
./gradlew build

ログとりわすれたが成功した。

Windows に戻ってビルド再挑戦

Docker コンテナでビルドしたビルド成果物を、 Windows のローカル Maven リポジトリへパブリッシュする。

> ./gradlew publishToMavenLocal
FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':yukari-exvoice'.
> java.lang.NullPointerException (no error message)

うーん?

コンテナに戻って publishToMavenLocal を試す。

# ./gradlew publishToMavenLocal
Configuration(s) specified but the install task does not exist in project :.

BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed

成功してしまった…。

こっちの成果物を Windows 側にコピーするか。

Windows 側で docker cp を実行。

> docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED          STATUS          PORTS NAMES
de2371b0e6d5   mikoto2000/y4a-buildkit   "bash"                   56 minutes ago   Up 56 minutes         elegant_merkle
> docker cp de2371b0e6d5:/root/.m2/repository/info/shibafu528 ${HOME}/.m2/repository/info/shibafu528

すでにビルド済みなので、 yukari-exvoice のビルドフラグを false に戻してビルド再挑戦。

> cd ..
> sed.exe -i -e "s/yukari.exvoice.build=true/yukari.exvoice.build=false/g" gradle.properties

yukari-exvoice のバージョンが、ビルド年月日時分秒になっているので、 build.gradle 内のバージョン番号を修正。

> cd Yukari
> ls ${HOME}/.m2/repository/info/shibafu528/yukari/yukari-exvoice
> $EXVOICE_VERSION=$(ls ${HOME}/.m2/repository/info/shibafu528/yukari/yukari-exvoice)[0].Name
> sed.exe -i -e "s/20210923.011845/${EXVOICE_VERSION}/g" build.gradle
> cd ..
> ./gradlew build -x test -x lint
...(snip)
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':Yukari:preAlphaDebugBuild'.
> Could not resolve all files for configuration ':Yukari:alphaDebugCompileClasspath'.
   > Could not find info.shibafu528.yukari:yukari-exvoice:20220119.054547.
     Required by:
         project :Yukari
...(snip)

見つからないそうです。

Gradle のキャッシュは ~/.m2 じゃなくて ~/.gradle の中か…。

Gradle のローカルキャッシュへの Publish や参照の仕組みを調べるのが面倒だったので、とりあえず依存をファイルパスで指定するように修正。…負けた。

> sed.exe -i -e 's#implementation \"info.shibafu528.yukari:yukari-exvoice:\$exvoiceVersion\"#implementation files (\"../yukari-exvoice/build/outputs/aar/yukari-exvoice-release.aar\")#g' Yukari/build.gradle
> ./gradlew build -x test -x lint

Yukari/build/outputs/apk/stable/releaseYukari/build/outputs/apk/stable/debug に、 apk ファイルが生成されていた。

動作確認

adb コマンドで、デバッグ用 apk ファイルを実機にインストール。

> cd .\Yukari\build\outputs\apk\stable\release\
> ~\AppData\Local\Android\Sdk\platform-tools\adb.exe install .\Yukari-stable-debug.apk
Performing Streamed Install
Success

とりあえず、アカウント追加画面が表示されることを確認できた。

これ多分ルートの Yukari ディレクトリをコンテナにマウントして、全部 Linux 環境でビルドしていくのが楽で安定するとおもう。

以上。

参考資料

2022年1月15日土曜日

PowerShell で GitHub から最新リリースのタグ名を取得したい

GitHub の REST API / Releases / Get the latest release で取得した JSON のメンバ, tag_name から取得できる。

> $Owner="vim"
> $Repo="vim-win32-installer"
> $LatestVersion=$(Invoke-RestMethod "https://api.github.com/repos/$Owner/$Repo/releases/latest").tag_name
> echo $LatestVersion
v8.2.4092

以上。

参考資料

2022年1月2日日曜日

Vim のコマンドラインに入力したコマンドをヤンクしたい

掲題の通りのメモ。

手順

  1. コマンドラインモードで <CTRL-F> すると、コマンドラインウィンドウが開き、履歴表示される
  2. コマンドラインウィンドウは、普通のバッファと同じようにカーソル移動・ヤンクが可能なのでヤンクする
  3. <CTRL-C> で履歴の領域からコマンドラインへフォーカスが移る
  4. <ESC> でコマンドラインモードを抜け、元のバッファへ戻る
  5. p でペーストできる

コマンドラインウィンドウを閉じる方法はたくさんあるので、詳しくは参考資料を参照されたい。

参考資料