Mozcをオフラインでビルドするには?
Bazelでネットワーク接続なしでビルドする。
repository_cacheを用いる場合
- 事前にMozcソースと依存関係があるモジュールなどを用意しておきます。
-
Mozcソースの準備
Ibus-Mozcのみでいい場合git clone --filter=tree:0 https://github.com/google/mozc
Fcitx5-Mozcも必要な場合。
git clone --filter=tree:0 https://github.com/fcitx/mozc
cd mozc/src git submodule update --init cd ../..
-
Bazel-central-registryの用意
git clone --filter=tree:0 https://github.com/bazelbuild/bazel-central-registry.git bcr
-
モジュールのダウンロード
--repository_cache=$BASE/bazel-cache
フォルダにビルドに必要なファイルがダウンロードされます。
bazel build --nobuild --build_event_json_file=bep.json --experimental_repository_resolved_file=resolved.bzl
オプションを使って、ビルドに必要な依存モジュールなどの情報を集めます。
bazel build --nobuild
の前に、bazel clean --expunge
を実行して、キャッシュを削除しておきましょう。export BASE=$PWD cd mozc/src bazel clean --expunge
Ibus-Mozcの場合
_BUILD_TARGETS="package"
Fcitx5-Mozcの場合
_BUILD_TARGETS="unix/fcitx5:fcitx5-mozc.so server:mozc_server gui/tool:mozc_tool"
ビルドに必要な情報を集めます。あとでスクリプトで同じことを実行するので、ここでは参考として、コマンドラインの提示のみ。
bazel build --nobuild --build_event_json_file=$PWD/bep.json --experimental_repository_resolved_file=$PWD/resolved.bzl --repository_cache="$BASE/bazel-cache" --registry=file://$BASE/bcr --config oss_linux --config release_build $_BUILD_TARGETS
resolved.bzlファイルに詳細な情報が集まります。
-
郵便番号のアーカイブについて
更新されてチェックサム(SHA256)が変更されているかもしれないので、それをチェックしてパッチを更新します。
以下のスクリプトで、bazel build --nobuildコマンドで情報を収集して、resolved.bzlが生成されます。
その後、それを加工してresolved.jsonファイルと、更に加工されて、mozc-deps.yamlが作成されます。
mozc-deps.yamlのSHA256を更新し、zip-code.patchのチェックサム値(SHA256)も更新されます。cd $BASE wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/update-sha256.sh wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/resolved.jq wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/update_mozc_zip_code_patch wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/zip-code.patch _MOZC_BAZEL_CACHE="$BASE/bazel-cache" _BUILD_TARGETS=${_BUILD_TARGETS} bash update-sha256.sh --registry=file://$BASE/bcr
-
ビルドチェック
その後、ネットワークなしで、ビルドできるか試します。
bazelのキャッシュを削除して、ネットワークを遮断して試しましょう。
--repotitory_cache=$BASE/bazel-cache --registry=file://$BASE/bcr
がポイントです。bazel clean --expunge cp -a $BASE/bazel-cache $BASE/bazel-cache-backup patch -p2 -i ../../zip-code.patch bazel build --config oss_linux --config release_build $_BUILD_TARGETS --repotitory_cache=$BASE/bazel-cache --registry=file://$BASE/bcr
ビルドできたなら、ビルドする前の
$BASE/bazel-cache-backup
フォルダとbazel central registry
のファイル群を、Mozcのソースとともにアップロードできれば、ビルド可能ということになります。
手順の概略は、こんな感じです。
distdirオプションを用いる場合
レポジトリキャッシュそのままではなくて、モジュールのアーカイブを纏めていても可能です。
その場合には、distdir
オプションを使います。
ますはモジュールのURL情報を整理します。
-
依存モジュールの情報の整理
下記の手順は、スクリプトのupdate-sha256.sh
で一通り行われています。
sedコマンドでresolved.bzrを加工してjqコマンドで処理しやすくします。cd $BASE wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/resolved.jq sed -e 's/^resolved = //' -e 's/ False/ "False"/g' -e 's/ None/ "None"/g' resolved.bzl > resolved.json jq -r -f resolved.jq resolved.json > mozc-deps.json yq -y "." mozc-deps.json > mozc-deps.yaml
resolved.jqをダウンロードしない場合
jq -r '[ .[] | select(.repositories != null) | .repositories[] | select(.attributes.name != null) | select(.rule_class != null) | { url: ( if .attributes.url == "" then ( .attributes.urls[0] // "") else (.attributes.url // (.attributes.urls[0] // "")) end ), sha256: ( .attributes.sha256 // "" ), downloaded_file_path: ( .attributes.downloaded_file_path // null ), } | select(.url != "") | { type: "file", url: .url, dest: "bazel-deps", } + ( if .downloaded_file_path != "" and .downloaded_file_path != null then { "dest-filename": .downloaded_file_path, } else {} end ) + { sha256: .sha256, } ]' resolved.json > mozc-deps.json yq -y "." mozc-deps.json > mozc-deps.yaml
mozc-deps.jsonファイルに必要なモジュールのURLが集まりました。
-
依存モジュールのダウンロード
distdirオプション用にダウンロードして、一つのフォルダに纏めておきます。mkdir -p $BASE/bazel-deps cd $BASE/bazel-deps cp -a $_MOZC_BAZEL_CACHE/distdir/* ./ cat $BASE/mozc-deps.json |jq -r '.[]| ( if ."dest-filename" != null and ."dest-filename" != "" then "\(.url) -O \(."dest-filename")" else "\(.url) -O \(.url |split("/")|last)" end )'|xargs -n3 wget -nc
-
オフラインでのビルドチェック
そして、そのフォルダをdistdirで指定してビルドします。cd $BASE/mozc/src patch -p2 -i $BASE/zip-code.patch bazel build --config oss_linux --config release_build --linkopt "${LDFLAGS}" $_BUILD_TARGETS --distdir=$BASE/bazel-deps --registry=file://$BASE/bcr/
distdirオプションは将来的になくなるかもしれないそうです。
それまでは、distdirオプションを利用するのが簡単そうです。
bcrフォルダの中身とbazel-depsフォルダにまとめたモジュールをMozcソースとともにアップロードできれば、--distdir
オプション,--registry
オプションを利用して、オフラインでのビルドが可能になると思います。
(まとめ)bzlmodを有効にした状態でのオフラインビルド
概略
- ソースファイルの準備
- bazel-central-registryの準備(bazel regitryオプション用)
- resolved.bzrから依存関係のモジュールの一覧を取得
- モジュールを一通りダウンロードしておく(bazel distdirオプション用)
- オフラインビルド
1. ソースファイルの準備。
依存モジュール解析のために、ソースを準備します。
export BASE=$PWD
git clone --filter=tree:0 https://github.com/fcitx/mozc
wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/update-sha256.sh
wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/resolved.jq
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/update_mozc_zip_code_patch
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/zip-code.patch
wget https://github.com/google/mozc/pull/1063.patch
cd mozc/src
git submodule update --init
bazel clean --expunge
patch -p2 -i $BASE/1063.patch
2. bazel-central-registryの準備
cd $BASE
git clone --filter=tree:0 https://github.com/bazelbuild/bazel-central-registry.git bcr
3. 依存ファイルの解析と情報の更新
resolved.bzlから、URL情報を収集します。
Fcitx5-Mozcの場合
export BASE=$PWD
cd mozc/src
export _BUILD_TARGETS="${_BUILD_TARGETS:-unix/fcitx5:fcitx5-mozc.so server:mozc_server gui/tool:mozc_tool}"
export _MOZC_BAZEL_CACHE="$BASE/bazel-cache"
郵便番号辞書の元データなどが、更新されてチェックサム(SHA256)が変更されているかもしれないので、それをチェックしてパッチを更新します。
resolved.bzlを元に、mozc-deps.yamlが作成されます。そしてmozc-deps.yamlのSHA256を更新し、zip-code.patchのチェックサム値(SHA256)も更新されます。
wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/update-sha256.sh
wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/resolved.jq
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/update_mozc_zip_code_patch
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/zip-code.patch
_MOZC_BAZEL_CACHE="$BASE/bazel-cache" _BUILD_TARGETS=${_BUILD_TARGETS} bash update-sha256.sh --registry=file://$BASE/bcr
4. 依存モジュールのダウンロード
ダウンロードして、一つのフォルダに纏めておきます。
mkdir -p $BASE/bazel-deps
cd $BASE/bazel-deps
cat $BASE/mozc-deps.json |jq -r '.[]| ( if ."dest-filename" != null and ."dest-filename" != "" then "\(.url) -O \(."dest-filename")" else "\(.url) -O \(.url |split("/")|last)" end )'|xargs -n3 wget -nc
5. オフラインビルド
ここからは、ネットワークを閉じても大丈夫です。
cd $BASE/mozc/src
patch -p2 -i $BASE/zip-code.patch
bazel build --config oss_linux --config release_build $_BUILD_TARGETS --distdir=$BASE/bazel-deps --registry=file://$BASE/bcr/
オフラインビルド その2
--experimental_downloader_configオプションの利用。
wengxtさんのPR #23での提案に基づいたものです。
このオプションを用いるとproxyサーバーを経由して、ダウンロードさせることができます。
簡易的なproxyサーバーのPythonスクリプトを用意して、中継させることで、URLやチェックサムなど、必要な情報が収集できます。
またローカルのフォルダに、URL名などを含んだ形でダウンロードさせることで、一覧作成が行いやすくなっています。
Fcitx5-Mozcでは、これだけで問題はないのですが、Ibus-Mozcの場合、アイコン名が複数同じファイル名のため、distdirオプション用に、保存先の名前まで反映することが必要になります。この部分はresolved.bzlのファイルから情報を持ってくることで対応しています。
これらのまとめた情報をもとに、proxyサーバーが保存したファイルを、bazel-depsフォルダにコピーしています。
概略
- bazel build --nobuildで情報収集
- 解析ファイル生成
- distdirオプション用のファイルの準備
- オフラインビルド
1. bazel build --nobuildで情報収集
ソースの準備は上記と同じなので、割愛します。
必要なファイルのダウンロード。
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/bazel_mirror.py
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/downloader.cfg
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/update_mozc_zip_code_patch
wget https://github.com/fcitx/flatpak-fcitx5/raw/refs/heads/master/zip-code.patch
Ibus-Mozcの場合
_BUILD_TARGETS="package"
Fcitx5-Mozcの場合
_BUILD_TARGETS="unix/fcitx5:fcitx5-mozc.so server:mozc_server gui/tool:mozc_tool"
--experimental_downloader_config --experimental_repository_resolved_file --registry オプションを使用します。
BASE=$PWD
_DOWNLOADER_CACHE="$BASE/downloader_cache"
pushd .
mkdir -p $_DOWNLOADER_CACHE
cd $_DOWNLOADER_CACHE
python $BASE/bazel_mirror.py &
popd
pushd .
cd mozc/src
bazel build --nobuild --experimental_downloader_config=$BASE/downloader.cfg --registry=file://$BASE/bcr --build_event_json_file=$BASE/bep.json --experimental_repository_resolved_file=$BASE/resolved.bzl --repository_cache="$_MOZC_BAZEL_CACHE" --config oss_linux --config release_build $_BUILD_TARGETS
popd
2. 解析ファイル生成
sed -e 's/^resolved = //' -e 's/ False/ "False"/g' -e 's/ None/ "None"/g' $BASE/resolved.bzl > $BASE/resolved.json
jq -r '[ .[] | select(.repositories != null) | .repositories[] | select(.attributes.name != null) | select(.rule_class != null) | { url: ( if .attributes.url == "" then ( .attributes.urls[0] // "") else (.attributes.url // (.attributes.urls[0] // "")) end ), sha256: ( .attributes.sha256 // "" ), downloaded_file_path: ( .attributes.downloaded_file_path // null ), } | select(.url != "") | { type: "file", url: .url, dest: "bazel-deps", } + ( if .downloaded_file_path != "" and .downloaded_file_path != null then { "dest-filename": .downloaded_file_path, } else {} end ) + { sha256: .sha256, } ]' $BASE/resolved.json > $BASE/mozc-deps.json
dest-filenameがすべてURLからダウンロードするファイル名と同じなら、下記の手順でもURL一覧を生成できます。
jq -r 'select(.id.fetch.url != null )|.id.fetch.[]|select( contains("http"))|.' $BASE/bep.json
プロキシーにダウンロードされたファイルを基にして、mozc-deps.yamlを作成します。
pushd .
cd $_DOWNLOADER_CACHE
for f in `find -type f` ; do
if [[ ! "$f" =~ "./bcr.bazel.build/" ]];then
url="https://${f#*/}"
echo "- type: file"
echo " url: $url"
echo " dest: bazel-deps"
sha=`sha256sum $f|cut -f1 -d" "`
echo " sha256: $sha"
dest=$(jq -r '.[]|select(.url=="'$url'")|."dest-filename"' $BASE/mozc-deps.json)
if [[ "$dest" != "null" ]];then
filename=$(basename $url)
[[ "$dest" != "$filename" ]] && echo " dest-filename: $dest"
fi
fi
done > $BASE/mozc-deps.yaml
popd
yq -y -i 'sort_by(.url)' $BASE/mozc-deps.yaml
1-2の手順をまとめたスクリプト
wget https://github.com/phoepsilonix/flatpak-fcitx5/raw/refs/heads/test/update-sha256_.sh
./update-sha256_.sh
3. distdirオプション用のファイルの準備
proxyで保存されたフォルダにあるファイルを、dest-filenameがある場合は、その名前を、それ以外はそのままのファイル名でコピーしています。
cp -al
でハードリンクでコピーしています。
mkdir -p bazel-deps
jq -r '.[]| ( if ."dest-filename" != null and ."dest-filename" != "" then "\(.url) ./bazel-deps/\(."dest-filename")" else "\(.url) ./bazel-deps/\(.url |split("/")|last)" end )' $BASE/mozc-deps.json | sed 's|https://|"'$_DOWNLOADER_CACHE'"/|'|xargs -n2 cp -al
4. オフラインビルド
ここからは、ネットワークを閉じても大丈夫です。
cd $BASE/mozc/src
patch -p2 -i $BASE/zip-code.patch
bazel build --config oss_linux --config release_build $_BUILD_TARGETS --distdir=$BASE/bazel-deps --registry=file://$BASE/bcr/
備考
上記手順でもbazel-7.1.1では、ネットワークアクセスを要求されることを確認しました。
flatpak-builderで--sandbox
オプションでビルドした場合です。sandboxなのでbuild-argsに--share=network
は含まれません。
なおbazel-7.3.1では、同じ手順で問題がなかったので、flatpak版のbazelが更新されることが望まれます。bazelが更新されるまでは、若干依存ライブラリのバージョンなどが異なりますが、bazelのビルド時に--noenable_bzlmod
オプションを追加することも、一つの手ではないでしょうか?
bazel-7.1.1などでは、--noenable_bzlmod
オプションを情報の収集の時点と、ビルドの時点の両方で指定すれば、回避できるかもしれません。
追記:
10月2日時点で、bazel-7.3.2に更新されています。(メンテナに加わって、更新してもらいました。)
注意点
- ビルドする環境に、Fcitx5やQt6のライブラリがあることが前提です。
ビルド環境に、ライブラリがあるか確認しましょう。
pkg-config --cflags --libs Fcitx5Core Qt6Core
- distdirオプション
--distdir
オプションはdeprecatedとされているようで、bazel-7系ですでに廃止予定の機能らしいのですが、bazel-7.3.1でも、まだ使えているオプションです。
類似の機能が残されるのか、別途実装されるのかはわかりませんが、その時に類似の機能がない場合には、--repository_cache
オプションを使うことになりそうです。repository_cacheをそのまま送れない環境なら、関連ファイルを元にrepository_cacheをbazelの機能以外で、別のスクリプトなどで再構築することが必要になるかもしれません。内部的な決まり毎が整理されていたら、可能かもしれませんが、ちょっと大変そうですね。
ただ、まだ来ても居ないことを心配しても仕方がありませんし、その時にはその時で、古いバージョンのbazelでビルドができるのなら、先延ばしもできますから、慌てることはないでしょう。
関連PR
参考サイト
下記サイトのorg.fcitx.Fcitx5.Addon.Mozc.yamlの手順が参考になります。
flatpak-builderでsandbox(ネットワーク無し)でビルドする手順を構築されています。
その他、Mozc関連記事
大概のLinuxで使えそうな日本語入力(Flatpak版Fcitx5-Mozc)
UbuntuでMozcの新しいバージョンをビルドするには
DockerでビルドしたMozcをUbuntu 22.04 LTSにインストールする
Ubuntu 20.04 LTS/20.10でFcitx5を使用する
謝辞
PRにご対応くださった、Hiroyuki Komatsuさん、ありがとうございました。
macosなどでのビルド確認が出来ないので、閉じたほうが良さそうですね。
いろいろとご確認にお手間をとらせることになり、申し訳ありません。
Discussion