aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroki Sato <hrs@FreeBSD.org>2026-10-19 06:05:27 +0000
committerHiroki Sato <hrs@FreeBSD.org>2026-10-19 06:05:27 +0000
commita6083c2eb06855592762f2ea2c3eb106faf3f18f (patch)
tree98971bf9ac2a250a8a32a1089f6bff97e9515f46
parent7e085b48a0cafb9b2c6e6ad66bc61f90a965b855 (diff)
japanese/mozc-server: Update from 2.23.2815.102.01 to 3.35.6354.101
- Adapt FreeBSD support and installation paths to the updated sources. - Use the base system's zlib and ports-provided Python, Qt 6, and input method framework libraries. - Add a static list of distfiles required by Bazel 9 to avoid network downloads during the build. - Update the IBus and uim frontends, and replace Fcitx 4 support with Fcitx 5. - Share icons installed by mozc-server with the input method frontends. - Fix Emacs input method registration and make mozc_emacs_helper available in PATH. This allows mozc.el from MELPA to work without additional configuration. - Update startup scripts, package messages, and license declarations. - Preserve license texts and copyright notices for bundled components.
-rw-r--r--MOVED1
-rw-r--r--japanese/Makefile2
-rw-r--r--japanese/fcitx-mozc/Makefile13
-rw-r--r--japanese/fcitx5-mozc/Makefile11
-rw-r--r--japanese/ibus-mozc/Makefile4
-rw-r--r--japanese/ibus-mozc/files/pkg-message.in17
-rw-r--r--japanese/mozc-el/pkg-message23
-rw-r--r--japanese/mozc-server/Makefile574
-rw-r--r--japanese/mozc-server/distinfo86
-rw-r--r--japanese/mozc-server/files/Makefile.bazel128
-rw-r--r--japanese/mozc-server/files/Makefile.distfiles204
-rw-r--r--japanese/mozc-server/files/bazel-fetch-log.py343
-rw-r--r--japanese/mozc-server/files/bazel-fetch-matrix.py222
-rw-r--r--japanese/mozc-server/files/bazel-versions.json22
-rw-r--r--japanese/mozc-server/files/bazel.python.BUILD.in22
-rw-r--r--japanese/mozc-server/files/bazel.zlib.BUILD13
-rw-r--r--japanese/mozc-server/files/bazel.zlib.MODULE6
-rw-r--r--japanese/mozc-server/files/extra-patch-src-MODULE-fcitx5.bazel19
-rw-r--r--japanese/mozc-server/files/extra-patch-src-MODULE-uim.bazel16
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.cc93
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.h60
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-mozc.cc238
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc-custom.scm47
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc.scm46
-rw-r--r--japanese/mozc-server/files/extra-patch-src-unix-uim-uim.gyp19
-rw-r--r--japanese/mozc-server/files/extra-src-unix-uim-BUILD.bazel37
-rw-r--r--japanese/mozc-server/files/leim-list.el22
-rw-r--r--japanese/mozc-server/files/mozc.in124
-rw-r--r--japanese/mozc-server/files/mozc_tool.in26
-rw-r--r--japanese/mozc-server/files/patch-src-.bazelrc13
-rw-r--r--japanese/mozc-server/files/patch-src-MODULE.bazel67
-rw-r--r--japanese/mozc-server/files/patch-src-base-cpu_stats.cc44
-rw-r--r--japanese/mozc-server/files/patch-src-base-file-recursive.cc29
-rw-r--r--japanese/mozc-server/files/patch-src-base-init_mozc.cc21
-rw-r--r--japanese/mozc-server/files/patch-src-base-password_manager.cc14
-rw-r--r--japanese/mozc-server/files/patch-src-base-port.h36
-rw-r--r--japanese/mozc-server/files/patch-src-base-process.cc57
-rw-r--r--japanese/mozc-server/files/patch-src-base-system_util.cc73
-rw-r--r--japanese/mozc-server/files/patch-src-bazel-cc_target_os-BUILD.bazel16
-rw-r--r--japanese/mozc-server/files/patch-src-bazel-pkg_config_repository.bzl36
-rw-r--r--japanese/mozc-server/files/patch-src-build_defs.bzl37
-rw-r--r--japanese/mozc-server/files/patch-src-client-client.cc20
-rw-r--r--japanese/mozc-server/files/patch-src-config.bzl29
-rw-r--r--japanese/mozc-server/files/patch-src-gui-config_dialog-config_dialog.cc46
-rw-r--r--japanese/mozc-server/files/patch-src-gui-config_dialog-keybinding_editor.cc31
-rw-r--r--japanese/mozc-server/files/patch-src-gui-word_register_dialog-word_register_dialog.cc14
-rw-r--r--japanese/mozc-server/files/patch-src-ipc-BUILD.bazel25
-rw-r--r--japanese/mozc-server/files/patch-src-ipc-ipc_path_manager.cc65
-rw-r--r--japanese/mozc-server/files/patch-src-ipc-unix_ipc.cc133
-rw-r--r--japanese/mozc-server/files/patch-src-unix-emacs-mozc.el16
-rw-r--r--japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.cc22
-rw-r--r--japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.h20
-rw-r--r--japanese/mozc-server/files/patch-src-unix-ibus-property_handler.cc11
-rw-r--r--japanese/mozc-server/files/patch-src-unix_emacs_mozc.el43
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary.cc11
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session.cc200
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session__test.cc62
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.cc195
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.h21
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage__test.cc188
-rw-r--r--japanese/mozc-server/files/patch-src_dictionary_user__dictionary__test.cc229
-rw-r--r--japanese/mozc-server/files/patch-src_gui_word__register__dialog_word__register__dialog.cc11
-rw-r--r--japanese/mozc-server/files/patch-src_prediction_gen__zero__query__data.py11
-rw-r--r--japanese/mozc-server/files/patch-src_prediction_user__history__predictor.cc63
-rw-r--r--japanese/mozc-server/files/patch-src_prediction_user__history__predictor.h19
-rw-r--r--japanese/mozc-server/files/patch-src_prediction_user__history__predictor__test.cc20
-rw-r--r--japanese/mozc-server/files/patch-src_rewriter_usage__rewriter__test.cc20
-rw-r--r--japanese/mozc-server/files/patch-src_unix_fcitx_eim.cc15
-rw-r--r--japanese/mozc-server/files/pkg-message-fcitx.in (renamed from japanese/fcitx-mozc/files/pkg-message.in)0
-rw-r--r--japanese/mozc-server/files/pkg-message-ibus.in27
-rw-r--r--japanese/mozc-server/files/pkg-message-uim.in33
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_build__mozc.py11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette.cc40
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette__table__widget.cc10
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_character__pad_unicode__util.cc41
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_character__form__editor.cc11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_config__dialog__libmain.cc10
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_generic__table__editor.cc11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_keybinding__editor.cc11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool.cc44
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool__libmain.cc10
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_qt__libraries.gypi13
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_qt__moc.gypi11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_qt__rcc.gypi11
-rw-r--r--japanese/mozc-server/files/qt6/patch-src_gui_qt__uic.gypi11
-rw-r--r--japanese/mozc-server/files/test-bazel-fetch.py158
-rw-r--r--japanese/uim-mozc/Makefile5
-rw-r--r--japanese/uim-mozc/files/pkg-message.in15
88 files changed, 3097 insertions, 1807 deletions
diff --git a/MOVED b/MOVED
index ecd3e011bd97..4f3829d1762e 100644
--- a/MOVED
+++ b/MOVED
@@ -5741,3 +5741,4 @@ www/npm-node20||2026-10-13|Removed, part of expired www/node20
devel/compiler-rt||2026-10-15|Now ships with the base system
textproc/py-pypa-docs-theme||2026-10-15|Has expired: Upstream archived the repo on Mar 16, 2024
www/py-wikitools||2026-10-18|Has expired: Not compatible with Python 3
+japanese/fcitx-mozc|japanese/fcitx5-mozc|2026-10-18|Deprecated: Use fcitx5 instead
diff --git a/japanese/Makefile b/japanese/Makefile
index de6f08e8eafb..33d5357584c0 100644
--- a/japanese/Makefile
+++ b/japanese/Makefile
@@ -48,12 +48,12 @@
SUBDIR += eijiro-fpw
SUBDIR += epwutil
SUBDIR += fcitx-anthy
- SUBDIR += fcitx-mozc
SUBDIR += fcitx-skk
SUBDIR += fcitx5-anthy
SUBDIR += fcitx5-cskk
SUBDIR += fcitx5-hazkey
SUBDIR += fcitx5-karukan
+ SUBDIR += fcitx5-mozc
SUBDIR += fcitx5-mozc3
SUBDIR += fcitx5-skk
SUBDIR += flower-fpw
diff --git a/japanese/fcitx-mozc/Makefile b/japanese/fcitx-mozc/Makefile
deleted file mode 100644
index 25646cdd2d95..000000000000
--- a/japanese/fcitx-mozc/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-PKGNAMEPREFIX= ja-fcitx-
-
-COMMENT= Mozc engine for Fcitx
-
-DATADIR= ${PREFIX}/share/fcitx/${PORTNAME}
-
-MASTERDIR= ${.CURDIR}/../../japanese/mozc-server
-FILESDIR= ${.CURDIR}/files
-SUB_FILES= pkg-message
-
-BUILD_MOZC_LIST= fcitx_mozc
-
-.include "${MASTERDIR}/Makefile"
diff --git a/japanese/fcitx5-mozc/Makefile b/japanese/fcitx5-mozc/Makefile
new file mode 100644
index 000000000000..53aaab00b52d
--- /dev/null
+++ b/japanese/fcitx5-mozc/Makefile
@@ -0,0 +1,11 @@
+PKGNAMEPREFIX= ja-fcitx5-
+
+COMMENT= Mozc engine for Fcitx 5
+
+DATADIR= ${PREFIX}/share/fcitx5/${PORTNAME}
+
+MASTERDIR= ${.CURDIR}/../../japanese/mozc-server
+
+BUILD_MOZC_LIST= fcitx5_mozc
+
+.include "${MASTERDIR}/Makefile"
diff --git a/japanese/ibus-mozc/Makefile b/japanese/ibus-mozc/Makefile
index 85c5c3317c78..632e0502c010 100644
--- a/japanese/ibus-mozc/Makefile
+++ b/japanese/ibus-mozc/Makefile
@@ -5,8 +5,8 @@ COMMENT= Mozc engine for IBus
DATADIR= ${PREFIX}/share/ibus-${PORTNAME}
MASTERDIR= ${.CURDIR}/../../japanese/mozc-server
-FILESDIR= ${.CURDIR}/files
-SUB_FILES= pkg-message
+SUB_FILES= pkg-message-ibus
+PKGMESSAGE= ${WRKDIR}/pkg-message-ibus
BUILD_MOZC_LIST= ibus_mozc
diff --git a/japanese/ibus-mozc/files/pkg-message.in b/japanese/ibus-mozc/files/pkg-message.in
deleted file mode 100644
index f7af7fe7cc3b..000000000000
--- a/japanese/ibus-mozc/files/pkg-message.in
+++ /dev/null
@@ -1,17 +0,0 @@
-[
-{ type: install
- message: <<EOM
-To activate ibus-mozc, please add the following into ~/.xinitrc,
-~/.xsession, or ~/.kde4/env (for KDE4):
-
-export GTK_IM_MODULE=ibus
-export QT_IM_MODULE=xim
-export XMODIFIERS=@im=ibus
-%%PREFIX%%/bin/mozc start
-ibus-daemon -r --daemonize --xim
-
-Note that textproc/ibus-qt with IBUS option is required to
-make QT_IM_MODULE=ibus work.
-EOM
-}
-]
diff --git a/japanese/mozc-el/pkg-message b/japanese/mozc-el/pkg-message
index 436907c15637..ebc367447f3a 100644
--- a/japanese/mozc-el/pkg-message
+++ b/japanese/mozc-el/pkg-message
@@ -1,12 +1,29 @@
[
{ type: install
message: <<EOM
-To activate mozc, you will need to add the following lines to
-your Emacs configuration:
+Restart Emacs after installation.
+
+To use Mozc as your default input method, add the following line
+to your Emacs initialization file, such as ~/.emacs or
+~/.emacs.d/init.el:
-(set-language-environment "Japanese")
(setq default-input-method "japanese-mozc")
+
+Press C-\ to toggle Japanese input.
+
+To select Mozc without changing your initialization file, use:
+
+M-x set-input-method RET japanese-mozc RET
+
+The helper program's path is configured by this port.
+The Mozc server starts automatically when needed.
+No IBus or Fcitx configuration is required for use within Emacs.
+
+If you prefer C-o for toggling input, you can optionally add:
+
(global-set-key (kbd "C-o") 'toggle-input-method)
+
+This replaces the standard C-o binding for open-line.
EOM
}
]
diff --git a/japanese/mozc-server/Makefile b/japanese/mozc-server/Makefile
index 0ed19a6e7c01..c6e36abd34c4 100644
--- a/japanese/mozc-server/Makefile
+++ b/japanese/mozc-server/Makefile
@@ -1,204 +1,228 @@
PORTNAME= mozc
-PORTVERSION= 2.23.2815.102.01
-DISTVERSIONPREFIX= v
-PORTREVISION?= 34
+PORTVERSION= 3.35.6354.101
CATEGORIES= japanese
+DIST_SUBDIR= ${PORTNAME}
+EXTRACT_ONLY= ${DISTFILE_DEFAULT}
MAINTAINER= hrs@FreeBSD.org
COMMENT?= Mozc Japanese Input Method, Server
WWW= https://github.com/google/mozc
-BUILD_DEPENDS= ${PYTHON_PKGNAMEPREFIX}gyp>=20200512:devel/py-gyp@${PY_FLAVOR}
-EXTRACT_DEPENDS=${PYTHON_CMD}:${PYTHON_PORTSDIR}
-LIB_DEPENDS= libabsl_spinlock_wait.so:devel/abseil \
- libprotobuf.so:devel/protobuf \
- libzinnia.so:japanese/zinnia
-RUN_DEPENDS= xdg-open:devel/xdg-utils
-
-BROKEN_powerpc= fails to compile: segfault
-
USE_GITHUB= yes
-GH_ACCOUNT= hrs-allbsd
-GH_TUPLE= hiroyuki-komatsu:japanese-usage-dictionary:e5b3425:udic
+GH_TUPLE= google:mozc:0136c35
+
+BUILD_MOZC_LIST?=mozc_server
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el" || make(makesum)
+GH_TUPLE+= bazelbuild:bazel-central-registry:9d03419:bcr \
+ hiroyuki-komatsu:japanese-usage-dictionary:38d3462:udic/src/japanese_usage_dictionary \
+ hiroyuki-komatsu:japanpost_zipcode:d630d72:zipcode/src/japanpost_zipcode
+EXTRACT_ONLY+= ${DISTFILE_bcr} \
+ ${DISTFILE_udic} \
+ ${DISTFILE_zipcode}
+.endif
-USES= compiler:c++17-lang gmake ninja:build pkgconfig \
- python:build shebangfix tar:bzip2
-SHEBANG_FILES= src/build_mozc.py
BUILD_WRKSRC= ${WRKSRC}/src
+DOCSDIR= ${PREFIX}/share/doc/${PORTNAME}
+CONFLICTS_INSTALL= ${PKGNAMEPREFIX}${PORTNAME}3${PKGNAMESUFFIX}
+.for P in ja-fcitx-mozc ja-ibus-mozc ja-mozc-tool ja-uim-mozc ja-mozc-el
+CONFLICTS_INSTALL+= ${P}-2.*
+.endfor
-LDFLAGS+= -labsl_spinlock_wait
-USE_CXXSTD= c++17
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el"
+LICENSE= BSD3CLAUSE APACHE20 MIT
+LICENSE_COMB= multi
+LICENSE_FILE_BSD3CLAUSE= ${WRKDIR}/LICENSE.BSD3CLAUSE
+LICENSE_DISTFILES_BSD3CLAUSE= ${DISTFILE_DEFAULT} \
+ protobuf-34.1.bazel.tar.gz
+LICENSE_FILE_APACHE20= ${WRKDIR}/LICENSE.abseil
+LICENSE_DISTFILES_APACHE20= abseil-cpp-20260107.1.tar.gz
+LICENSE_FILE_MIT= ${WRKDIR}/LICENSE.utf8_range
+LICENSE_DISTFILES_MIT= protobuf-34.1.bazel.tar.gz
-BUILD_MOZC_LIST?= mozc_server
+BUILD_DEPENDS= bazel9>=9.0.0:devel/bazel9
+USES= compiler:c++20-lang pkgconfig java:build python:3.12+,build
+USE_CXXSTD= c++20
+JAVA_VERSION= 21
+MAKE_ENV+= JAVA_HOME=${JAVA_HOME:Q}
+.endif
.if ${BUILD_MOZC_LIST:Mmozc_server} == "mozc_server"
PKGNAMEPREFIX= ja-
PKGNAMESUFFIX= -server
-CONFLICTS_INSTALL= ja-mozc3-server
-
-LICENSE= BSD3CLAUSE NAISTL
-LICENSE_COMB= multi
-LICENSE_FILE_BSD3CLAUSE= ${WRKSRC}/LICENSE
-LICENSE_DISTFILES_BSD3CLAUSE= ${DISTNAME}${EXTRACT_SUFX}
+LICENSE+= BSD2CLAUSE NAISTL
+LICENSE_FILE_BSD2CLAUSE= ${WRKSRC}/src/japanese_usage_dictionary/LICENSE
+LICENSE_DISTFILES_BSD2CLAUSE= ${DISTFILE_udic}
LICENSE_NAME_NAISTL= Nara Institute of Science and Technology License
LICENSE_PERMS_NAISTL= dist-mirror dist-sell pkg-mirror pkg-sell auto-accept
LICENSE_FILE_NAISTL= ${WRKSRC}/src/data/dictionary_oss/README.txt
-LICENSE_DISTFILES_NAISTL=${DISTNAME}${EXTRACT_SUFX}
+LICENSE_DISTFILES_NAISTL= ${DISTFILE_DEFAULT}
+LICENSE_FILE_MIT= ${WRKDIR}/LICENSE.MIT.server
+LICENSE_DISTFILES_MIT+= ${DISTFILE_DEFAULT}
.elif ${BUILD_MOZC_LIST:Mmozc_tool} == "mozc_tool"
-USES+= qt:6 gnome
-USE_GNOME= glib20 gtk20
-USE_QT= base tools:build
-EXTRA_PATCHES= ${PATCHDIR}/qt6
-CONFLICTS_INSTALL= ja-mozc3-tool
+LICENSE+= NAISTL
+LICENSE_NAME_NAISTL= Nara Institute of Science and Technology License
+LICENSE_PERMS_NAISTL= dist-mirror dist-sell pkg-mirror pkg-sell auto-accept
+LICENSE_FILE_NAISTL= ${WRKSRC}/src/data/dictionary_oss/README.txt
+LICENSE_DISTFILES_NAISTL= ${DISTFILE_DEFAULT}
+USES+= gl qt:6
+USE_GL= gl
+USE_QT= base
.elif ${BUILD_MOZC_LIST:Mibus_mozc} == "ibus_mozc"
-USES+= gettext-runtime gnome xorg
-USE_XORG= xcb
-USE_GNOME= cairo gdkpixbuf glib20 gtk20
-LIB_DEPENDS+= libfontconfig.so:x11-fonts/fontconfig \
- libfreetype.so:print/freetype2
-CONFLICTS_INSTALL= ja-ibus-mozc3
+USES+= gettext-runtime gnome gl qt:6
+USE_GNOME+= glib20
+USE_GL= gl
+USE_QT= base
.elif ${BUILD_MOZC_LIST:Mmozc_el} == "mozc_el"
+LICENSE= BSD3CLAUSE BSD2CLAUSE
+LICENSE_COMB= multi
+LICENSE_FILE_BSD3CLAUSE= ${WRKDIR}/LICENSE.mozc-el
+LICENSE_DISTFILES_BSD3CLAUSE= ${DISTFILE_DEFAULT}
+LICENSE_FILE_BSD2CLAUSE= ${WRKDIR}/LICENSE.leim-list
+LICENSE_DISTFILES_BSD2CLAUSE=
USES+= emacs
-.elif ${BUILD_MOZC_LIST:Mfcitx_mozc}
+.elif ${BUILD_MOZC_LIST:Muim_mozc} == "uim_mozc"
+USES+= gettext-runtime
+.elif ${BUILD_MOZC_LIST:Mfcitx5_mozc} == "fcitx5_mozc"
USES+= gettext-tools
.endif
-# Use GCC only when the stock clang does not have libc++.so.
-.if exists(/usr/bin/clang) && exists(/usr/lib/libc++.so)
-_CCTYPE= clang
-.else
-USE_GCC= yes
-_CCTYPE= gcc
-.endif
-
.include <bsd.port.pre.mk>
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el"
+. include "${FILESDIR}/Makefile.bazel"
+.endif
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el" || make(makesum)
+. include "${FILESDIR}/Makefile.distfiles"
+.endif
-GYP_DEFINES= use_libprotobuf=1 \
- channel_dev=0 \
- enable_unittest=0 \
- compiler_host='${_CCTYPE}' \
- compiler_target='${_CCTYPE}' \
- use_libzinnia=1 \
- zinnia_model_file='${LOCALBASE}/share/tegaki/models/zinnia/handwriting-ja.model' \
- ibus_mozc_icon_path='${LOCALBASE}/share/ibus-mozc/icons/product_icon.png' \
- ibus_mozc_path='${PREFIX}/libexec/ibus-engine-mozc'
-BUILD_MODE= Release
-BUILD_CMD= ${SETENV} ${MAKE_ENV} PATH=/bin:/usr/bin:${PATH} ${MAKE_CMD}
-BUILD_MOZC_CMD= cd ${BUILD_WRKSRC} && \
- ${SETENV} BUILD_COMMAND="${BUILD_WRKSRC}/mozcmake" \
- PATH="${PATH}" \
- GYP_DEFINES="${GYP_DEFINES}" \
- PYTHONPATH=${PYTHON_SITELIBDIR}/gyp \
- CC_host="${CC}" \
- CC_target="${CC}" \
- CXX_host="${CXX}" \
- CXX_target="${CXX}" \
- LD_host="${CXX}" \
- AR_host="${AR}" \
- ${MAKE_ENV} \
- ${PYTHON_CMD} build_mozc.py
-BUILD_MOZC_CMD_BUILD= ${BUILD_MOZC_CMD} build -c ${BUILD_MODE} ${_MAKE_JOBS}
-BUILD_GYP_CMD= ${SETENV} ${MAKE_ENV} ${LOCALBASE}/bin/gyp
-
-post-extract: # XXX: do not activate fcitx5
- ${RM} -r ${WRKSRC}/src/unix/fcitx5
-post-patch:
- ${FIND} ${BUILD_WRKSRC} \( -name '*.gyp' -o -name '*.gypi' \) -exec \
- ${REINPLACE_CMD} "s,'python','${PYTHON_CMD}',g" {} \;
-.if ${BUILD_MOZC_LIST:Mfcitx_mozc} == "fcitx_mozc"
- ${REINPLACE_CMD} 's,/po/mo},%po}mo,g' \
- ${BUILD_WRKSRC}/unix/fcitx/gen_fcitx_mozc_i18n.sh
+EMACS_SITE_LISPDIR?= share/emacs/site-lisp
+EXTRA_SUB_LIST= PREFIX LOCALBASE DOCSDIR EMACS_SITE_LISPDIR
+EXTRA_SUB_FILES= \
+ config.bzl \
+ bazel/pkg_config_repository.bzl
+post-patch-apply-extra-slist:
${REINPLACE_CMD} \
- "s,IconName=.*,IconName=${LOCALBASE:Q}/share/fcitx/mozc/icon/mozc.png," \
- ${BUILD_WRKSRC}/unix/fcitx/mozc.conf
+ ${EXTRA_SUB_LIST:@v@-e 's|%%$v%%|${$v}|g'@} \
+ ${EXTRA_SUB_FILES:@v@${BUILD_WRKSRC}/$v@}
+post-patch: post-patch-apply-extra-slist
+
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el"
+post-extract-zipcode:
+ cd ${BUILD_WRKSRC} && ${UNZIP_NATIVE_CMD} -q \
+ japanpost_zipcode/ken_all.zip -d japanpost_zipcode
+ cd ${BUILD_WRKSRC} && ${UNZIP_NATIVE_CMD} -q \
+ japanpost_zipcode/jigyosyo.zip -d japanpost_zipcode
+post-extract: post-extract-zipcode
.endif
-.if !${BUILD_MOZC_LIST:Mmozc_el}
-${BUILD_WRKSRC}/mozcmake:
- ${PRINTF} "%s\n\n%s\n" "#!/bin/sh" 'exec ${BUILD_CMD} "$$@"' \
- > ${BUILD_WRKSRC}/mozcmake
- ${CHMOD} +x ${BUILD_WRKSRC}/mozcmake
+.if ${BUILD_MOZC_LIST:Mmozc_el} != "mozc_el"
+post-extract-mozc-licenses:
+ ${TAR} -xOf \
+ ${DISTDIR}/${DIST_SUBDIR}/protobuf-34.1.bazel.tar.gz \
+ protobuf-34.1/third_party/utf8_range/LICENSE \
+ > ${WRKDIR}/LICENSE.utf8_range
+ ${INSTALL_DATA} ${WRKSRC}/LICENSE ${WRKDIR}/LICENSE.BSD3CLAUSE
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.BSD3CLAUSE
+ ${TAR} -xOf \
+ ${DISTDIR}/${DIST_SUBDIR}/protobuf-34.1.bazel.tar.gz \
+ protobuf-34.1/LICENSE \
+ >> ${WRKDIR}/LICENSE.BSD3CLAUSE
+ ${TAR} -xOf \
+ ${DISTDIR}/${DIST_SUBDIR}/abseil-cpp-20260107.1.tar.gz \
+ abseil-cpp-20260107.1/LICENSE \
+ > ${WRKDIR}/LICENSE.abseil
-post-configure: ${BUILD_WRKSRC}/mozcmake
- ${BUILD_MOZC_CMD} gyp \
- --gypdir=${LOCALBASE}/bin \
- --server_dir="${PREFIX}/bin" \
- --tool_dir="${PREFIX}/libexec" \
- --renderer_dir="${PREFIX}/libexec" \
- --localbase="${LOCALBASE}" \
- --ldflags="${LDFLAGS} -fstack-protector -L${LOCALBASE}/lib" \
- --cflags="${CFLAGS:Q}" \
- --cflags_cc="${CXXFLAGS:Q}" \
- --include_dirs="${LOCALBASE}/include" \
- ${GYP_OPTIONS}
+post-extract: post-extract-mozc-licenses
.endif
# mozc_server
.if ${BUILD_MOZC_LIST:Mmozc_server} == "mozc_server" || make(makesum)
-GYP_OPTIONS+= --noqt
-GYP_DEFINES+= use_libibus=0 \
- enable_gtk_renderer=0
-
-MASTER_SITES+= LOCAL/hrs:zipcode
-DISTFILES+= \
- ken_all-20221228.zip:zipcode \
- jigyosyo-20221228.zip:zipcode
PLIST_FILES+= bin/mozc \
- bin/mozc_server \
- libexec/mozc_emacs_helper
+ bin/mozc_emacs_helper \
+ libexec/mozc_server \
+ libexec/mozc_emacs_helper \
+ %%DATADIR%%/icons/mozc.png \
+ %%DATADIR%%/icons/mozc.svg \
+ %%DATADIR%%/icons/alpha_full.png \
+ %%DATADIR%%/icons/alpha_full.svg \
+ %%DATADIR%%/icons/alpha_half.png \
+ %%DATADIR%%/icons/alpha_half.svg \
+ %%DATADIR%%/icons/direct.png \
+ %%DATADIR%%/icons/direct.svg \
+ %%DATADIR%%/icons/hiragana.png \
+ %%DATADIR%%/icons/hiragana.svg \
+ %%DATADIR%%/icons/katakana_full.png \
+ %%DATADIR%%/icons/katakana_full.svg \
+ %%DATADIR%%/icons/katakana_half.png \
+ %%DATADIR%%/icons/katakana_half.svg \
+ %%DATADIR%%/icons/dictionary.png \
+ %%DATADIR%%/icons/dictionary.svg \
+ %%DATADIR%%/icons/properties.png \
+ %%DATADIR%%/icons/properties.svg \
+ %%DATADIR%%/icons/tool.png \
+ %%DATADIR%%/icons/tool.svg \
+ %%DATADIR%%/icons/white/dictionary.svg \
+ %%DATADIR%%/icons/white/properties.svg \
+ %%DATADIR%%/icons/white/tool.svg \
+ %%DATADIR%%/icons/outlined/dictionary.svg \
+ %%DATADIR%%/icons/outlined/properties.svg \
+ %%DATADIR%%/icons/outlined/tool.svg
SUB_FILES+= mozc
-post-patch-mozc_server:
- @for F in ${DISTFILES:M*\:zipcode:C/\:zipcode//}; do \
- ${UNZIP_NATIVE_CMD} -L -d ${BUILD_WRKSRC}/data/dictionary_oss \
- ${DISTDIR}/$$F; \
- done
- cd ${BUILD_WRKSRC}/data/dictionary_oss && \
- ${SETENV} PYTHONPATH=${BUILD_WRKSRC} \
- ${PYTHON_CMD} ${BUILD_WRKSRC}/dictionary/gen_zip_code_seed.py \
- --zip_code=ken_all.csv --jigyosyo=jigyosyo.csv \
- >> dictionary09.txt
- ${MV} ${WRKSRC_udic}/usage_dict.txt \
- ${BUILD_WRKSRC}/third_party/japanese_usage_dictionary
+post-extract-mozc_server-mit: post-extract-mozc-licenses
+ ${INSTALL_DATA} ${WRKDIR}/LICENSE.utf8_range \
+ ${WRKDIR}/LICENSE.MIT.server
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.MIT.server
+ ${AWK} '\
+ /<h3>Tamachi Phonetic Kanji Alphabet / { section = 1 } \
+ section && /^<pre>/ { body = 1; next } \
+ body && /^<\/pre>/ { exit } \
+ body { print }' \
+ ${BUILD_WRKSRC}/data/installer/credits_en.html \
+ >> ${WRKDIR}/LICENSE.MIT.server
-post-patch: post-patch-mozc_server
+post-extract: post-extract-mozc_server-mit
do-build-mozc_server:
- ${BUILD_MOZC_CMD_BUILD} server/server.gyp:mozc_server
- ${BUILD_MOZC_CMD_BUILD} unix/emacs/emacs.gyp:mozc_emacs_helper
+ ${BUILD_MOZC_CMD} \
+ //server:mozc_server \
+ //unix/emacs:mozc_emacs_helper \
+ //unix:icons
do-install-mozc_server:
- ${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/mozc_server \
- ${STAGEDIR}${PREFIX}/bin
- ${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/mozc_emacs_helper \
+ cd ${BUILD_WRKSRC} && ${INSTALL_PROGRAM} \
+ bazel-bin/server/mozc_server \
+ bazel-bin/unix/emacs/mozc_emacs_helper \
${STAGEDIR}${PREFIX}/libexec
+ ${RLN} ${STAGEDIR}${PREFIX}/libexec/mozc_emacs_helper \
+ ${STAGEDIR}${PREFIX}/bin/mozc_emacs_helper
${INSTALL_SCRIPT} \
${WRKDIR}/mozc ${STAGEDIR}/${PREFIX}/bin
+ @${MKDIR} ${STAGEDIR}${DATADIR}/icons
+ ${UNZIP_NATIVE_CMD} -q \
+ ${BUILD_WRKSRC}/bazel-bin/unix/icons.zip \
+ -d ${STAGEDIR}${DATADIR}/icons
.endif
# mozc_tool
.if ${BUILD_MOZC_LIST:Mmozc_tool} == "mozc_tool"
-GYP_DEFINES+= use_libibus=0 \
- enable_gtk_renderer=1
-
-RUN_DEPENDS+= ${LOCALBASE}/share/tegaki/models/zinnia/handwriting-ja.model:japanese/tegaki-zinnia-japanese
+RUN_DEPENDS+= ${LOCALBASE}/libexec/mozc_server:japanese/mozc-server \
+ xdg-open:devel/xdg-utils
PLIST_FILES+= libexec/mozc_tool \
bin/mozc_tool \
%%DATADIR%%/icons/product_logo.png \
- %%DATADIR%%/icons/update_uptodate.png
+ %%DATADIR%%/icons/update_uptodate.png \
+ %%DOCSDIR%%/credits_en.html
SUB_FILES+= mozc_tool
do-build-mozc_tool:
- ${BUILD_MOZC_CMD_BUILD} gui/gui.gyp:mozc_tool
+ ${BUILD_MOZC_CMD} //gui/tool:mozc_tool
do-install-mozc_tool:
${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/mozc_tool \
+ ${BUILD_WRKSRC}/bazel-bin/gui/tool/mozc_tool \
${STAGEDIR}${PREFIX}/libexec
${INSTALL_SCRIPT} ${WRKDIR}/mozc_tool ${STAGEDIR}${PREFIX}/bin
@${MKDIR} ${STAGEDIR}${DATADIR}/icons
@@ -208,193 +232,257 @@ do-install-mozc_tool:
${INSTALL_DATA} \
${BUILD_WRKSRC}/data/images/unix/ime_product_icon_opensource-32.png \
${STAGEDIR}${DATADIR}/icons/update_uptodate.png
+ @${MKDIR} ${STAGEDIR}${DOCSDIR}
+ ${INSTALL_DATA} \
+ ${BUILD_WRKSRC}/data/installer/credits_en.html \
+ ${STAGEDIR}${DOCSDIR}
.endif
# ibus_mozc
.if ${BUILD_MOZC_LIST:Mibus_mozc} == "ibus_mozc"
-GYP_OPTIONS+= --noqt
-GYP_DEFINES+= use_libibus=1 \
- enable_gtk_renderer=1
LIB_DEPENDS+= libibus-1.0.so:textproc/ibus
-RUN_DEPENDS+= mozc_server:japanese/mozc-server \
+RUN_DEPENDS+= ${LOCALBASE}/libexec/mozc_server:japanese/mozc-server \
mozc_tool:japanese/mozc-tool
PLIST_FILES+= libexec/mozc_renderer \
libexec/ibus-engine-mozc \
- %%DATADIR%%/icons/alpha_full.png \
- %%DATADIR%%/icons/alpha_half.png \
- %%DATADIR%%/icons/dictionary.png \
- %%DATADIR%%/icons/direct.png \
- %%DATADIR%%/icons/hiragana.png \
- %%DATADIR%%/icons/katakana_full.png \
- %%DATADIR%%/icons/katakana_half.png \
- %%DATADIR%%/icons/product_icon.png \
- %%DATADIR%%/icons/properties.png \
- %%DATADIR%%/icons/tool.png \
share/ibus/component/mozc.xml
-PLIST_DIRS+= %%DATADIR%%/icons ${DATADIR_REL}
do-build-ibus_mozc:
- ${BUILD_MOZC_CMD_BUILD} \
- unix/ibus/ibus.gyp:ibus_mozc \
- renderer/renderer.gyp:mozc_renderer
+ ${BUILD_MOZC_CMD} \
+ //unix/ibus:ibus_mozc \
+ //unix/ibus:gen_mozc_xml \
+ //renderer/qt:mozc_renderer
do-install-ibus_mozc:
${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/mozc_renderer \
+ ${BUILD_WRKSRC}/bazel-bin/renderer/qt/mozc_renderer \
${STAGEDIR}${PREFIX}/libexec/mozc_renderer
${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/ibus_mozc \
+ ${BUILD_WRKSRC}/bazel-bin/unix/ibus/ibus_mozc \
${STAGEDIR}${PREFIX}/libexec/ibus-engine-mozc
${MKDIR} ${STAGEDIR}${PREFIX}/share/ibus/component
${INSTALL_DATA} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/gen/unix/ibus/mozc.xml \
+ ${BUILD_WRKSRC}/bazel-bin/unix/ibus/mozc.xml \
${STAGEDIR}${PREFIX}/share/ibus/component/mozc.xml
- @${MKDIR} ${STAGEDIR}${DATADIR}/icons
-.for F in ui-alpha_full ui-alpha_half ui-dictionary ui-direct \
- ui-hiragana ui-katakana_full ui-katakana_half ui-properties ui-tool
- ${INSTALL_DATA} \
- ${BUILD_WRKSRC}/data/images/unix/${F}.png \
- ${STAGEDIR}${DATADIR}/icons/${F:S/^ui-//}.png
-.endfor
- ${INSTALL_DATA} \
- ${BUILD_WRKSRC}/data/images/unix/ime_product_icon_opensource-32.png \
- ${STAGEDIR}${DATADIR}/icons/product_icon.png
.endif
# uim_mozc
.if ${BUILD_MOZC_LIST:Muim_mozc} == "uim_mozc" || make(makesum)
-GH_TUPLE+= e-kato:macuim:v0.6.16.2.1:MU
+GH_TUPLE+= e-kato:macuim:7beac7b:MU
+EXTRACT_ONLY+= ${DISTFILE_MU}
+
+LICENSE_DISTFILES_BSD3CLAUSE+= ${DISTFILE_MU}
+LICENSE_FILE_BSD3CLAUSE= ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
LIB_DEPENDS+= libuim.so:textproc/uim
-RUN_DEPENDS+= mozc_server:japanese/mozc-server \
+RUN_DEPENDS+= ${LOCALBASE}/libexec/mozc_server:japanese/mozc-server \
mozc_tool:japanese/mozc-tool
-CONFLICTS_INSTALL= ja-uim-mozc3
-
-EXTRA_PATCHES= ${PATCHDIR}/extra-patch-src-unix-uim-mozc.cc \
- ${PATCHDIR}/extra-patch-src-unix-uim-uim.gyp \
+EXTRA_PATCHES= ${PATCHDIR}/extra-patch-src-MODULE-uim.bazel \
+ ${PATCHDIR}/extra-patch-src-unix-uim-mozc.cc \
${PATCHDIR}/extra-patch-src-unix-uim-key_translator.h \
- ${PATCHDIR}/extra-patch-src-unix-uim-key_translator.cc
+ ${PATCHDIR}/extra-patch-src-unix-uim-key_translator.cc \
+ ${PATCHDIR}/extra-patch-src-unix-uim-scm-mozc-custom.scm \
+ ${PATCHDIR}/extra-patch-src-unix-uim-scm-mozc.scm
PLIST_FILES+= lib/uim/plugin/libuim-mozc.so \
%%DATADIR%%/mozc.scm \
%%DATADIR%%/mozc-custom.scm \
%%DATADIR%%/mozc-key-custom.scm \
%%DATADIR%%/pixmaps/mozc.png \
- "@postexec ${SETENV} MOZC_NOLOG=true ${LOCALBASE}/bin/uim-module-manager --register mozc" \
+ %%DATADIR%%/pixmaps/mozc_tool_selector.png \
+ %%DATADIR%%/pixmaps/mozc_tool_config_dialog.png \
+ %%DATADIR%%/pixmaps/mozc_tool_dictionary_tool.png \
+ %%DATADIR%%/pixmaps/mozc_tool_word_register_dialog.png \
+ %%DATADIR%%/pixmaps/mozc_tool_about_dialog.png \
+ "@postexec ${LOCALBASE}/bin/uim-module-manager --register mozc" \
"@preunexec ${LOCALBASE}/bin/uim-module-manager --unregister mozc"
-GYP_OPTIONS+= --noqt
-GYP_DEFINES+= use_libibus=0 \
- enable_gtk_renderer=0
-
post-extract-uim_mozc:
${MV} ${WRKSRC_MU}/Mozc/uim ${BUILD_WRKSRC}/unix
- ${REINPLACE_CMD} -e "s,/usr/lib/mozc,${LOCALBASE}/libexec," \
- ${WRKSRC_MU}/Mozc/scm/mozc-custom.scm
+ ${MV} ${WRKSRC_MU}/Mozc/scm ${BUILD_WRKSRC}/unix/uim/scm
+ ${INSTALL_DATA} ${PATCHDIR}/extra-src-unix-uim-BUILD.bazel \
+ ${BUILD_WRKSRC}/unix/uim/BUILD.bazel
post-extract: post-extract-uim_mozc
+post-extract-uim-licenses: post-extract-mozc-licenses post-extract-uim_mozc
+ ${INSTALL_DATA} ${WRKDIR}/LICENSE.BSD3CLAUSE \
+ ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
+ ${SED} -n '1,/^[[:space:]]*\*\//p' \
+ ${BUILD_WRKSRC}/unix/uim/mozc.cc \
+ >> ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
+ ${SED} '/^$$/q' \
+ ${BUILD_WRKSRC}/unix/uim/key_translator.cc \
+ >> ${WRKDIR}/LICENSE.BSD3CLAUSE.uim
+
+post-extract: post-extract-uim-licenses
+
+post-patch-uim_mozc:
+ ${REINPLACE_CMD} -e "s,/usr/lib/mozc,${LOCALBASE}/libexec," \
+ ${BUILD_WRKSRC}/unix/uim/scm/mozc-custom.scm
+
+post-patch: post-patch-uim_mozc
+
do-build-uim_mozc:
- ${BUILD_MOZC_CMD_BUILD} \
- unix/uim/uim.gyp:uim-mozc
+ ${BUILD_MOZC_CMD} //unix/uim:uim-mozc
do-install-uim_mozc:
${MKDIR} ${STAGEDIR}${PREFIX}/lib/uim/plugin
${INSTALL_PROGRAM} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/libuim-mozc.so \
+ ${BUILD_WRKSRC}/bazel-bin/unix/uim/libuim-mozc.so \
${STAGEDIR}${PREFIX}/lib/uim/plugin
${MKDIR} ${STAGEDIR}${DATADIR}
- cd ${WRKSRC_MU}/Mozc/scm && \
+ cd ${BUILD_WRKSRC}/unix/uim/scm && \
${INSTALL_DATA} mozc.scm mozc-custom.scm mozc-key-custom.scm \
${STAGEDIR}${DATADIR}
${MKDIR} ${STAGEDIR}${DATADIR}/pixmaps
${INSTALL_DATA} \
${BUILD_WRKSRC}/data/images/product_icon_32bpp-128.png \
${STAGEDIR}${DATADIR}/pixmaps/mozc.png
+.for name icon in \
+ selector tool \
+ config_dialog properties \
+ dictionary_tool dictionary \
+ word_register_dialog dictionary \
+ about_dialog mozc
+ ${LN} -sf ${LOCALBASE}/share/mozc/icons/${icon}.png \
+ ${STAGEDIR}${DATADIR}/pixmaps/mozc_tool_${name}.png
+.endfor
.endif
-# fcitx_mozc
-.if ${BUILD_MOZC_LIST:Mfcitx_mozc} == "fcitx_mozc"
-GYP_OPTIONS+= --noqt
-GYP_DEFINES+= use_libibus=0 \
- enable_gtk_renderer=0 \
- use_fcitx="YES"
+# fcitx5_mozc
+.if ${BUILD_MOZC_LIST:Mfcitx5_mozc} == "fcitx5_mozc" || make(makesum)
+GH_TUPLE+= fcitx:mozc:13ef96d:fcitx
+EXTRACT_ONLY+= ${DISTFILE_fcitx}
+
+MASTER_SITES+= https://creativecommons.org/publicdomain/zero/1.0/:cc0
+DISTFILES+= legalcode.txt:cc0
+.endif
-LIB_DEPENDS+= libfcitx-core.so:chinese/fcitx
-RUN_DEPENDS+= mozc_server:japanese/mozc-server \
+.if ${BUILD_MOZC_LIST:Mfcitx5_mozc} == "fcitx5_mozc"
+LICENSE+= LGPL20+ CC0-1.0
+LICENSE_FILE_LGPL20+ = ${WRKDIR}/LICENSE.LGPL20.fcitx5
+LICENSE_DISTFILES_LGPL20+ = ${DISTFILE_fcitx}
+LICENSE_DISTFILES_CC0-1.0= ${DISTFILE_fcitx}
+LICENSE_FILE_BSD3CLAUSE= ${WRKDIR}/LICENSE.BSD3CLAUSE.fcitx5
+LICENSE_DISTFILES_BSD3CLAUSE+= ${DISTFILE_fcitx}
+LICENSE_FILE_CC0-1.0= ${WRKDIR}/LICENSE.CC0
+
+LIB_DEPENDS+= libFcitx5Core.so:textproc/fcitx5
+RUN_DEPENDS+= ${LOCALBASE}/libexec/mozc_server:japanese/mozc-server \
+ xdg-open:devel/xdg-utils \
mozc_tool:japanese/mozc-tool
-PLIST_FILES+= lib/fcitx/fcitx-mozc.so \
- share/fcitx/addon/fcitx-mozc.conf \
- share/fcitx/inputmethod/mozc.conf \
- %%DATADIR%%/icon/mozc.png \
- %%DATADIR%%/icon/mozc-alpha_full.png \
- %%DATADIR%%/icon/mozc-alpha_half.png \
- %%DATADIR%%/icon/mozc-direct.png \
- %%DATADIR%%/icon/mozc-hiragana.png \
- %%DATADIR%%/icon/mozc-katakana_full.png \
- %%DATADIR%%/icon/mozc-katakana_half.png \
- %%DATADIR%%/icon/mozc-dictionary.png \
- %%DATADIR%%/icon/mozc-properties.png \
- %%DATADIR%%/icon/mozc-tool.png \
- share/locale/ja/LC_MESSAGES/fcitx-mozc.mo \
- share/locale/zh_CN/LC_MESSAGES/fcitx-mozc.mo \
- share/locale/zh_TW/LC_MESSAGES/fcitx-mozc.mo
-PLIST_DIRS+= %%DATADIR%%/icon ${DATADIR_REL}
+EXTRA_PATCHES+= ${PATCHDIR}/extra-patch-src-MODULE-fcitx5.bazel
+
+PLIST_FILES+= lib/fcitx5/fcitx5-mozc.so \
+ share/fcitx5/addon/mozc.conf \
+ share/fcitx5/inputmethod/mozc.conf \
+ ${FCITX5_MOZC_LOCALES:@l@share/locale/$l/LC_MESSAGES/fcitx5-mozc.mo@} \
+ share/icons/hicolor/scalable/apps/fcitx_mozc.svg \
+ ${FCITX5_MOZC_ICONS:@i@share/icons/hicolor/scalable/apps/fcitx_mozc_$i.svg@} \
+ share/metainfo/org.fcitx.Fcitx5.Addon.Mozc.metainfo.xml
+FCITX5_MOZC_LOCALES= ca da de fr he ja ka ko ru sv tr vi zh_CN zh_TW
+FCITX5_MOZC_ICONS= alpha_full alpha_half direct hiragana \
+ katakana_full katakana_half dictionary properties tool
-do-build-fcitx_mozc:
- ${BUILD_MOZC_CMD_BUILD} unix/fcitx/fcitx.gyp:fcitx-mozc
+post-extract-fcitx5_mozc:
+ ${MV} ${WRKSRC_fcitx}/src/unix/fcitx5 ${BUILD_WRKSRC}/unix
+ ${MV} ${WRKSRC_fcitx}/src/unix/fcitx/gen_fcitx_mozc_i18n.sh \
+ ${BUILD_WRKSRC}/unix/fcitx5/
-do-install-fcitx_mozc:
- @${MKDIR} \
- ${STAGEDIR}${PREFIX}/lib/fcitx \
- ${STAGEDIR}${PREFIX}/share/fcitx/addon \
- ${STAGEDIR}${PREFIX}/share/fcitx/inputmethod
+post-extract-fcitx5-licenses: post-extract-mozc-licenses post-extract-fcitx5_mozc
+ ${INSTALL_DATA} ${WRKDIR}/LICENSE.BSD3CLAUSE \
+ ${WRKDIR}/LICENSE.BSD3CLAUSE.fcitx5
+.for src in fcitx_key_event_handler fcitx_key_translator mozc_client_pool \
+ mozc_response_parser mozc_state surrounding_text_util
+. for ext in cc h
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.BSD3CLAUSE.fcitx5
+ ${SED} '/^$$/q' \
+ ${BUILD_WRKSRC}/unix/fcitx5/${src}.${ext} \
+ >> ${WRKDIR}/LICENSE.BSD3CLAUSE.fcitx5
+. endfor
+.endfor
+ ${INSTALL_DATA} ${PORTSDIR}/Templates/Licenses/LGPL20 \
+ ${WRKDIR}/LICENSE.LGPL20.fcitx5
+.for src in mozc_engine.cc mozc_engine.h mozc_engine_factory.cc i18nwrapper.h
+ ${ECHO_CMD} "" >> ${WRKDIR}/LICENSE.LGPL20.fcitx5
+ ${SED} -n '1,/^[[:space:]]*\*\//p' \
+ ${BUILD_WRKSRC}/unix/fcitx5/${src} \
+ >> ${WRKDIR}/LICENSE.LGPL20.fcitx5
+.endfor
+ ${INSTALL_DATA} ${DISTDIR}/${DIST_SUBDIR}/legalcode.txt \
+ ${WRKDIR}/LICENSE.CC0
+
+post-extract: post-extract-fcitx5-licenses
+
+do-build-fcitx5_mozc:
+ ${BUILD_MOZC_CMD} //unix/fcitx5:fcitx5-mozc.so
+ cd ${BUILD_WRKSRC}/unix/fcitx5 && \
+ ${LOCALBASE}/bin/msgfmt --xml -d po \
+ --template org.fcitx.Fcitx5.Addon.Mozc.metainfo.xml.in \
+ -o org.fcitx.Fcitx5.Addon.Mozc.metainfo.xml
+ cd ${BUILD_WRKSRC}/unix/fcitx5 && \
+ ${SETENV} ${MAKE_ENV} ${SH} gen_fcitx_mozc_i18n.sh ./po
+
+post-extract: post-extract-fcitx5_mozc
+
+do-install-fcitx5_mozc:
+ ${MKDIR} ${STAGEDIR}${PREFIX}/lib/fcitx5 \
+ ${STAGEDIR}${PREFIX}/share/fcitx5/addon \
+ ${STAGEDIR}${PREFIX}/share/fcitx5/inputmethod
${INSTALL_LIB} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/fcitx-mozc.so \
- ${STAGEDIR}${PREFIX}/lib/fcitx/fcitx-mozc.so
+ ${BUILD_WRKSRC}/bazel-bin/unix/fcitx5/fcitx5-mozc.so \
+ ${STAGEDIR}${PREFIX}/lib/fcitx5/
${INSTALL_DATA} \
- ${BUILD_WRKSRC}/unix/fcitx/fcitx-mozc.conf \
- ${STAGEDIR}${PREFIX}/share/fcitx/addon/fcitx-mozc.conf
+ ${BUILD_WRKSRC}/unix/fcitx5/mozc-addon.conf \
+ ${STAGEDIR}${PREFIX}/share/fcitx5/addon/mozc.conf
${INSTALL_DATA} \
- ${BUILD_WRKSRC}/unix/fcitx/mozc.conf \
- ${STAGEDIR}${PREFIX}/share/fcitx/inputmethod/mozc.conf
- @${MKDIR} ${STAGEDIR}${DATADIR}/icon
-.for F in ui-alpha_full ui-alpha_half ui-dictionary ui-direct \
- ui-hiragana ui-katakana_full ui-katakana_half ui-properties ui-tool
+ ${BUILD_WRKSRC}/unix/fcitx5/mozc.conf \
+ ${STAGEDIR}${PREFIX}/share/fcitx5/inputmethod/mozc.conf
+.for lang in ${FCITX5_MOZC_LOCALES}
+ ${MKDIR} ${STAGEDIR}${PREFIX}/share/locale/${lang}/LC_MESSAGES
${INSTALL_DATA} \
- ${BUILD_WRKSRC}/data/images/unix/${F}.png \
- ${STAGEDIR}${DATADIR}/icon/${F:S,^ui-,mozc-,}.png
+ ${BUILD_WRKSRC}/unix/fcitx5/po/${lang}.mo \
+ ${STAGEDIR}${PREFIX}/share/locale/${lang}/LC_MESSAGES/fcitx5-mozc.mo
.endfor
+ ${MKDIR} ${STAGEDIR}${PREFIX}/share/metainfo
${INSTALL_DATA} \
- ${BUILD_WRKSRC}/data/images/product_icon_32bpp-128.png \
- ${STAGEDIR}${DATADIR}/icon/mozc.png
-.for L in ja zh_CN zh_TW
- ${INSTALL_DATA} \
- ${BUILD_WRKSRC}/out_linux/${BUILD_MODE}/gen/unix/fcitx/po/${L}.mo \
- ${STAGEDIR}${PREFIX}/share/locale/${L}/LC_MESSAGES/fcitx-mozc.mo
+ ${BUILD_WRKSRC}/unix/fcitx5/org.fcitx.Fcitx5.Addon.Mozc.metainfo.xml \
+ ${STAGEDIR}${PREFIX}/share/metainfo/
+ ${MKDIR} ${STAGEDIR}${PREFIX}/share/icons/hicolor/scalable/apps
+ ${LN} -sf ${LOCALBASE}/share/mozc/icons/mozc.svg \
+ ${STAGEDIR}${PREFIX}/share/icons/hicolor/scalable/apps/fcitx_mozc.svg
+.for icon in ${FCITX5_MOZC_ICONS}
+ ${LN} -sf ${LOCALBASE}/share/mozc/icons/${icon}.svg \
+ ${STAGEDIR}${PREFIX}/share/icons/hicolor/scalable/apps/fcitx_mozc_${icon}.svg
.endfor
.endif
# mozc_el
.if ${BUILD_MOZC_LIST:Mmozc_el} == "mozc_el"
CATEGORIES+= elisp
-RUN_DEPENDS+= mozc_server:japanese/mozc-server
-
-CONFLICTS_INSTALL= ja-mozc3-el
+RUN_DEPENDS+= ${LOCALBASE}/libexec/mozc_server:japanese/mozc-server
NO_ARCH= yes
PLIST_FILES+= ${EMACS_SITE_LISPDIR}/mozc/mozc.el.gz \
${EMACS_SITE_LISPDIR}/mozc/leim-list.el
PLIST_DIRS+= ${EMACS_SITE_LISPDIR}/mozc
-post-patch-mozc_el:
- ${REINPLACE_CMD} "s,%%PREFIX%%,${PREFIX}," \
- ${BUILD_WRKSRC}/unix/emacs/mozc.el
+EXTRA_SUB_FILES+= unix/emacs/mozc.el
+
+post-extract-mozc-el-licenses:
+ ${SED} -n '/^;; Copyright/p; /^;; Redistribution/,/^$$/p' \
+ ${BUILD_WRKSRC}/unix/emacs/mozc.el \
+ > ${WRKDIR}/LICENSE.mozc-el
+ ${SED} '/^$$/q' ${FILESDIR}/leim-list.el \
+ > ${WRKDIR}/LICENSE.leim-list
-post-patch: post-patch-mozc_el
+post-extract: post-extract-mozc-el-licenses
do-build-mozc_el:
cd ${BUILD_WRKSRC}/unix/emacs && ${GZIP_CMD} mozc.el
diff --git a/japanese/mozc-server/distinfo b/japanese/mozc-server/distinfo
index c90c863630f8..b144f8af89ff 100644
--- a/japanese/mozc-server/distinfo
+++ b/japanese/mozc-server/distinfo
@@ -1,11 +1,75 @@
-TIMESTAMP = 1673183895
-SHA256 (ken_all-20221228.zip) = cfe8d51d3610ec20b40be7472a05afa2b92bd1e5e68c8b25871a4958d09a94ef
-SIZE (ken_all-20221228.zip) = 1691520
-SHA256 (jigyosyo-20221228.zip) = d5b07562130585778860d4e173c879c17d5246049e7d958f720e192b5dfd6a5d
-SIZE (jigyosyo-20221228.zip) = 773333
-SHA256 (hrs-allbsd-mozc-v2.23.2815.102.01_GH0.tar.gz) = 05da136f52230aa8f7d0b96e8c3aaf4a2367a44bc1026bd4b23d22b46c6687b6
-SIZE (hrs-allbsd-mozc-v2.23.2815.102.01_GH0.tar.gz) = 36712681
-SHA256 (hiroyuki-komatsu-japanese-usage-dictionary-e5b3425_GH0.tar.gz) = 2af954cd844c6a3113449d7dca37e36b769ecb2b49d3a54318a3bdee1a75af56
-SIZE (hiroyuki-komatsu-japanese-usage-dictionary-e5b3425_GH0.tar.gz) = 71050
-SHA256 (e-kato-macuim-v0.6.16.2.1_GH0.tar.gz) = ae999a2f02379bd049484a22684c37be5eb1f4db9763fa79885c4981502336e9
-SIZE (e-kato-macuim-v0.6.16.2.1_GH0.tar.gz) = 324549
+TIMESTAMP = 1792384988
+SHA256 (mozc/bazel/sha256/9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628/24px.svg) = 9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628
+SIZE (mozc/bazel/sha256/9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628/24px.svg) = 812
+SHA256 (mozc/bazel/sha256/a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d/24px.svg) = a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d
+SIZE (mozc/bazel/sha256/a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d/24px.svg) = 294
+SHA256 (mozc/bazel/sha256/df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804/24px.svg) = df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804
+SIZE (mozc/bazel/sha256/df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804/24px.svg) = 326
+SHA256 (mozc/abseil-cpp-20260107.1.tar.gz) = 4314e2a7cbac89cac25a2f2322870f343d81579756ceff7f431803c2c9090195
+SIZE (mozc/abseil-cpp-20260107.1.tar.gz) = 2301097
+SHA256 (mozc/apple_support.2.4.0.tar.gz) = 9f2ee0d23bf46b1c8ac88cea73ab13d415f340ec777e1e68841e09153880a67e
+SIZE (mozc/apple_support.2.4.0.tar.gz) = 115899
+SHA256 (mozc/apple_support.2.5.2.tar.gz) = ce4fc3e360c151af7c142da190abd4cfb49ca90aa833291d136afa05e94ba4ea
+SIZE (mozc/apple_support.2.5.2.tar.gz) = 116707
+SHA256 (mozc/baseline_build_black_48dp.png) = 269433bf6d6948a93ab6a57a73ceb5930870223046052cfffe01eeca37327d3e
+SIZE (mozc/baseline_build_black_48dp.png) = 360
+SHA256 (mozc/bazel-lib-v2.22.5.tar.gz) = 94e192033ca8027f26de71c9000a67ef9c73695c2b88e2c559045170917ead0c
+SIZE (mozc/bazel-lib-v2.22.5.tar.gz) = 167962
+SHA256 (mozc/bazel-lib-v3.0.0.tar.gz) = 6fd3b1e1a38ca744f9664be4627ced80895c7d2ee353891c172f1ab61309c933
+SIZE (mozc/bazel-lib-v3.0.0.tar.gz) = 112873
+SHA256 (mozc/bazel-skylib-1.9.0.tar.gz) = 3b5b49006181f5f8ff626ef8ddceaa95e9bb8ad294f7b5d7b11ea9f7ddaf8c59
+SIZE (mozc/bazel-skylib-1.9.0.tar.gz) = 44790
+SHA256 (mozc/bazel_features-v1.42.1.tar.gz) = 8189bac9a6bf9cc155a854c4cbebfebf58b9ca7a2d0a67645f7d0c1f83c523ac
+SIZE (mozc/bazel_features-v1.42.1.tar.gz) = 18078
+SHA256 (mozc/outline_chrome_reader_mode_black_48dp.png) = 6d2ac7befa038d4f32e07136293acaf5d8645a4daecb6d063f34be2ffea59b55
+SIZE (mozc/outline_chrome_reader_mode_black_48dp.png) = 205
+SHA256 (mozc/platforms-1.0.0.tar.gz) = 3384eb1c30762704fbe38e440204e114154086c8fc8a8c2e3e28441028c019a8
+SIZE (mozc/platforms-1.0.0.tar.gz) = 7879
+SHA256 (mozc/protobuf-34.1.bazel.tar.gz) = 9f0933ad12abb0a8957b3b64aefc34774ccbe57f77f890c66cb4067519bb83c1
+SIZE (mozc/protobuf-34.1.bazel.tar.gz) = 7038508
+SHA256 (mozc/round_settings_black_48dp.png) = c4ae8bb7992f43157be9d026f76a7039af6e0e3de0f220842208dfda8c38714a
+SIZE (mozc/round_settings_black_48dp.png) = 557
+SHA256 (mozc/rules_android-v0.7.1.tar.gz) = 7c45b6aaa837fb6f2f23ad11387638cb00fa9f839a04ec564caac70a543a9cd5
+SIZE (mozc/rules_android-v0.7.1.tar.gz) = 1308711
+SHA256 (mozc/rules_android_ndk-v0.1.5.tar.gz) = 07e7a2777113bb3d0a432265d1c78cfaa140a5bc4c82be4c8cd988b34382ec90
+SIZE (mozc/rules_android_ndk-v0.1.5.tar.gz) = 25604
+SHA256 (mozc/rules_apple.4.5.2.tar.gz) = bdac384944a8a7b555f403e10fecb25de6096ff340722e090847bfb562c0ce89
+SIZE (mozc/rules_apple.4.5.2.tar.gz) = 2481952
+SHA256 (mozc/rules_cc-0.2.17.tar.gz) = 283fa1cdaaf172337898749cf4b9b1ef5ea269da59540954e51fba0e7b8f277a
+SIZE (mozc/rules_cc-0.2.17.tar.gz) = 380004
+SHA256 (mozc/rules_go-v0.60.0.zip) = 86d3dc8f59d253524f933aaf2f3c05896cb0b605fc35b460c0b4b039996124c6
+SIZE (mozc/rules_go-v0.60.0.zip) = 2543890
+SHA256 (mozc/rules_java-9.3.0.tar.gz) = 6ef26d4f978e8b4cf5ce1d47532d70cb62cd18431227a1c8007c8f7843243c06
+SIZE (mozc/rules_java-9.3.0.tar.gz) = 116088
+SHA256 (mozc/rules_kotlin-v2.2.2.tar.gz) = 411db26afb3492cc8351b5b5349931522afe2c54f2651b6d127730a1256d0f60
+SIZE (mozc/rules_kotlin-v2.2.2.tar.gz) = 50801637
+SHA256 (mozc/rules_license-1.0.0.tar.gz) = 26d4021f6898e23b82ef953078389dd49ac2b5618ac564ade4ef87cced147b38
+SIZE (mozc/rules_license-1.0.0.tar.gz) = 35903
+SHA256 (mozc/rules_pkg-1.2.0.tar.gz) = b5c9184a23bb0bcff241981fd9d9e2a97638a1374c9953bb1808836ce711f990
+SIZE (mozc/rules_pkg-1.2.0.tar.gz) = 94391
+SHA256 (mozc/rules_python-1.9.0.tar.gz) = 098ba13578e796c00c853a2161f382647f32eb9a77099e1c88bc5299333d0d6e
+SIZE (mozc/rules_python-1.9.0.tar.gz) = 1061163
+SHA256 (mozc/rules_shell-v0.6.1.tar.gz) = e6b87c89bd0b27039e3af2c5da01147452f240f75d505f5b6880874f31036307
+SIZE (mozc/rules_shell-v0.6.1.tar.gz) = 23916
+SHA256 (mozc/rules_swift.3.5.0.tar.gz) = c98f201bc217d2ce28e01afc78b410d05c67b846c04a7095e4e701b37422ecb2
+SIZE (mozc/rules_swift.3.5.0.tar.gz) = 333115
+SHA256 (mozc/tar.bzl-v0.5.1.tar.gz) = b47e3c83a0c1440ce335aa1ae18753da6eb7cd551d4946fa303de2abde07e20b
+SIZE (mozc/tar.bzl-v0.5.1.tar.gz) = 103758
+SHA256 (mozc/legalcode.txt) = a2010f343487d3f7618affe54f789f5487602331c0a8d03f49e9a7c547cf0499
+SIZE (mozc/legalcode.txt) = 7048
+SHA256 (mozc/google-mozc-3.35.6354.101-0136c35_GH0.tar.gz) = 3f8f65c5d2f02d79ef085dfb0bde9edba3c0eb1609c8f558bd6ed24865824775
+SIZE (mozc/google-mozc-3.35.6354.101-0136c35_GH0.tar.gz) = 29185574
+SHA256 (mozc/bazelbuild-bazel-central-registry-9d03419_GH0.tar.gz) = a09506625a4c4731c427efb9f9dd54f8e5b5597a3fa42d6363339f0cc310d5f9
+SIZE (mozc/bazelbuild-bazel-central-registry-9d03419_GH0.tar.gz) = 15794804
+SHA256 (mozc/hiroyuki-komatsu-japanese-usage-dictionary-38d3462_GH0.tar.gz) = 87f2a3ff0483e932aab6ac995530ff28929b15a6b0cc0d89c6d44449771f8d89
+SIZE (mozc/hiroyuki-komatsu-japanese-usage-dictionary-38d3462_GH0.tar.gz) = 72005
+SHA256 (mozc/hiroyuki-komatsu-japanpost_zipcode-d630d72_GH0.tar.gz) = e86f1bb8e6b250537bd4c2505aa3ec266cd1b09b190b14a4892c2fb4be59ba2a
+SIZE (mozc/hiroyuki-komatsu-japanpost_zipcode-d630d72_GH0.tar.gz) = 4597398
+SHA256 (mozc/abseil-abseil-py-v2.1.0_GH0.tar.gz) = 8a3d0830e4eb4f66c4fa907c06edf6ce1c719ced811a12e26d9d3162f8471758
+SIZE (mozc/abseil-abseil-py-v2.1.0_GH0.tar.gz) = 235261
+SHA256 (mozc/bats-core-bats-core-v1.10.0_GH0.tar.gz) = a1a9f7875aa4b6a9480ca384d5865f1ccf1b0b1faead6b47aa47d79709a5c5fd
+SIZE (mozc/bats-core-bats-core-v1.10.0_GH0.tar.gz) = 159353
+SHA256 (mozc/e-kato-macuim-7beac7b_GH0.tar.gz) = 9241ae481bc15c07ab128f73fc3259c092daea1eec81ae83865ed727a4df336e
+SIZE (mozc/e-kato-macuim-7beac7b_GH0.tar.gz) = 324660
+SHA256 (mozc/fcitx-mozc-13ef96d_GH0.tar.gz) = 7b3d82b73fa7d928dfa7eec7861c9964cdfa0b72f32c092cf7b369497981e786
+SIZE (mozc/fcitx-mozc-13ef96d_GH0.tar.gz) = 29259439
diff --git a/japanese/mozc-server/files/Makefile.bazel b/japanese/mozc-server/files/Makefile.bazel
new file mode 100644
index 000000000000..4ddd35eed056
--- /dev/null
+++ b/japanese/mozc-server/files/Makefile.bazel
@@ -0,0 +1,128 @@
+BUILD_MOZC_CMD= \
+ cd ${BUILD_WRKSRC:Q} && \
+ ${SETENV} ${MAKE_ENV} PATH=/bin:/usr/bin:${PATH} \
+ ${BAZEL_CMD} \
+ build \
+ ${BAZEL_FLAGS} \
+ --repository_disable_download
+
+BAZEL_CMD?= ${LOCALBASE}/bin/bazel
+
+BAZEL_FLAGS= ${BAZEL_DISTDIR_FLAGS} \
+ --distdir="${DISTDIR}/${DIST_SUBDIR}" \
+ --registry="file://${WRKSRC_bcr}" \
+ --action_env=PATH="/bin:/usr/bin:${LOCALBASE}/bin" \
+ --jobs=${MAKE_JOBS_NUMBER} \
+ --verbose_failures \
+ --config oss_freebsd
+.if defined(DEVELOPER)
+BAZEL_FLAGS+= --sandbox_debug
+.endif
+#
+# Standard flags for compilation. Some of them
+# defined by -c opt will overridden by {C,CXX}FLAGS.
+#
+BAZEL_FLAGS+= -c opt \
+ ${CPPFLAGS:@f@--copt=${f:Q}@} \
+ ${CPPFLAGS:@f@--host_copt=${f:Q}@} \
+ ${CFLAGS:@f@--conlyopt=${f:Q}@} \
+ ${CFLAGS:@f@--host_conlyopt=${f:Q}@} \
+ ${CXXFLAGS:@f@--cxxopt=${f:Q}@} \
+ ${CXXFLAGS:@f@--host_cxxopt=${f:Q}@} \
+ ${LDFLAGS:@f@--linkopt=${f:Q}@} \
+ ${LDFLAGS:@f@--host_linkopt=${f:Q}@}
+#
+# Override modules and extra toolchains
+#
+SUB_FILES+= bazel.python.BUILD
+SUB_LIST+= PYTHON_CMD=${PYTHON_CMD}
+
+.for M in python zlib
+post-configure-$M:
+ ${MKDIR} ${BUILD_WRKSRC:Q}/bazel-${M}
+. for T in MODULE BUILD
+ if [ -r ${WRKDIR:Q}/bazel.$M.$T ]; then \
+ ${INSTALL_DATA} ${WRKDIR:Q}/bazel.$M.$T \
+ ${BUILD_WRKSRC:Q}/bazel-$M/$T.bazel; \
+ elif [ -r ${FILESDIR:Q}/bazel.$M.$T ]; then \
+ ${INSTALL_DATA} ${FILESDIR:Q}/bazel.$M.$T \
+ ${BUILD_WRKSRC:Q}/bazel-$M/$T.bazel; \
+ fi
+. endfor
+post-configure: post-configure-$M
+.endfor
+
+.for M in zlib
+BAZEL_FLAGS+= --override_module=$M=${BUILD_WRKSRC:Q}/bazel-$M
+.endfor
+BAZEL_FLAGS+= --extra_toolchains=//bazel-python:python_toolchain
+#
+# Generator of files/Makefile.distfiles
+#
+BAZEL_FETCH_LOG=${WRKDIR:Q}/bazel-fetch.log
+BAZEL_FETCH_CACHE?=${WRKDIR}/bazel-fetch-cache
+BAZEL_FETCH_OUTPUT?=${WRKDIR}/bazel-fetch-audit
+BAZEL_TARGETS?= //server:mozc_server \
+ //unix/emacs:mozc_emacs_helper \
+ //gui/tool:mozc_tool \
+ //unix/ibus:ibus_mozc \
+ //unix/ibus:gen_mozc_xml \
+ //renderer/qt:mozc_renderer
+
+BAZEL_MATRIX_WORK?= ${.CURDIR}/work-bazel-matrix
+BAZEL_BIN_DIR?= ${.CURDIR}/work-bazel-versions
+BAZEL_FETCH_FLAGS?=
+
+update-bazel-versions:
+ ${PYTHON_CMD} ${FILESDIR:Q}/bazel-fetch-matrix.py versions \
+ --ports-root ${PORTSDIR:Q}
+
+update-bazel-fetch-all:
+ ${PYTHON_CMD} ${FILESDIR:Q}/bazel-fetch-matrix.py fetch \
+ --port ${.CURDIR:Q} --bin-dir ${BAZEL_BIN_DIR:Q} \
+ --work-root ${BAZEL_MATRIX_WORK:Q}
+
+update-bazel-distfiles:
+ ${PYTHON_CMD} ${FILESDIR:Q}/bazel-fetch-matrix.py generate \
+ --work-root ${BAZEL_MATRIX_WORK:Q}
+
+verify-bazel-distfiles:
+ ${PYTHON_CMD} ${FILESDIR:Q}/bazel-fetch-matrix.py verify \
+ --port ${.CURDIR:Q} --bin-dir ${BAZEL_BIN_DIR:Q} \
+ --work-root ${BAZEL_MATRIX_WORK:Q}
+
+update-bazel-distfiles-single:
+ ${PYTHON_CMD} ${FILESDIR:Q}/bazel-fetch-log.py \
+ --bcr-root ${WRKSRC_bcr:Q} ${BAZEL_FETCH_LOG} \
+ > ${FILESDIR:Q}/Makefile.distfiles.tmp && \
+ ${MV} ${FILESDIR:Q}/Makefile.distfiles.tmp \
+ ${FILESDIR:Q}/Makefile.distfiles
+
+post-configure-bazel-distdir:
+ @set -eu; \
+ for entry in ${BAZEL_GH_DISTFILES:@f@${f:Q}@}; do \
+ src=${DISTDIR:Q}/${DIST_SUBDIR:Q}/$${entry%%:*}; \
+ dst=${WRKDIR:Q}/bazel-distdir/$${entry#*:}; \
+ if [ ! -f "$$src" ]; then \
+ echo "Missing Bazel distfile: $$src" >&2; \
+ exit 1; \
+ fi; \
+ ${MKDIR} "$${dst%/*}"; \
+ ${LN} -sf "$$src" "$$dst"; \
+ done
+
+post-configure: post-configure-bazel-distdir
+
+update-bazel-fetch: configure
+ cd ${BUILD_WRKSRC:Q} && \
+ ${SETENV} ${MAKE_ENV} PATH=/bin:/usr/bin:${PATH} \
+ ${BAZEL_CMD} \
+ --output_base=${BAZEL_FETCH_OUTPUT:Q} \
+ fetch \
+ --force \
+ ${BAZEL_FLAGS} \
+ ${BAZEL_FETCH_FLAGS} \
+ --repository_cache=${BAZEL_FETCH_CACHE:Q} \
+ --repo_contents_cache= \
+ --experimental_workspace_rules_log_file=${BAZEL_FETCH_LOG} \
+ ${BAZEL_TARGETS}
diff --git a/japanese/mozc-server/files/Makefile.distfiles b/japanese/mozc-server/files/Makefile.distfiles
new file mode 100644
index 000000000000..cede34c4afab
--- /dev/null
+++ b/japanese/mozc-server/files/Makefile.distfiles
@@ -0,0 +1,204 @@
+# Bazel versions: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# Generated from Bazel download requests; review before inclusion.
+# Keep these files out of EXTRACT_ONLY; run make makesum.
+
+# Local BCR inputs and directories for conflicting download basenames.
+BAZEL_DISTDIR_FLAGS+= --distdir="${DISTDIR}/${DIST_SUBDIR}/bazel/sha256/9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628"
+BAZEL_DISTDIR_FLAGS+= --distdir="${DISTDIR}/${DIST_SUBDIR}/bazel/sha256/a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d"
+BAZEL_DISTDIR_FLAGS+= --distdir="${DISTDIR}/${DIST_SUBDIR}/bazel/sha256/df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/abseil-cpp/20260107.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/abseil-py/2.1.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/abseil-py/2.1.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/apple_support/2.4.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/apple_support/2.4.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/apple_support/2.5.2"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/apple_support/2.5.2/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/aspect_bazel_lib/2.22.5"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/aspect_bazel_lib/2.22.5/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/bazel_features/1.42.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/bazel_features/1.42.1/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/bazel_lib/3.0.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/bazel_lib/3.0.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/bazel_skylib/1.9.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/platforms/1.0.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/protobuf/34.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_android/0.7.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_android_ndk/0.1.5"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_android_ndk/0.1.5/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_apple/4.5.2"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_apple/4.5.2/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_cc/0.2.17"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_cc/0.2.17/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_go/0.60.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_go/0.60.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_java/9.3.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_kotlin/2.2.2"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_kotlin/2.2.2/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_license/1.0.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_pkg/1.2.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_python/1.9.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_python/1.9.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_shell/0.6.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_shell/0.6.1/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_swift/3.5.0"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/rules_swift/3.5.0/patches"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/tar.bzl/0.5.1"
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKSRC_bcr}/modules/tar.bzl/0.5.1/patches"
+
+.if !defined(USE_GITHUB)
+USE_GITHUB= nodefault
+.endif
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:8a3d0830e4eb4f66c4fa907c06edf6ce1c719ced811a12e26d9d3162f8471758
+# Bazel URL: https://github.com/abseil/abseil-py/archive/refs/tags/v2.1.0.tar.gz
+GH_TUPLE+= abseil:abseil-py:v2.1.0:bazelgh0001
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKDIR}/bazel-distdir/bazelgh0001"
+BAZEL_GH_DISTFILES+= ${DISTFILE_bazelgh0001}:bazelgh0001/v2.1.0.tar.gz
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:a1a9f7875aa4b6a9480ca384d5865f1ccf1b0b1faead6b47aa47d79709a5c5fd
+# Bazel URL: https://github.com/bats-core/bats-core/archive/v1.10.0.tar.gz
+GH_TUPLE+= bats-core:bats-core:v1.10.0:bazelgh0002
+BAZEL_DISTDIR_FLAGS+= --distdir="${WRKDIR}/bazel-distdir/bazelgh0002"
+BAZEL_GH_DISTFILES+= ${DISTFILE_bazelgh0002}:bazelgh0002/v1.10.0.tar.gz
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/src/action/settings/materialiconsround/24px.svg?dummy=/:bazelfetch0001
+DISTFILES+= bazel/sha256/9b01b133be1caffc680f132d385d0e594262d6cfd29759a63c428050b83fe628/24px.svg:bazelfetch0001
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/src/action/chrome_reader_mode/materialiconsoutlined/24px.svg?dummy=/:bazelfetch0002
+DISTFILES+= bazel/sha256/a4c7b9bfb442a7497b72d74358c31034c4fef1ab2a50659834784580751ac04d/24px.svg:bazelfetch0002
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/src/action/build/materialicons/24px.svg?dummy=/:bazelfetch0003
+DISTFILES+= bazel/sha256/df34fba3d09778db69503a23b688761051dbf65b5bccb0d7b729c69ff61c3804/24px.svg:bazelfetch0003
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:4314e2a7cbac89cac25a2f2322870f343d81579756ceff7f431803c2c9090195
+MASTER_SITES+= https://github.com/abseil/abseil-cpp/releases/download/20260107.1/:bazelfetch0004
+DISTFILES+= abseil-cpp-20260107.1.tar.gz:bazelfetch0004
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0
+# sha256:9f2ee0d23bf46b1c8ac88cea73ab13d415f340ec777e1e68841e09153880a67e
+MASTER_SITES+= https://github.com/bazelbuild/apple_support/releases/download/2.4.0/:bazelfetch0005
+DISTFILES+= apple_support.2.4.0.tar.gz:bazelfetch0005
+
+# Required by Bazel: 9.3.0
+# sha256:ce4fc3e360c151af7c142da190abd4cfb49ca90aa833291d136afa05e94ba4ea
+MASTER_SITES+= https://github.com/bazelbuild/apple_support/releases/download/2.5.2/:bazelfetch0006
+DISTFILES+= apple_support.2.5.2.tar.gz:bazelfetch0006
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:269433bf6d6948a93ab6a57a73ceb5930870223046052cfffe01eeca37327d3e
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/png/action/build/materialicons/48dp/1x/:bazelfetch0007
+DISTFILES+= baseline_build_black_48dp.png:bazelfetch0007
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:94e192033ca8027f26de71c9000a67ef9c73695c2b88e2c559045170917ead0c
+MASTER_SITES+= https://github.com/bazel-contrib/bazel-lib/releases/download/v2.22.5/:bazelfetch0008
+DISTFILES+= bazel-lib-v2.22.5.tar.gz:bazelfetch0008
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:6fd3b1e1a38ca744f9664be4627ced80895c7d2ee353891c172f1ab61309c933
+MASTER_SITES+= https://github.com/bazel-contrib/bazel-lib/releases/download/v3.0.0/:bazelfetch0009
+DISTFILES+= bazel-lib-v3.0.0.tar.gz:bazelfetch0009
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:3b5b49006181f5f8ff626ef8ddceaa95e9bb8ad294f7b5d7b11ea9f7ddaf8c59
+MASTER_SITES+= https://github.com/bazelbuild/bazel-skylib/releases/download/1.9.0/:bazelfetch0010
+DISTFILES+= bazel-skylib-1.9.0.tar.gz:bazelfetch0010
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:8189bac9a6bf9cc155a854c4cbebfebf58b9ca7a2d0a67645f7d0c1f83c523ac
+MASTER_SITES+= https://github.com/bazel-contrib/bazel_features/releases/download/v1.42.1/:bazelfetch0011
+DISTFILES+= bazel_features-v1.42.1.tar.gz:bazelfetch0011
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:6d2ac7befa038d4f32e07136293acaf5d8645a4daecb6d063f34be2ffea59b55
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/png/action/chrome_reader_mode/materialiconsoutlined/48dp/1x/:bazelfetch0012
+DISTFILES+= outline_chrome_reader_mode_black_48dp.png:bazelfetch0012
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:3384eb1c30762704fbe38e440204e114154086c8fc8a8c2e3e28441028c019a8
+MASTER_SITES+= https://github.com/bazelbuild/platforms/releases/download/1.0.0/:bazelfetch0013
+DISTFILES+= platforms-1.0.0.tar.gz:bazelfetch0013
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:9f0933ad12abb0a8957b3b64aefc34774ccbe57f77f890c66cb4067519bb83c1
+MASTER_SITES+= https://github.com/protocolbuffers/protobuf/releases/download/v34.1/:bazelfetch0014
+DISTFILES+= protobuf-34.1.bazel.tar.gz:bazelfetch0014
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:c4ae8bb7992f43157be9d026f76a7039af6e0e3de0f220842208dfda8c38714a
+MASTER_SITES+= https://raw.githubusercontent.com/google/material-design-icons/4.0.0/png/action/settings/materialiconsround/48dp/1x/:bazelfetch0015
+DISTFILES+= round_settings_black_48dp.png:bazelfetch0015
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:7c45b6aaa837fb6f2f23ad11387638cb00fa9f839a04ec564caac70a543a9cd5
+MASTER_SITES+= https://github.com/bazelbuild/rules_android/releases/download/v0.7.1/:bazelfetch0016
+DISTFILES+= rules_android-v0.7.1.tar.gz:bazelfetch0016
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:07e7a2777113bb3d0a432265d1c78cfaa140a5bc4c82be4c8cd988b34382ec90
+MASTER_SITES+= https://github.com/bazelbuild/rules_android_ndk/releases/download/v0.1.5/:bazelfetch0017
+DISTFILES+= rules_android_ndk-v0.1.5.tar.gz:bazelfetch0017
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:bdac384944a8a7b555f403e10fecb25de6096ff340722e090847bfb562c0ce89
+MASTER_SITES+= https://github.com/bazelbuild/rules_apple/releases/download/4.5.2/:bazelfetch0018
+DISTFILES+= rules_apple.4.5.2.tar.gz:bazelfetch0018
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:283fa1cdaaf172337898749cf4b9b1ef5ea269da59540954e51fba0e7b8f277a
+MASTER_SITES+= https://github.com/bazelbuild/rules_cc/releases/download/0.2.17/:bazelfetch0019
+DISTFILES+= rules_cc-0.2.17.tar.gz:bazelfetch0019
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:86d3dc8f59d253524f933aaf2f3c05896cb0b605fc35b460c0b4b039996124c6
+MASTER_SITES+= https://github.com/bazel-contrib/rules_go/releases/download/v0.60.0/:bazelfetch0020
+DISTFILES+= rules_go-v0.60.0.zip:bazelfetch0020
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:6ef26d4f978e8b4cf5ce1d47532d70cb62cd18431227a1c8007c8f7843243c06
+MASTER_SITES+= https://github.com/bazelbuild/rules_java/releases/download/9.3.0/:bazelfetch0021
+DISTFILES+= rules_java-9.3.0.tar.gz:bazelfetch0021
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:411db26afb3492cc8351b5b5349931522afe2c54f2651b6d127730a1256d0f60
+MASTER_SITES+= https://github.com/bazelbuild/rules_kotlin/releases/download/v2.2.2/:bazelfetch0022
+DISTFILES+= rules_kotlin-v2.2.2.tar.gz:bazelfetch0022
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:26d4021f6898e23b82ef953078389dd49ac2b5618ac564ade4ef87cced147b38
+MASTER_SITES+= https://github.com/bazelbuild/rules_license/releases/download/1.0.0/:bazelfetch0023
+DISTFILES+= rules_license-1.0.0.tar.gz:bazelfetch0023
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:b5c9184a23bb0bcff241981fd9d9e2a97638a1374c9953bb1808836ce711f990
+MASTER_SITES+= https://github.com/bazelbuild/rules_pkg/releases/download/1.2.0/:bazelfetch0024
+DISTFILES+= rules_pkg-1.2.0.tar.gz:bazelfetch0024
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:098ba13578e796c00c853a2161f382647f32eb9a77099e1c88bc5299333d0d6e
+MASTER_SITES+= https://github.com/bazel-contrib/rules_python/releases/download/1.9.0/:bazelfetch0025
+DISTFILES+= rules_python-1.9.0.tar.gz:bazelfetch0025
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:e6b87c89bd0b27039e3af2c5da01147452f240f75d505f5b6880874f31036307
+MASTER_SITES+= https://github.com/bazelbuild/rules_shell/releases/download/v0.6.1/:bazelfetch0026
+DISTFILES+= rules_shell-v0.6.1.tar.gz:bazelfetch0026
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:c98f201bc217d2ce28e01afc78b410d05c67b846c04a7095e4e701b37422ecb2
+MASTER_SITES+= https://github.com/bazelbuild/rules_swift/releases/download/3.5.0/:bazelfetch0027
+DISTFILES+= rules_swift.3.5.0.tar.gz:bazelfetch0027
+
+# Required by Bazel: 9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0
+# sha256:b47e3c83a0c1440ce335aa1ae18753da6eb7cd551d4946fa303de2abde07e20b
+MASTER_SITES+= https://github.com/bazel-contrib/tar.bzl/releases/download/v0.5.1/:bazelfetch0028
+DISTFILES+= tar.bzl-v0.5.1.tar.gz:bazelfetch0028
diff --git a/japanese/mozc-server/files/bazel-fetch-log.py b/japanese/mozc-server/files/bazel-fetch-log.py
new file mode 100644
index 000000000000..8d041f152928
--- /dev/null
+++ b/japanese/mozc-server/files/bazel-fetch-log.py
@@ -0,0 +1,343 @@
+#!/usr/bin/env python3
+"""Convert a binary Bazel workspace-rules log to FreeBSD Ports definitions.
+
+Usage: python3 files/bazel-fetch-log.py work/*/bazel-fetch.log > Makefile.distfiles
+
+Multiple logs are merged before deduplication and filename-collision handling.
+Use bazel-fetch-matrix.py for collection and checked publication of all supported
+Bazel versions. Direct log conversion does not validate collection completeness.
+
+Input is --experimental_workspace_rules_log_file output, NOT parser text.
+Only Python's standard library is required. The wire-format reader implements
+the relevant fields of Bazel 9.2.0's workspace_log.proto:
+https://github.com/bazelbuild/bazel/blob/9.2.0/src/main/java/com/google/devtools/build/lib/bazel/debug/workspace_log.proto
+
+Download events record requests, not success. Cached/skipped repository rules
+and downloads performed by external commands may be absent. Review the result,
+keep these files out of EXTRACT_ONLY, run make makesum, and test offline.
+GitHub /archive/*.tar.gz URLs use GH_TUPLE; all other URLs use MASTER_SITES
+and DISTFILES. Stage GitHub distfiles under Bazel's original basenames and
+verify the hashes before offline use. ZIP files are never converted.
+Query URLs use Ports' &dummy=/ convention and the logged output basename
+when the URL has none. Unchecksummed metadata needs separate Bazel handling.
+Conflicting basenames with SHA256 checksums are stored in separate
+bazel/sha256/<digest>/ directories and emit additional BAZEL_DISTDIR_FLAGS.
+Local BCR downloads emit deduplicated BAZEL_DISTDIR_FLAGS using ${WRKSRC_bcr}.
+Use --bcr-root for an explicit registry path; otherwise a directory named
+bazel-central-registry or bazel-central-registry-* is inferred from file URLs.
+"""
+
+import argparse
+import base64
+import binascii
+import re
+import sys
+from pathlib import Path
+from urllib.parse import unquote, urlsplit
+
+
+def varint(data, pos):
+ """Read an unsigned protobuf varint, rejecting truncation and overflow."""
+ value = 0
+ for shift in range(0, 70, 7):
+ if pos >= len(data):
+ raise ValueError("truncated protobuf varint")
+ byte = data[pos]
+ pos += 1
+ if shift == 63 and byte > 1:
+ raise ValueError("protobuf varint overflow")
+ value |= (byte & 127) << shift
+ if byte < 128:
+ return value, pos
+ raise ValueError("invalid protobuf varint")
+
+
+def fields(data):
+ """Yield length-delimited fields; safely skip other supported wire types."""
+ pos = 0
+ while pos < len(data):
+ tag, pos = varint(data, pos)
+ number, wire = tag >> 3, tag & 7
+ if not 0 < number < 2**29:
+ raise ValueError("invalid protobuf field number")
+ if wire == 0:
+ _, pos = varint(data, pos)
+ elif wire in (1, 2, 5):
+ if wire == 2:
+ size, pos = varint(data, pos)
+ else:
+ size = 8 if wire == 1 else 4
+ end = pos + size
+ if end > len(data):
+ raise ValueError("truncated protobuf field")
+ if wire == 2:
+ yield number, data[pos:end]
+ pos = end
+ else:
+ raise ValueError(f"unsupported protobuf wire type {wire}")
+
+
+def downloads(data):
+ pos = 0
+ while pos < len(data):
+ offset = pos
+ size, pos = varint(data, pos)
+ end = pos + size
+ if end > len(data):
+ raise ValueError(f"truncated WorkspaceEvent at byte {offset}")
+ for number, event in fields(data[pos:end]):
+ if number not in (4, 5):
+ continue
+ values = {}
+ # Download.integrity = 5; DownloadAndExtract.integrity = 6.
+ integrity_field = 5 if number == 4 else 6
+ for key, raw in fields(event):
+ if key in (1, 2, 3, integrity_field):
+ values.setdefault(key, []).append(raw.decode("utf-8"))
+ yield (values.get(1, []), values.get(3, [""])[-1],
+ values.get(integrity_field, [""])[-1],
+ values.get(2, [""])[-1])
+ pos = end
+
+
+def checksum(sha256, integrity):
+ """Normalize SHA256/SRI for duplicate and filename-collision detection."""
+ if sha256 and not re.fullmatch(r"[0-9a-fA-F]{64}", sha256):
+ raise ValueError(f"invalid SHA256: {sha256!r}")
+ sha256 = sha256.lower()
+ tokens = integrity.split()
+ for token in tokens:
+ if token.startswith("sha256-"):
+ try:
+ digest = base64.b64decode(token[7:], validate=True)
+ except binascii.Error as exc:
+ raise ValueError("invalid SHA256 integrity") from exc
+ if len(digest) != 32 or (sha256 and sha256 != digest.hex()):
+ raise ValueError("inconsistent SHA256 and integrity")
+ sha256 = digest.hex()
+ return "sha256:" + sha256 if sha256 else " ".join(sorted(tokens))
+
+
+def github_tuple(url):
+ """Recognize GitHub-generated tar.gz archives, not release assets or ZIPs."""
+ parsed = urlsplit(url)
+ if (parsed.scheme not in ("http", "https") or parsed.netloc != "github.com"
+ or parsed.query or parsed.fragment):
+ return None
+ match = re.fullmatch(
+ r"/([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)/archive/(?:refs/tags/)?(.+)\.tar\.gz",
+ parsed.path,
+ )
+ if not match:
+ return None
+ account, project, ref = match.groups()
+ ref = unquote(ref)
+ if not re.fullmatch(r"[A-Za-z0-9_+.-]+(?:/[A-Za-z0-9_+.-]+)*", ref):
+ raise ValueError(f"ref cannot be represented safely in GH_TUPLE: {url!r}")
+ return account, project, ref
+
+
+def bcr_distdir(url, bcr_root):
+ """Return a relocatable parent directory for a local registry input."""
+ parsed = urlsplit(url)
+ if parsed.netloc not in ("", "localhost") or parsed.query or parsed.fragment:
+ raise ValueError(f"unsupported local file URL: {url!r}")
+ path = Path(unquote(parsed.path))
+ if not path.is_absolute():
+ raise ValueError(f"file URL must be absolute: {url!r}")
+ path = path.resolve()
+ if bcr_root is None:
+ bcr_root = next((parent for parent in path.parents
+ if parent.name == "bazel-central-registry"
+ or parent.name.startswith("bazel-central-registry-")), None)
+ if bcr_root is None:
+ return None
+ try:
+ relative = path.relative_to(bcr_root)
+ except ValueError:
+ return None
+ directory = relative.parent.as_posix()
+ if not re.fullmatch(r"[A-Za-z0-9_./+-]+", directory):
+ raise ValueError(f"BCR path needs manual Makefile handling: {url!r}")
+ return "${WRKSRC_bcr}" + ("/" + directory if directory != "." else "")
+
+
+def definitions(data, bcr_root=None):
+ """Merge streams before assigning names, groups, and collision directories."""
+ entries = {}
+ github = {}
+ distdirs = set()
+ if bcr_root is not None:
+ bcr_root = Path(bcr_root).resolve()
+ warnings = set()
+ count = 0
+ streams = [data] if isinstance(data, bytes) else data
+ for urls, sha256, integrity, output in (event for stream in streams
+ for event in downloads(stream)):
+ count += 1
+ digest = checksum(sha256, integrity)
+
+ # rules_go optionally queries this mutable SDK index.
+ # Without a checksum, --distdir cannot satisfy this request.
+ go_sdk_indexes = {
+ "https://go.dev/dl/?mode=json&include=all",
+ "https://golang.google.cn/dl/?mode=json&include=all",
+ }
+ if (
+ not digest
+ and urls
+ and all(url in go_sdk_indexes for url in urls)
+ ):
+ warnings.add(
+ "Omitted optional Go SDK version index from DISTFILES; "
+ "verify the required targets with downloads disabled."
+ )
+ continue
+
+ remote = []
+ for url in urls:
+ parsed = urlsplit(url)
+ if parsed.scheme == "file":
+ directory = bcr_distdir(url, bcr_root)
+ if directory is None:
+ warnings.add(f"Local input outside the BCR was omitted: {url}; "
+ "use --bcr-root if this is registry data.")
+ else:
+ distdirs.add(directory)
+ continue
+ if parsed.scheme not in ("http", "https", "ftp"):
+ raise ValueError(f"unsupported download URL: {url!r}")
+ # Reject syntax that cannot safely be pasted into a Ports Makefile.
+ if (not parsed.netloc or parsed.username is not None
+ or parsed.fragment
+ or re.search(r'[\s$#\\\x00-\x1f\x7f]', url)
+ or "%SUBDIR%" in url):
+ raise ValueError(f"URL needs manual MASTER_SITES handling: {url!r}")
+ name = parsed.path.rsplit("/", 1)[-1]
+ if not name and parsed.query:
+ name = output.rsplit("/", 1)[-1]
+ if not re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._+%-]*", name):
+ raise ValueError(f"unsafe or missing distfile name: {url!r}")
+ remote.append((name, url))
+ if not remote:
+ continue
+ tuples = {github_tuple(url) for _, url in remote} - {None}
+ if len(tuples) > 1:
+ raise ValueError("download mirrors refer to different GitHub archives")
+ if tuples:
+ key = tuples.pop()
+ if key in github:
+ old_digest, sources = github[key]
+ if old_digest != digest:
+ raise ValueError(f"conflicting checksums for GitHub archive {key!r}")
+ sources.update(url for _, url in remote)
+ else:
+ github[key] = (digest, {url for _, url in remote})
+ if not digest:
+ warnings.add(f"{key}: no checksum in log; verify the GitHub archive before make makesum.")
+ continue
+ name = remote[0][0]
+ sources = {url for n, url in remote if n == name}
+ if any(n != name for n, _ in remote):
+ warnings.add(f"{name}: mirrors with different basenames were omitted.")
+ variants = entries.setdefault(name, {})
+ if digest in variants:
+ if not digest and not variants[digest].intersection(sources):
+ raise ValueError(f"conflicting downloads named {name!r} without SHA256; "
+ "rename/stage them explicitly")
+ variants[digest].update(sources)
+ else:
+ variants[digest] = sources
+ if not digest:
+ warnings.add(f"{name}: no checksum in log; verify the fetched file before make makesum.")
+ if any(urlsplit(url).query for _, url in remote):
+ warnings.add(f"{name}: unchecksummed query metadata cannot be supplied via --distdir alone; "
+ "pin its contents and checksum in the Bazel rule or avoid this lookup.")
+ if not count:
+ raise ValueError("no download events found (expected a binary Bazel workspace-rules log)")
+ distfiles = []
+ for name, variants in sorted(entries.items()):
+ conflicting = len(variants) > 1
+ for digest, sources in sorted(variants.items()):
+ filename = name
+ if conflicting:
+ if not re.fullmatch(r"sha256:[0-9a-f]{64}", digest):
+ raise ValueError(f"conflicting downloads named {name!r} without SHA256; "
+ "rename/stage them explicitly")
+ directory = "bazel/sha256/" + digest.removeprefix("sha256:")
+ filename = directory + "/" + name
+ distdirs.add("${DISTDIR}/${DIST_SUBDIR}/" + directory)
+ # do-fetch.sh strips ?dummy=/ or &dummy=/ and uses -o to save
+ # the exact URL under the DISTFILES path, including subdirectories.
+ sites = {url + ("&dummy=/" if urlsplit(url).query else "?dummy=/")
+ if conflicting or urlsplit(url).query
+ else url.rsplit("/", 1)[0] + "/"
+ for url in sources}
+ distfiles.append((filename, digest, sites))
+ lines = ["# Generated from Bazel download requests; review before inclusion.",
+ "# Keep these files out of EXTRACT_ONLY; run make makesum."]
+ if distdirs:
+ lines += ["", "# Local BCR inputs and directories for conflicting download basenames."]
+ for directory in sorted(distdirs):
+ lines.append(f'BAZEL_DISTDIR_FLAGS+=\t--distdir="{directory}"')
+ if github:
+ lines += ["", ".if !defined(USE_GITHUB)", "USE_GITHUB=\tnodefault", ".endif"]
+ for index, (key, (digest, sources)) in enumerate(sorted(github.items()), 1):
+ group = f"bazelgh{index:04d}"
+ lines.append("")
+ if digest:
+ lines.append(f"# {digest}")
+ for url in sorted(sources):
+ lines.append(f"# Bazel URL: {url}")
+ lines.append(f"GH_TUPLE+=\t{':'.join(key)}:{group}")
+ lines.append(
+ f'BAZEL_DISTDIR_FLAGS+=\t--distdir="${{WRKDIR}}/bazel-distdir/{group}"'
+ )
+ names = sorted({
+ urlsplit(url).path.rsplit("/", 1)[-1]
+ for url in sources
+ })
+ for name in names:
+ lines.append(
+ f"BAZEL_GH_DISTFILES+=\t"
+ f"${{DISTFILE_{group}}}:{group}/{name}"
+ )
+ for index, (name, digest, sites) in enumerate(distfiles, 1):
+ group = f"bazelfetch{index:04d}"
+ lines.append("")
+ if digest:
+ lines.append(f"# {digest}")
+ for site in sorted(sites):
+ lines.append(f"MASTER_SITES+=\t{site}:{group}")
+ lines.append(f"DISTFILES+=\t{name}:{group}")
+ return "\n".join(lines) + "\n", warnings, len(distfiles) + len(github)
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument("logfile", type=Path, nargs="+",
+ help="binary Bazel workspace-rules logs to merge")
+ parser.add_argument("--bcr-root", type=Path,
+ help="local registry root to replace with ${WRKSRC_bcr}")
+ args = parser.parse_args()
+ try:
+ streams = [path.read_bytes() for path in args.logfile]
+ # Reject an empty input even if another log contains download events.
+ for path, stream in zip(args.logfile, streams):
+ if not any(downloads(stream)):
+ raise ValueError(f"no download events in {path}")
+ output, warnings, count = definitions(streams, args.bcr_root)
+ except (OSError, ValueError) as exc:
+ print(f"{parser.prog}: error: {exc}", file=sys.stderr)
+ return 1
+ for warning in sorted(warnings):
+ print(f"warning: {warning}", file=sys.stderr)
+ print(f"{count} distfiles; requests in this log may be incomplete or unsuccessful.",
+ file=sys.stderr)
+ sys.stdout.write(output)
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/japanese/mozc-server/files/bazel-fetch-matrix.py b/japanese/mozc-server/files/bazel-fetch-matrix.py
new file mode 100644
index 000000000000..d7496a2971af
--- /dev/null
+++ b/japanese/mozc-server/files/bazel-fetch-matrix.py
@@ -0,0 +1,222 @@
+#!/usr/bin/env python3
+"""Collect independent Bazel fetch logs and atomically generate their union.
+
+Provision FreeBSD Bazel executables in BIN_DIR/VERSION/bazel first. Historical
+port commits are recorded in bazel-versions.json; no installed package is changed.
+Use `versions --ports-root /usr/ports` to refresh that list from Git history.
+Use `fetch --bin-dir ... --work-root ...` then `generate --work-root ...`.
+A successful fetch publishes a manifest only after every version succeeds.
+
+The corresponding port targets are update-bazel-versions, update-bazel-fetch-all,
+and update-bazel-distfiles. Set BAZEL_BIN_DIR to the executable directory; each
+VERSION/bazel may be a symlink. Run make makesum after generation and verify
+with verify-bazel-distfiles: it fetches the same targets with fresh output and
+download caches, the repo contents cache disabled, and downloads forbidden.
+"""
+
+import argparse
+import hashlib
+import importlib.util
+import json
+from pathlib import Path
+import re
+import shlex
+import subprocess
+import sys
+import tempfile
+
+HERE = Path(__file__).resolve().parent
+sys.dont_write_bytecode = True
+
+
+def atomic_write(path, content):
+ path = Path(path)
+ with tempfile.NamedTemporaryFile(mode="w", dir=path.parent,
+ prefix=path.name + ".", delete=False) as out:
+ temporary = Path(out.name)
+ try:
+ out.write(content)
+ out.close()
+ temporary.chmod(path.stat().st_mode & 0o777 if path.exists() else 0o644)
+ temporary.replace(path)
+ finally:
+ temporary.unlink(missing_ok=True)
+
+
+def digest(path):
+ return hashlib.sha256(Path(path).read_bytes()).hexdigest()
+
+
+def inputs(port):
+ """Detect source/patch changes between collection and publication."""
+ paths = [port / "Makefile", *(port / "files").iterdir()]
+ return {str(path.relative_to(port)): digest(path) for path in sorted(paths)
+ if path.is_file() and path.name != "Makefile.distfiles"}
+
+
+def version_list(path):
+ entries = json.loads(Path(path).read_text())
+ versions = [entry["version"] for entry in entries]
+ if (not versions or len(versions) != len(set(versions))
+ or any(not re.fullmatch(r"9\.\d+\.\d+", v) for v in versions)):
+ raise ValueError("expected a nonempty list of distinct Bazel 9 versions")
+ return entries
+
+
+def history(root):
+ def git(*args):
+ return subprocess.check_output(["git", "-C", str(root), *args], text=True)
+ commits = git("log", "--reverse", "--format=%H", "--",
+ "devel/bazel9/Makefile").splitlines()
+ entries = {}
+ for commit in commits:
+ contents = git("show", f"{commit}:devel/bazel9/Makefile")
+ match = re.search(r"^DISTVERSION=\s*(9\.\d+\.\d+)\s*$", contents, re.M)
+ if not match:
+ raise ValueError(f"cannot read DISTVERSION at {commit}")
+ entries.setdefault(match[1], {"version": match[1], "commit": commit})
+ return sorted(entries.values(), key=lambda e: tuple(map(int, e["version"].split("."))))
+
+
+def collect(args, offline=False):
+ entries = version_list(args.versions)
+ original_inputs = inputs(args.port)
+ protected = {"WRKDIR", "BAZEL_CMD", "BAZEL_FETCH_LOG", "BAZEL_FETCH_OUTPUT",
+ "BAZEL_FETCH_CACHE", "BAZEL_FETCH_FLAGS"}
+ for argument in args.make_arg:
+ name, separator, _ = argument.partition("=")
+ if not separator or not re.fullmatch(r"[A-Z_][A-Z_0-9]*", name) or name in protected:
+ raise ValueError(f"unsupported make assignment: {argument}")
+ # Check all executables before starting potentially expensive fetches.
+ for entry in entries:
+ executable = (args.bin_dir / entry["version"] / "bazel").resolve()
+ actual = subprocess.check_output([str(executable), "--version"], text=True).strip()
+ if actual != "bazel " + entry["version"]:
+ raise ValueError(f"{executable}: expected bazel {entry['version']}, got {actual}")
+ entry["executable"] = str(executable)
+ args.work_root.mkdir(parents=True, exist_ok=True)
+ if offline:
+ previous = json.loads((args.work_root / "manifest.json").read_text())["versions"]
+ if [e["version"] for e in previous] != [e["version"] for e in entries]:
+ raise ValueError("collect all supported versions before verification")
+ workdirs = {e["version"]: Path(e["log"]).parent for e in previous}
+ prefix = "verify-" if offline else "run-"
+ run = Path(tempfile.mkdtemp(prefix=prefix, dir=args.work_root)).resolve()
+ pending = args.work_root / "pending"
+ if not offline:
+ atomic_write(pending, str(run) + "\n")
+ for entry in entries:
+ version = entry["version"]
+ work = workdirs[version] if offline else run / version
+ console = run / (version + ".console.log")
+ print(f"Fetching with Bazel {version}; log: {console}", flush=True)
+ executable = shlex.quote(entry["executable"])
+ extra = []
+ if offline:
+ extra = ["post-configure-bazel-distdir",
+ "BAZEL_FETCH_LOG=" + str(run / (version + ".fetch.log")),
+ "BAZEL_FETCH_OUTPUT=" + str(run / version / "output"),
+ "BAZEL_FETCH_FLAGS=--repository_disable_download"]
+ command = [args.make, "-C", str(args.port), *extra, "update-bazel-fetch",
+ f"BAZEL_CMD={executable}", f"WRKDIR={work}",
+ *args.make_arg]
+ if offline:
+ # The normal fetch recipe also disables the repo contents cache.
+ # Override its download cache without changing the source tree.
+ command.append("BAZEL_FETCH_CACHE=" + str(run / version / "cache"))
+ with console.open("w") as out:
+ subprocess.run(command, stdout=out, stderr=subprocess.STDOUT, check=True)
+ logfile = run / (version + ".fetch.log") if offline else work / "bazel-fetch.log"
+ entry["log"] = str(logfile)
+ entry["sha256"] = digest(logfile)
+ if original_inputs != inputs(args.port):
+ raise ValueError("port inputs changed during collection; rerun fetch")
+ if offline:
+ atomic_write(run / "verified.json", json.dumps(entries, indent=2) + "\n")
+ print(f"Offline fetch passed for all {len(entries)} versions; results: {run}")
+ return
+ manifest = {"schema": 1, "versions": entries, "inputs": original_inputs}
+ atomic_write(args.work_root / "manifest.json", json.dumps(manifest, indent=2) + "\n")
+ pending.unlink()
+
+
+def generate(args):
+ if (args.work_root / "pending").exists():
+ raise ValueError("latest collection did not finish; rerun fetch before generating")
+ expected = version_list(args.versions)
+ manifest = json.loads((args.work_root / "manifest.json").read_text())
+ entries = manifest["versions"]
+ if (manifest.get("schema") != 1
+ or [(e["version"], e["commit"]) for e in entries]
+ != [(e["version"], e["commit"]) for e in expected]):
+ raise ValueError("manifest does not match the supported version list; rerun fetch")
+ if manifest["inputs"] != inputs(args.port):
+ raise ValueError("port inputs changed since collection; rerun fetch")
+ spec = importlib.util.spec_from_file_location("fetch_log", HERE / "bazel-fetch-log.py")
+ parser = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(parser)
+ streams = []
+ required_by = {}
+ for entry in entries:
+ path = Path(entry["log"])
+ if digest(path) != entry["sha256"]:
+ raise ValueError(f"log changed since successful fetch: {path}")
+ stream = path.read_bytes()
+ if not any(parser.downloads(stream)):
+ raise ValueError(f"no download events: {path}")
+ for urls, sha256, integrity, _ in parser.downloads(stream):
+ key = parser.checksum(sha256, integrity)
+ if key:
+ required_by.setdefault(key, set()).add(entry["version"])
+ streams.append(stream)
+ # Infer each local BCR root from its URL, as every run has a separate WRKDIR.
+ output, warnings, count = parser.definitions(streams)
+ lines = []
+ for line in output.splitlines():
+ if line.startswith("# ") and line[2:] in required_by:
+ versions = sorted(required_by[line[2:]],
+ key=lambda v: tuple(map(int, v.split("."))))
+ lines.append("# Required by Bazel: " + ", ".join(versions))
+ lines.append(line)
+ output = "\n".join(lines) + "\n"
+ provenance = "# Bazel versions: " + ", ".join(e["version"] for e in entries) + "\n"
+ for warning in sorted(warnings):
+ print("warning: " + warning, file=sys.stderr)
+ atomic_write(args.output, provenance + output)
+ print(f"Generated {args.output}: {count} distfiles from {len(entries)} Bazel versions")
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument("action", choices=("versions", "fetch", "generate", "verify"))
+ parser.add_argument("--versions", type=Path, default=HERE / "bazel-versions.json")
+ parser.add_argument("--ports-root", type=Path, default=HERE.parents[2])
+ parser.add_argument("--port", type=Path, default=HERE.parent)
+ parser.add_argument("--bin-dir", type=Path)
+ parser.add_argument("--work-root", type=Path, default=HERE.parent / "work-bazel-matrix")
+ parser.add_argument("--output", type=Path, default=HERE / "Makefile.distfiles")
+ parser.add_argument("--make", default="make")
+ parser.add_argument("--make-arg", action="append", default=[],
+ help="extra make variable assignment, e.g. MAKE_JOBS_NUMBER=4")
+ args = parser.parse_args()
+ try:
+ if args.action == "versions":
+ entries = history(args.ports_root)
+ if not entries:
+ raise ValueError("no Bazel 9 versions found in Git history")
+ atomic_write(args.versions, json.dumps(entries, indent=2) + "\n")
+ elif args.action in ("fetch", "verify"):
+ if args.bin_dir is None:
+ parser.error("fetch requires --bin-dir")
+ collect(args, offline=args.action == "verify")
+ else:
+ generate(args)
+ except (OSError, ValueError, KeyError, subprocess.CalledProcessError) as exc:
+ print(f"{parser.prog}: {exc}", file=sys.stderr)
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/japanese/mozc-server/files/bazel-versions.json b/japanese/mozc-server/files/bazel-versions.json
new file mode 100644
index 000000000000..9d021241cd43
--- /dev/null
+++ b/japanese/mozc-server/files/bazel-versions.json
@@ -0,0 +1,22 @@
+[
+ {
+ "version": "9.0.1",
+ "commit": "0130386c6903257df345990069a5aa8edcb0a848"
+ },
+ {
+ "version": "9.1.0",
+ "commit": "83d8a324ee192af252dfd10d6d087c7ddd23db8d"
+ },
+ {
+ "version": "9.1.1",
+ "commit": "3c288518d2cf075cb26362e8782d5d962204231c"
+ },
+ {
+ "version": "9.2.0",
+ "commit": "f034f2f2da5189f71abf1e004f3bb8c7a562609e"
+ },
+ {
+ "version": "9.3.0",
+ "commit": "f24c69c8f6bfde8ab8f76955355abcb9eb3fe5fb"
+ }
+]
diff --git a/japanese/mozc-server/files/bazel.python.BUILD.in b/japanese/mozc-server/files/bazel.python.BUILD.in
new file mode 100644
index 000000000000..02c2e786e1e6
--- /dev/null
+++ b/japanese/mozc-server/files/bazel.python.BUILD.in
@@ -0,0 +1,22 @@
+load("@rules_python//python:py_runtime.bzl", "py_runtime")
+load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair")
+
+package(default_visibility = ["//visibility:public"])
+
+py_runtime(
+ name = "runtime",
+ interpreter_path = "%%PYTHON_CMD%%",
+ python_version = "PY3",
+ stub_shebang = "#!%%PYTHON_CMD%%",
+)
+
+py_runtime_pair(
+ name = "runtime_pair",
+ py3_runtime = ":runtime",
+)
+
+toolchain(
+ name = "python_toolchain",
+ toolchain = ":runtime_pair",
+ toolchain_type = "@rules_python//python:toolchain_type",
+)
diff --git a/japanese/mozc-server/files/bazel.zlib.BUILD b/japanese/mozc-server/files/bazel.zlib.BUILD
new file mode 100644
index 000000000000..b2d4bf25bb1e
--- /dev/null
+++ b/japanese/mozc-server/files/bazel.zlib.BUILD
@@ -0,0 +1,13 @@
+load("@rules_cc//cc:cc_library.bzl", "cc_library")
+
+package(default_visibility = ["//visibility:public"])
+
+cc_library(
+ name = "z",
+ linkopts = ["/usr/lib/libz.so"],
+)
+
+alias(
+ name = "zlib",
+ actual = ":z",
+)
diff --git a/japanese/mozc-server/files/bazel.zlib.MODULE b/japanese/mozc-server/files/bazel.zlib.MODULE
new file mode 100644
index 000000000000..eabc8ad88187
--- /dev/null
+++ b/japanese/mozc-server/files/bazel.zlib.MODULE
@@ -0,0 +1,6 @@
+module(
+ name = "zlib",
+ compatibility_level = 1,
+)
+
+bazel_dep(name = "rules_cc", version = "0.2.17")
diff --git a/japanese/mozc-server/files/extra-patch-src-MODULE-fcitx5.bazel b/japanese/mozc-server/files/extra-patch-src-MODULE-fcitx5.bazel
new file mode 100644
index 000000000000..ad1f07fa3d95
--- /dev/null
+++ b/japanese/mozc-server/files/extra-patch-src-MODULE-fcitx5.bazel
@@ -0,0 +1,19 @@
+--- src/MODULE.bazel.orig
++++ src/MODULE.bazel
+@@ -215,6 +215,16 @@
+ "pkg_config_repository",
+ )
+
++# Fcitx 5
++pkg_config_repository(
++ name = "fcitx5",
++ exec_os = ["linux", "freebsd"],
++ packages = [
++ "Fcitx5Core",
++ "Fcitx5Module",
++ ],
++)
++
+ # iBus
+ pkg_config_repository(
+ name = "ibus",
diff --git a/japanese/mozc-server/files/extra-patch-src-MODULE-uim.bazel b/japanese/mozc-server/files/extra-patch-src-MODULE-uim.bazel
new file mode 100644
index 000000000000..a3834b82a0cd
--- /dev/null
+++ b/japanese/mozc-server/files/extra-patch-src-MODULE-uim.bazel
@@ -0,0 +1,16 @@
+--- src/MODULE.bazel.orig
++++ src/MODULE.bazel
+@@ -215,6 +215,13 @@
+ "pkg_config_repository",
+ )
+
++# uim
++pkg_config_repository(
++ name = "uim",
++ exec_os = ["linux", "freebsd"],
++ packages = ["uim"],
++)
++
+ # iBus
+ pkg_config_repository(
+ name = "ibus",
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.cc b/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.cc
index a5036a1c14a0..ba0aa9e2003c 100644
--- a/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.cc
+++ b/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.cc
@@ -1,33 +1,78 @@
---- src/unix/uim/key_translator.cc.orig 2019-03-04 19:32:08.940982000 +0900
-+++ src/unix/uim/key_translator.cc 2019-03-04 19:32:33.285357000 +0900
-@@ -368,25 +368,25 @@
+--- src/unix/uim/key_translator.cc.orig
++++ src/unix/uim/key_translator.cc
+@@ -32,7 +32,13 @@
+
+ #include <uim.h>
+
+-#include "base/logging.h"
++#include <cstddef>
++#include <iterator>
++#include <string>
++#include <utility>
++
++#include "absl/log/check.h"
++#include "base/vlog.h"
+
+ namespace {
+
+@@ -325,7 +331,7 @@
+ DCHECK(out_event) << "out_event is NULL";
+ out_event->Clear();
+
+- string kana_key_string;
++ std::string kana_key_string;
+ if ((method == config::Config::KANA) && IsKanaAvailable(
+ keyval, keycode, modifiers, layout_is_jp, &kana_key_string)) {
+ out_event->set_key_code(keyval);
+@@ -344,7 +350,7 @@
+ /* regards yen key as backslash */
+ out_event->set_key_code('\\');
+ } else {
+- VLOG(1) << "Unknown keyval: " << keyval;
++ MOZC_VLOG(1) << "Unknown keyval: " << keyval;
+ return false;
+ }
+
+@@ -367,28 +373,28 @@
+ }
void KeyTranslator::Init() {
- for (int i = 0; i < arraysize(special_key_map); ++i) {
-- CHECK(special_key_map_.insert(make_pair(special_key_map[i].from,
-+ CHECK(special_key_map_.insert(std::make_pair(special_key_map[i].from,
- special_key_map[i].to)).second);
+- for (int i = 0; i < arraysize(special_key_map); ++i) {
++ for (std::size_t i = 0; i < std::size(special_key_map); ++i) {
+ CHECK(special_key_map_.insert(
+ std::make_pair(special_key_map[i].from,
+ special_key_map[i].to)).second);
}
- for (int i = 0; i < arraysize(modifier_key_map); ++i) {
-- CHECK(modifier_key_map_.insert(make_pair(modifier_key_map[i].from,
-+ CHECK(modifier_key_map_.insert(std::make_pair(modifier_key_map[i].from,
- modifier_key_map[i].to)).second);
+- for (int i = 0; i < arraysize(modifier_key_map); ++i) {
++ for (std::size_t i = 0; i < std::size(modifier_key_map); ++i) {
+ CHECK(modifier_key_map_.insert(
+ std::make_pair(modifier_key_map[i].from,
+ modifier_key_map[i].to)).second);
}
- for (int i = 0; i < arraysize(modifier_mask_map); ++i) {
-- CHECK(modifier_mask_map_.insert(make_pair(modifier_mask_map[i].from,
-+ CHECK(modifier_mask_map_.insert(std::make_pair(modifier_mask_map[i].from,
- modifier_mask_map[i].to)).second);
+- for (int i = 0; i < arraysize(modifier_mask_map); ++i) {
++ for (std::size_t i = 0; i < std::size(modifier_mask_map); ++i) {
+ CHECK(modifier_mask_map_.insert(
+ std::make_pair(modifier_mask_map[i].from,
+ modifier_mask_map[i].to)).second);
}
- for (int i = 0; i < arraysize(kana_map_jp); ++i) {
+- for (int i = 0; i < arraysize(kana_map_jp); ++i) {
++ for (std::size_t i = 0; i < std::size(kana_map_jp); ++i) {
CHECK(kana_map_jp_.insert(
-- make_pair(kana_map_jp[i].code, make_pair(
-+ std::make_pair(kana_map_jp[i].code, std::make_pair(
- kana_map_jp[i].no_shift, kana_map_jp[i].shift))).second);
+ std::make_pair(kana_map_jp[i].code,
+ std::make_pair(kana_map_jp[i].no_shift,
+ kana_map_jp[i].shift))).second);
}
- for (int i = 0; i < arraysize(kana_map_us); ++i) {
+- for (int i = 0; i < arraysize(kana_map_us); ++i) {
++ for (std::size_t i = 0; i < std::size(kana_map_us); ++i) {
CHECK(kana_map_us_.insert(
-- make_pair(kana_map_us[i].code, make_pair(
-+ std::make_pair(kana_map_us[i].code, std::make_pair(
- kana_map_us[i].no_shift, kana_map_us[i].shift))).second);
+ std::make_pair(kana_map_us[i].code,
+ std::make_pair(kana_map_us[i].no_shift,
+@@ -412,7 +418,7 @@
+ unsigned int keycode,
+ unsigned int modifiers,
+ bool layout_is_jp,
+- string *out) const {
++ std::string *out) const {
+ if ((modifiers & UMod_Control) || (modifiers & UMod_Alt)) {
+ return false;
}
- }
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.h b/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.h
index bc56d9036607..9802f79ba82c 100644
--- a/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.h
+++ b/japanese/mozc-server/files/extra-patch-src-unix-uim-key_translator.h
@@ -1,13 +1,57 @@
---- src/unix/uim/key_translator.h.orig 2015-07-15 10:04:31.000000000 +0900
-+++ src/unix/uim/key_translator.h 2019-03-04 19:28:03.722916000 +0900
-@@ -62,8 +62,8 @@
+--- src/unix/uim/key_translator.h.orig
++++ src/unix/uim/key_translator.h
+@@ -34,11 +34,12 @@
+ #include <uim.h>
+
+ #include <map>
+-#include <ext/hash_map>
+-using __gnu_cxx::hash_map;
++#include <string>
++#include <unordered_map>
++#include <utility>
+
+-#include "base/port.h"
+ #include "protocol/commands.pb.h"
++#include "protocol/config.pb.h"
+
+ namespace mozc {
+ namespace uim {
+@@ -49,6 +50,8 @@
+ class KeyTranslator {
+ public:
+ KeyTranslator();
++ KeyTranslator(const KeyTranslator&) = delete;
++ KeyTranslator& operator=(const KeyTranslator&) = delete;
+ virtual ~KeyTranslator();
+
+ // Converts ibus keycode to Mozc key code and stores them on |out_event|.
+@@ -61,9 +64,9 @@
+ commands::KeyEvent *out_event) const;
private:
- typedef hash_map<unsigned int, commands::KeyEvent::SpecialKey> SpecialKeyMap;
-- typedef map<unsigned int, commands::KeyEvent::ModifierKey> ModifierKeyMap;
-- typedef map<unsigned int, pair<string, string> > KanaMap;
-+ typedef std::map<unsigned int, commands::KeyEvent::ModifierKey> ModifierKeyMap;
-+ typedef std::map<unsigned int, std::pair<string, string> > KanaMap;
+- typedef hash_map<unsigned int, commands::KeyEvent::SpecialKey> SpecialKeyMap;
++ typedef std::unordered_map<unsigned int, commands::KeyEvent::SpecialKey> SpecialKeyMap;
+ typedef std::map<unsigned int, commands::KeyEvent::ModifierKey> ModifierKeyMap;
+- typedef std::map<unsigned int, std::pair<string, string> > KanaMap;
++ typedef std::map<unsigned int, std::pair<std::string, std::string> > KanaMap;
// Returns true iff key is modifier key such as SHIFT, ALT, or CAPSLOCK.
bool IsModifierKey(unsigned int keyval,
+@@ -79,7 +82,7 @@
+ unsigned int keycode,
+ unsigned int modifiers,
+ bool layout_is_jp,
+- string *out) const;
++ std::string *out) const;
+
+
+ // Returns true iff key is ASCII such as '0', 'A', or '!'.
+@@ -101,8 +104,6 @@
+ // 'Hiragana Letter Small U' (with Shift modifier).
+ KanaMap kana_map_jp_; // mapping for JP keyboard.
+ KanaMap kana_map_us_; // mapping for US keyboard.
+-
+- DISALLOW_COPY_AND_ASSIGN(KeyTranslator);
+ };
+
+ } // namespace uim
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-mozc.cc b/japanese/mozc-server/files/extra-patch-src-unix-uim-mozc.cc
index 90c8d7ad8ba7..ba761d5c03cd 100644
--- a/japanese/mozc-server/files/extra-patch-src-unix-uim-mozc.cc
+++ b/japanese/mozc-server/files/extra-patch-src-unix-uim-mozc.cc
@@ -1,28 +1,226 @@
---- src/unix/uim/mozc.cc.orig 2015-07-15 10:04:31.000000000 +0900
-+++ src/unix/uim/mozc.cc 2019-03-04 19:35:14.711403000 +0900
-@@ -48,6 +48,7 @@
- # include "plugin.h"
+--- src/unix/uim/mozc.cc.orig
++++ src/unix/uim/mozc.cc
+@@ -61,20 +61,23 @@
+
+ #define USE_CASCADING_CANDIDATES 0
+
+-#include <map>
+-#include <ext/hash_map>
+-using __gnu_cxx::hash_map;
++#include <cstdint>
++#include <ctime>
++#include <string>
++#include <unordered_map>
++#include <utility>
++#include <vector>
+ static char **argv;
+
+ // for every 5 minutes, call SyncData
+-const uint64 kSyncDataInterval = 5 * 60;
++const std::uint64_t kSyncDataInterval = 5 * 60;
+ #if USE_CASCADING_CANDIDATES
+ // An ID for a candidate which is not associated with a text.
+-const int32 kBadCandidateId = -1;
++const std::int32_t kBadCandidateId = -1;
+ #endif
+
+-uint64 GetTime() {
+- return static_cast<uint64>(time(NULL));
++std::uint64_t GetTime() {
++ return static_cast<std::uint64_t>(time(NULL));
+ }
+
+ namespace mozc {
+@@ -93,9 +96,9 @@
+ bool need_cand_reactivate;
+ int prev_page;
+ int cand_nr_before;
+- uint64 last_sync_time;
++ std::uint64_t last_sync_time;
+ #if USE_CASCADING_CANDIDATES
+- vector<int32> *unique_candidate_ids;
++ std::vector<std::int32_t> *unique_candidate_ids;
+ #endif
+ config::Config::PreeditMethod preedit_method;
+ } *context_slot;
+@@ -126,7 +129,7 @@
+ if (context_slot[id].session == NULL)
+ return;
+
+- const uint64 current_time = GetTime();
++ const std::uint64_t current_time = GetTime();
+ if (force ||
+ (current_time >= context_slot[id].last_sync_time &&
+ current_time - context_slot[id].last_sync_time >= kSyncDataInterval)) {
+@@ -173,8 +176,8 @@
+ {
+ size_t len = segment.value_length();
+
+- auto former = string(Util::Utf8SubString(segment.value(), 0, pos));
+- auto latter = string(Util::Utf8SubString(segment.value(), pos, len));
++ auto former = std::string(Util::Utf8SubString(segment.value(), 0, pos));
++ auto latter = std::string(Util::Utf8SubString(segment.value(), pos, len));
+
+ uim_lisp seg_f, seg_c, seg_l;
+ if (pos == 0) {
+@@ -280,14 +283,14 @@
+ {
+ commands::Output *output = context_slot[id].output;
+
+- if (!output->has_candidates()) {
++ if (!output->has_candidate_window()) {
+ uim_scm_callf("im-deactivate-candidate-selector", "o", mc_);
+ context_slot[id].cand_nr_before = 0;
+
+ return;
+ }
+
+- const commands::Candidates &candidates = output->candidates();
++ const commands::CandidateWindow &candidates = output->candidate_window();
+ bool first_time = false;
+ bool has_focused_index = candidates.has_focused_index();
+ int current_page = has_focused_index ? candidates.focused_index() / 9 : 0;
+@@ -316,7 +319,7 @@
+ context_slot[id].unique_candidate_ids->clear();
+ for (int i = 0; i < candidates.candidate_size(); ++i) {
+ if (candidates.candidate(i).has_id()) {
+- const int32 cand_id = candidates.candidate(i).id();
++ const std::int32_t cand_id = candidates.candidate(i).id();
+ context_slot[id].unique_candidate_ids->push_back(cand_id);
+ } else {
+ // The parent node of the cascading window does not have an id since the
+@@ -380,7 +383,7 @@
+ !NULLP(latter = uim_scm_callf("ustr-latter-seq", "o", ustr))) {
+ uim_lisp str = CAR(latter);
+
+- string text = REFER_C_STR(str);
++ std::string text = REFER_C_STR(str);
+ session_command.set_text(text);
+ } else {
+ #if 0
+@@ -389,7 +392,7 @@
+ ustr = uim_scm_callf("im-acquire-text", "oyyyi", mc_, "primary", "cursor", "line", 0);
+ if (TRUEP(ustr) && !NULLP(former = uim_scm_callf("ustr-former-seq", "o", ustr))) {
+ uim_lisp str = CAR(former);
+- string text = REFER_C_STR(str);
++ std::string text = REFER_C_STR(str);
+ session_command.set_text(text);
+ use_primary_text = 1;
+ } else
+@@ -449,7 +452,7 @@
+ context_slot[id].cand_nr_before = 0;
+ context_slot[id].prev_page = 0;
+ #if USE_CASCADING_CANDIDATES
+- context_slot[id].unique_candidate_ids = new vector<int32>;
++ context_slot[id].unique_candidate_ids = new std::vector<std::int32_t>;
#endif
-+#include "base/init_mozc.h"
- #include "base/port.h"
- #include "base/util.h"
- #include "protocol/config.pb.h"
-@@ -902,7 +903,7 @@
- int i;
+ // Launch mozc_server
+@@ -568,7 +571,7 @@
+ int id = C_INT(id_);
+ commands::Output *output = context_slot[id].output;
- for (i = 0; key_tab[i].key; i++)
-- key_map.insert(make_pair(key_tab[i].str, key_tab[i].key));
-+ key_map.insert(std::make_pair(key_tab[i].str, key_tab[i].key));
+- return MAKE_INT(output->candidates().size());
++ return MAKE_INT(output->candidate_window().size());
}
static uim_lisp
-@@ -1196,7 +1197,7 @@
- argv[0] = (char *)name;
- argv[1] = NULL;
+@@ -576,7 +579,7 @@
+ {
+ int id = C_INT(id_);
+ commands::Output *output = context_slot[id].output;
+- const commands::Candidates &candidates = output->candidates();
++ const commands::CandidateWindow &candidates = output->candidate_window();
+ const char *cand, *prefix, *suffix;
+ char *s;
-- InitGoogle((const char *)argv[0], &argc, (char ***)&argv, true);
-+ mozc::InitMozc((const char *)argv[0], &argc, (char ***)&argv, true);
- mozc::uim::install_keymap();
- }
+@@ -612,7 +615,7 @@
+ {
+ int id = C_INT(id_);
+ commands::Output *output = context_slot[id].output;
+- const commands::Candidates &candidates = output->candidates();
++ const commands::CandidateWindow &candidates = output->candidate_window();
+ const char *label;
+
+ int nth;
+@@ -641,7 +644,7 @@
+ {
+ int id = C_INT(id_);
+ commands::Output *output = context_slot[id].output;
+- const commands::Candidates &candidates = output->candidates();
++ const commands::CandidateWindow &candidates = output->candidate_window();
+ const char *annotation;
+
+ int nth;
+@@ -889,15 +892,7 @@
+ {0, 0}
+ };
+
+-struct eqstr
+-{
+- bool operator()(const char* s1, const char* s2) const
+- {
+- return strcmp(s1, s2) == 0;
+- }
+-};
+-
+-typedef hash_map<const char *, int, __gnu_cxx::hash<const char *>, eqstr> KeyMap;
++using KeyMap = std::unordered_map<std::string, int>;
+ static KeyMap key_map;
+
+ static void install_keymap(void)
+@@ -992,7 +987,7 @@
+ update_all(mc_, id);
+ uim_scm_callf("mozc-context-set-on!", "oo", mc_, uim_scm_f());
+ } else {
+- command.set_type(commands::SessionCommand::SWITCH_INPUT_MODE);
++ command.set_type(commands::SessionCommand::SWITCH_COMPOSITION_MODE);
+ command.set_composition_mode(mode);
+ context_slot[id].session->SendCommand(command, context_slot[id].output);
+ context_slot[id].currentMode = mode; /* don't set this with DIRECT mode */
+@@ -1008,7 +1003,7 @@
+ int id = C_INT(id_);
+ commands::SessionCommand command;
+
+- command.set_type(commands::SessionCommand::SWITCH_INPUT_MODE);
++ command.set_type(commands::SessionCommand::SWITCH_COMPOSITION_MODE);
+ command.set_composition_mode(context_slot[id].currentMode);
+ context_slot[id].session->SendCommand(command, context_slot[id].output);
+
+@@ -1032,16 +1027,16 @@
+ #if USE_CASCADING_CANDIDATES
+ if (idx >= context_slot[id].unique_candidate_ids->size())
+ #else
+- if (idx >= context_slot[id].output->candidates().candidate_size())
++ if (idx >= context_slot[id].output->candidate_window().candidate_size())
+ #endif
+ return uim_scm_f();
+
+ #if USE_CASCADING_CANDIDATES
+- const int32 cand_id = (*context_slot[id].unique_candidate_ids)[idx];
++ const std::int32_t cand_id = (*context_slot[id].unique_candidate_ids)[idx];
+ if (cand_id == kBadCandidateId)
+ return uim_scm_f();
+ #else
+- const int32 cand_id = context_slot[id].output->candidates().candidate(idx).id();
++ const std::int32_t cand_id = context_slot[id].output->candidate_window().candidate(idx).id();
+ #endif
+
+ commands::SessionCommand command;
+@@ -1126,14 +1121,14 @@
+ !NULLP(latter = uim_scm_callf("ustr-latter-seq", "o", ustr))) {
+ uim_lisp str = CAR(latter);
+- string text = REFER_C_STR(str);
++ std::string text = REFER_C_STR(str);
+ session_command.set_text(text);
+ } else {
+ ustr = uim_scm_callf("im-acquire-text", "oyyyi", mc_, "primary", "cursor", "line", 0);
+ if (TRUEP(ustr) &&
+ !NULLP(former = uim_scm_callf("ustr-former-seq", "o", ustr))) {
+ uim_lisp str = CAR(former);
+- string text = REFER_C_STR(str);
++ std::string text = REFER_C_STR(str);
+ session_command.set_text(text);
+ use_primary_text = 1;
+ } else
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc-custom.scm b/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc-custom.scm
new file mode 100644
index 000000000000..2ac44d05095d
--- /dev/null
+++ b/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc-custom.scm
@@ -0,0 +1,47 @@
+--- src/unix/uim/scm/mozc-custom.scm.orig
++++ src/unix/uim/scm/mozc-custom.scm
+@@ -137,16 +137,6 @@
+ "W"
+ (N_ "Word register dialog")
+ (N_ "Word register dialog"))
+- (list 'action_mozc_tool_character_palette
+- 'mozc_tool_character_palette
+- "P"
+- (N_ "Character palette")
+- (N_ "Character palette"))
+- (list 'action_mozc_tool_hand_writing
+- 'mozc_tool_hand_writing
+- "H"
+- (N_ "Hand writing")
+- (N_ "Hand writing"))
+ (list 'action_mozc_reconvert
+ 'mozc_reconvert
+ "R"
+@@ -370,27 +360,3 @@
+ '(string ".*")
+ (N_ "Option for word register dialog command")
+ (N_ "long description will be here."))
+-
+-(define-custom 'mozc-tool-character-palette-cmd "/usr/lib/mozc/mozc_tool"
+- '(mozc-tool)
+- '(pathname regular-file)
+- (N_ "Path of character palette command")
+- (N_ "long description will be here."))
+-
+-(define-custom 'mozc-tool-character-palette-cmd-option "--mode=character_palette"
+- '(mozc-tool)
+- '(string ".*")
+- (N_ "Option for character palette command")
+- (N_ "long description will be here."))
+-
+-(define-custom 'mozc-tool-hand-writing-cmd "/usr/lib/mozc/mozc_tool"
+- '(mozc-tool)
+- '(pathname regular-file)
+- (N_ "Path of hand writing command")
+- (N_ "long description will be here."))
+-
+-(define-custom 'mozc-tool-hand-writing-cmd-option "--mode=hand_writing"
+- '(mozc-tool)
+- '(string ".*")
+- (N_ "Option for hand writing command")
+- (N_ "long description will be here."))
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc.scm b/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc.scm
new file mode 100644
index 000000000000..cf13f44e9369
--- /dev/null
+++ b/japanese/mozc-server/files/extra-patch-src-unix-uim-scm-mozc.scm
@@ -0,0 +1,46 @@
+--- src/unix/uim/scm/mozc.scm.orig
++++ src/unix/uim/scm/mozc.scm
+@@ -98,10 +98,6 @@
+ (mozc-run-process mozc-tool-dictionary-tool-cmd (list mozc-tool-dictionary-tool-cmd mozc-tool-dictionary-tool-cmd-option)))
+ ((mozc-tool-word-register-dialog)
+ (mozc-run-process mozc-tool-word-register-dialog-cmd (list mozc-tool-word-register-dialog-cmd mozc-tool-word-register-dialog-cmd-option)))
+- ((mozc-tool-character-palette)
+- (mozc-run-process mozc-tool-character-palette-cmd (list mozc-tool-character-palette-cmd mozc-tool-character-palette-cmd-option)))
+- ((mozc-tool-hand-writing)
+- (mozc-run-process mozc-tool-hand-writing-cmd (list mozc-tool-hand-writing-cmd mozc-tool-hand-writing-cmd-option)))
+ (else
+ #f))))
+
+@@ -294,32 +290,6 @@
+ #f)
+ (lambda (mc)
+ (mozc-tool-activate mc 'mozc-tool-word-register-dialog)))
+-
+-(register-action 'action_mozc_tool_character_palette
+-;; (indication-alist-indicator 'action_mozc_tool_character_palette
+-;; mozc-tool-indication-alist)
+- (lambda (mc)
+- '(mozc_tool_character_palette
+- "W"
+- "Character palette"
+- "Character palette"))
+- (lambda (mc)
+- #f)
+- (lambda (mc)
+- (mozc-tool-activate mc 'mozc-tool-character-palette)))
+-
+-(register-action 'action_mozc_tool_hand_writing
+-;; (indication-alist-indicator 'action_mozc_tool_hand_writing
+-;; mozc-tool-indication-alist)
+- (lambda (mc)
+- '(mozc_tool_hand_writing
+- "W"
+- "Hand writing"
+- "Hand writing"))
+- (lambda (mc)
+- #f)
+- (lambda (mc)
+- (mozc-tool-activate mc 'mozc-tool-hand-writing)))
+
+ (register-action 'action_mozc_reconvert
+ ;; (indication-alist-indicator 'action_mozc_reconvert
diff --git a/japanese/mozc-server/files/extra-patch-src-unix-uim-uim.gyp b/japanese/mozc-server/files/extra-patch-src-unix-uim-uim.gyp
deleted file mode 100644
index ad49d67e1974..000000000000
--- a/japanese/mozc-server/files/extra-patch-src-unix-uim-uim.gyp
+++ /dev/null
@@ -1,19 +0,0 @@
---- src/unix/uim/uim.gyp.orig 2015-07-15 10:04:31.000000000 +0900
-+++ src/unix/uim/uim.gyp 2016-05-11 00:37:33.495056000 +0900
-@@ -31,6 +31,7 @@
- {
- 'variables': {
- 'relative_dir': 'unix/uim',
-+ 'gen_out_dir': '<(SHARED_INTERMEDIATE_DIR)/<(relative_dir)',
- 'pkg_config_libs': [
- 'uim',
- ],
-@@ -39,6 +40,8 @@
- 'uim_dependencies': [
- '../../base/base.gyp:base',
- '../../client/client.gyp:client',
-+ '../../ipc/ipc.gyp:ipc',
-+ '../../session/session_base.gyp:ime_switch_util',
- ],
- },
- 'targets': [
diff --git a/japanese/mozc-server/files/extra-src-unix-uim-BUILD.bazel b/japanese/mozc-server/files/extra-src-unix-uim-BUILD.bazel
new file mode 100644
index 000000000000..8c1b98f36bdf
--- /dev/null
+++ b/japanese/mozc-server/files/extra-src-unix-uim-BUILD.bazel
@@ -0,0 +1,37 @@
+load("//:build_defs.bzl", "mozc_cc_binary", "mozc_cc_library")
+
+mozc_cc_library(
+ name = "key_translator",
+ srcs = ["key_translator.cc"],
+ hdrs = ["key_translator.h"],
+ linkstatic = True,
+ deps = [
+ "//base:vlog",
+ "//protocol:commands_cc_proto",
+ "//protocol:config_cc_proto",
+ "@com_google_absl//absl/log:check",
+ "@uim//:uim",
+ ],
+)
+
+mozc_cc_binary(
+ name = "libuim-mozc.so",
+ srcs = ["mozc.cc"],
+ linkshared = True,
+ linkstatic = True,
+ deps = [
+ ":key_translator",
+ "//base:init_mozc",
+ "//base:port",
+ "//base:util",
+ "//client",
+ "//protocol:commands_cc_proto",
+ "//protocol:config_cc_proto",
+ "@uim//:uim",
+ ],
+)
+
+alias(
+ name = "uim-mozc",
+ actual = ":libuim-mozc.so",
+)
diff --git a/japanese/mozc-server/files/leim-list.el b/japanese/mozc-server/files/leim-list.el
index b99d5da571b2..23d36d614491 100644
--- a/japanese/mozc-server/files/leim-list.el
+++ b/japanese/mozc-server/files/leim-list.el
@@ -1,6 +1,6 @@
-;; leim-list.el --- Mozc setup for leim API
+;; leim-list.el --- Mozc setup for leim API -*- lexical-binding: nil; -*-
;;
-;; Copyright (c) 2013 Hiroki Sato <hrs@FreeBSD.org>. All rights reserved.
+;; Copyright (c) 2013, 2026 Hiroki Sato <hrs@FreeBSD.org>
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following conditions
@@ -11,9 +11,25 @@
;; notice, this list of conditions and the following disclaimer in the
;; documentation and/or other materials provided with the distribution.
;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+;; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+;; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+;; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+;; SUCH DAMAGE.
(autoload 'mozc-mode "mozc" "Activate Mozc." t)
-(autoload 'mozc-leim-activate "mozc" "Activate Mozc." t)
+(defun mozc-leim-activate (input-method)
+ "Activate Mozc through its own LEIM registration."
+ (require 'mozc)
+ (mozc-leim-register-input-method)
+ (funcall (nth 2 (assoc input-method input-method-alist))
+ input-method))
(defcustom mozc-leim-title "[Mozc]"
"Mode line string shown when mozc-mode is enabled.
diff --git a/japanese/mozc-server/files/mozc.in b/japanese/mozc-server/files/mozc.in
index 3b5cd059e3fa..2612d3fcb39a 100644
--- a/japanese/mozc-server/files/mozc.in
+++ b/japanese/mozc-server/files/mozc.in
@@ -1,71 +1,111 @@
#!/bin/sh
-: ${MOZCDIR:="${HOME}/.mozc"}
# Mozc does not run by priviledged user. Ignore silently.
-case $(id -u) in
-0) exit 0 ;;
-esac
+MOZC_UID=$(id -u) || exit 1
+[ "${MOZC_UID}" -eq 0 ] && exit 0
-mkdir -m 0700 -p "${MOZCDIR}"
-chmod 0700 "${MOZCDIR}"
+# Mozc looks into the following directories:
+#
+# ~/.mozc if any
+# ${XDG_CONFIG_HOME}/mozc
+# ~/.config/mozc
+#
+if [ -z "${HOME}" ]; then
+ echo "HOME is not set." >&2
+ exit 1
+fi
+if [ -d "${HOME}/.mozc" ]; then
+ MOZCDIR="${HOME}/.mozc"
+else
+ MOZCDIR="${XDG_CONFIG_HOME:-${HOME}/.config}/mozc"
+fi
-cleanup_lock()
-{
- rm -f "${MOZCDIR}/.session.ipc" \
- "${MOZCDIR}/.server.lock" \
- "${MOZCDIR}/mozc_server.pid"
-}
-check_lock()
+mkdir -m 0700 -p "${MOZCDIR}" || exit 1
+chmod 0700 "${MOZCDIR}" || exit 1
+
+server_pids()
{
- if [ -r "${MOZCDIR}/.server.lock" ]; then
- if [ -r "${MOZCDIR}/mozc_server.pid" ]; then
- pid=$(cat "${MOZCDIR}/mozc_server.pid")
- pid=" (PID=$pid)"
- fi
- printf "mozc_server is running%s.\n" "$pid" \
- > /dev/stderr
- false
- fi
+ pgrep -u "${MOZC_UID}" -x mozc_server
}
start_cmd()
{
+ pids=$(server_pids)
+ rc=$?
+ case $rc in
+ 0)
+ printf 'mozc_server is already running (PID: %s).\n' \
+ "${pids}" >&2
+ return 1
+ ;;
+ 1)
+ # No matching process.
+ ;;
+ *)
+ echo "Cannot check mozc_server status." >&2
+ return 1
+ ;;
+ esac
+
daemon -c -f -p "${MOZCDIR}/mozc_server.pid" \
- "%%PREFIX%%/bin/mozc_server"
+ "%%PREFIX%%/libexec/mozc_server"
}
-stop_server()
+stop_cmd()
{
- if [ -r "${MOZCDIR}/mozc_server.pid" ]; then
- pkill -F "${MOZCDIR}/mozc_server.pid"
- else
- for p in $(pgrep -U $(id -u) mozc_server); do
- kill $p
- done
- fi
+ pkill -TERM -u "${MOZC_UID}" -x mozc_server
+ rc=$?
+ case $rc in
+ 0|1)
+ # A signal was sent, or no matching process existed.
+ ;;
+ *)
+ echo "Cannot stop mozc_server." >&2
+ return 1
+ ;;
+ esac
+
+ attempt=0
+ while :; do
+ pids=$(server_pids)
+ rc=$?
+ case $rc in
+ 0)
+ ;;
+ 1)
+ return 0
+ ;;
+ *)
+ echo "Cannot check mozc_server status." >&2
+ return 1
+ ;;
+ esac
+
+ if [ "$attempt" -ge 10 ]; then
+ printf 'mozc_server did not stop (PID: %s).\n' \
+ "${pids}" >&2
+ return 1
+ fi
+
+ sleep 1
+ attempt=$((attempt + 1))
+ done
}
case $1 in
start)
- check_lock || exit 1
start_cmd
;;
forcestart|restart)
- stop_server
- cleanup_lock
+ stop_cmd || exit 1
start_cmd
;;
stop|forcestop)
- stop_server
- cleanup_lock
+ stop_cmd
;;
status)
- pid=$(pgrep -U $(id -u) mozc_server)
- case $pid in
- [0-9]*) echo $pid && exit 0 ;;
- *) exit 1 ;;
- esac
+ server_pids
;;
*)
- echo "$0 [start|stop|restart|forcestart|forcestop|status]"
+ echo "$0 [start|stop|restart|forcestart|forcestop|status]" >&2
exit 1
;;
esac
diff --git a/japanese/mozc-server/files/mozc_tool.in b/japanese/mozc-server/files/mozc_tool.in
index 4f6b8d3dfd08..e3c32064afe9 100644
--- a/japanese/mozc-server/files/mozc_tool.in
+++ b/japanese/mozc-server/files/mozc_tool.in
@@ -1,16 +1,24 @@
#!/bin/sh
-: ${MODE:=${1:-about_dialog}}
-case $MODE in
---mode=*)
- exec %%PREFIX%%/libexec/mozc_tool $MODE
-;;
-config_dialog|dictionary_tool|word_register_dialog|about_dialog|character_palette|hand_writing)
- exec %%PREFIX%%/libexec/mozc_tool --mode="$MODE"
+mode=${1:-${MODE:-about_dialog}}
+if [ "$#" -gt 0 ]; then
+ shift
+fi
+mode=${mode#--mode=}
+
+case "$mode" in
+config_dialog|dictionary_tool|word_register_dialog|about_dialog|error_message_dialog)
+ exec "%%PREFIX%%/libexec/mozc_tool" --mode="${mode}" "$@"
;;
*)
- echo "Specify one of the following keywords:"
- echo "config_dialog|dictionary_tool|word_register_dialog|about_dialog|character_palette|hand_writing" | tr "|" "\n"
+ echo "Usage: $0 [MODE|--mode=MODE] [arguments ...]" >&2
+ echo "Available modes:" >&2
+ printf ' %s\n' \
+ config_dialog \
+ dictionary_tool \
+ word_register_dialog \
+ about_dialog \
+ error_message_dialog >&2
exit 1
;;
esac
diff --git a/japanese/mozc-server/files/patch-src-.bazelrc b/japanese/mozc-server/files/patch-src-.bazelrc
new file mode 100644
index 000000000000..509c01cbb7a3
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-.bazelrc
@@ -0,0 +1,13 @@
+--- src/.bazelrc.orig 2026-10-17 21:11:34 UTC
++++ src/.bazelrc
+@@ -11,6 +11,10 @@ common:prod_linux_dev --noenable_platform_specific_con
+ common:prod_linux --noenable_platform_specific_config --config=linux_env --define TARGET=prod_linux
+ common:prod_linux_dev --noenable_platform_specific_config --config=linux_env --define TARGET=prod_linux --config=dev_channel
+
++common:oss_freebsd --noenable_platform_specific_config --config=freebsd_env --define TARGET=oss_linux
++common:freebsd_env --config=compiler_gcc_like
++build:freebsd_env --copt=-fPIC --linkopt=-lm --host_linkopt=-lm
++
+ common:macos --config=macos_env --define TARGET=oss_macos
+ common:oss_macos --noenable_platform_specific_config --config=macos_env --define TARGET=oss_macos
+ common:prod_macos --noenable_platform_specific_config --config=macos_env --define TARGET=prod_macos
diff --git a/japanese/mozc-server/files/patch-src-MODULE.bazel b/japanese/mozc-server/files/patch-src-MODULE.bazel
new file mode 100644
index 000000000000..7d041f8a4d34
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-MODULE.bazel
@@ -0,0 +1,67 @@
+--- src/MODULE.bazel.orig 2026-10-16 12:33:33 UTC
++++ src/MODULE.bazel
+@@ -219,7 +219,7 @@ pkg_config_repository(
+ # iBus
+ pkg_config_repository(
+ name = "ibus",
+- exec_os = ["linux"],
++ exec_os = ["linux", "freebsd"],
+ packages = [
+ "glib-2.0",
+ "gobject-2.0",
+@@ -230,11 +230,12 @@ pkg_config_repository(
+ # Qt for Linux
+ pkg_config_repository(
+ name = "qt_linux",
+- exec_os = ["linux"],
++ exec_os = ["linux", "freebsd"],
+ packages = [
+ "Qt6Core",
+ "Qt6Gui",
+ "Qt6Widgets",
++ "gl",
+ ],
+ )
+
+@@ -366,32 +367,22 @@ http_archive(
+ ],
+ )
+
+-# Japanese Usage Dictionary (2025-01-25)
+-JA_USAGE_DICT_TAG = "2025-01-25"
+-
+-http_archive(
++# Japanese Usage Dictionary fetched and extracted by FreeBSD ports.
++new_local_repository(
+ name = "ja_usage_dict",
+- sha256 = "140f24f71f7d78d5eb5b93a9c079f44f23728dca5ab16bf857fe8a3fa1bf20ed",
+- strip_prefix = "japanese-usage-dictionary-%s" % JA_USAGE_DICT_TAG,
+- url = "https://github.com/hiroyuki-komatsu/japanese-usage-dictionary/archive/refs/tags/%s.zip" % JA_USAGE_DICT_TAG,
++ build_file = "@//bazel:BUILD.ja_usage_dict.bazel",
++ path = "japanese_usage_dictionary",
+ )
+
+-# Zip code (2026-04-03, 621d059fbcbfae17bfca15b439692bae934268c3)
+-# https://github.com/hiroyuki-komatsu/japanpost_zipcode/ contains snapshots of the zip code data
+-# with version control.
+-# The data files are mirror of the following files.
+-# * https://www.post.japanpost.jp/zipcode/dl/jigyosyo/zip/jigyosyo.zip
+-# * https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
+-http_archive(
++# Japan Post zip code data fetched and extracted by FreeBSD ports.
++new_local_repository(
+ name = "zip_code_jigyosyo",
+ build_file_content = "exports_files([\"JIGYOSYO.CSV\"])",
+- sha256 = "14be1030f607c5f819f2f45a485e89511907bdd1d62e7fb1931b6e48a3431c3a",
+- url = "https://github.com/hiroyuki-komatsu/japanpost_zipcode/raw/621d059fbcbfae17bfca15b439692bae934268c3/jigyosyo.zip",
++ path = "japanpost_zipcode",
+ )
+
+-http_archive(
++new_local_repository(
+ name = "zip_code_ken_all",
+ build_file_content = "exports_files([\"KEN_ALL.CSV\"])",
+- sha256 = "3adc97d8e19e1168a6cdcb2fce759d0e9e613a9a3b630cc180aecfd56ae81eaf",
+- url = "https://github.com/hiroyuki-komatsu/japanpost_zipcode/raw/621d059fbcbfae17bfca15b439692bae934268c3/ken_all.zip",
++ path = "japanpost_zipcode",
+ )
diff --git a/japanese/mozc-server/files/patch-src-base-cpu_stats.cc b/japanese/mozc-server/files/patch-src-base-cpu_stats.cc
new file mode 100644
index 000000000000..cfd5e8c8c94b
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-cpu_stats.cc
@@ -0,0 +1,44 @@
+--- src/base/cpu_stats.cc.orig 2026-10-16 12:33:33 UTC
++++ src/base/cpu_stats.cc
+@@ -116,13 +116,13 @@ float CPUStats::GetSystemCPULoad() {
+
+ #endif // __APPLE__
+
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ // NOT IMPLEMENTED
+ // TODO(taku): implement Linux version
+ // can take the info from /proc/stats
+ const uint64_t total_times = 0;
+ const uint64_t cpu_times = 0;
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+
+ return UpdateCPULoad(total_times, cpu_times, &prev_system_total_times_,
+ &prev_system_cpu_times_);
+@@ -169,11 +169,11 @@ float CPUStats::GetCurrentProcessCPULoad() {
+ TimeValueTToInt64(task_times_info.system_time);
+ #endif // __APPLE__
+
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ // not implemented
+ const uint64_t total_times = 0;
+ const uint64_t cpu_times = 0;
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+
+ return UpdateCPULoad(total_times, cpu_times,
+ &prev_current_process_total_times_,
+@@ -200,9 +200,9 @@ size_t CPUStats::GetNumberOfProcessors() const {
+ return static_cast<size_t>(basic_info.avail_cpus);
+ #endif // __APPLE__
+
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ // Not implemented
+ return 1;
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+ }
+ } // namespace mozc
diff --git a/japanese/mozc-server/files/patch-src-base-file-recursive.cc b/japanese/mozc-server/files/patch-src-base-file-recursive.cc
new file mode 100644
index 000000000000..07b6fdfa74f8
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-file-recursive.cc
@@ -0,0 +1,29 @@
+--- src/base/file/recursive.cc.orig 2026-10-17 19:43:44 UTC
++++ src/base/file/recursive.cc
+@@ -104,7 +104,7 @@ void UnlinkFileOrLog(const char* path) {
+ } // namespace
+
+ #if (defined(__linux__) && !defined(__ANDROID__)) || \
+- (defined(TARGET_OS_OSX) && TARGET_OS_OSX)
++ (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || defined(__FreeBSD__)
+
+ absl::Status DeleteRecursively(const absl::string_view path) {
+ // fts is not POSIX, but it's available on both Linux and MacOS.
+@@ -155,7 +155,7 @@ absl::Status DeleteRecursively(const absl::string_view
+ return absl::OkStatus();
+ }
+
+-#else // (__linux__ && !__ANDROID__) || TARGET_OS_OSX
++#else // (__linux__ && !__ANDROID__) || TARGET_OS_OSX || __FreeBSD__
+
+ namespace {
+ int FtwDelete(const char* path, const struct stat* sb, int typeflag,
+@@ -193,7 +193,7 @@ absl::Status DeleteRecursively(const absl::string_view
+ return absl::OkStatus();
+ }
+
+-#endif // !(__linux__ && !__ANDROID__) || TARGET_OS_OSX)
++#endif // !(__linux__ && !__ANDROID__) || TARGET_OS_OSX) || __FreeBSD__
+ #endif // !_WIN32
+
+ } // namespace mozc::file
diff --git a/japanese/mozc-server/files/patch-src-base-init_mozc.cc b/japanese/mozc-server/files/patch-src-base-init_mozc.cc
deleted file mode 100644
index 707ec476599a..000000000000
--- a/japanese/mozc-server/files/patch-src-base-init_mozc.cc
+++ /dev/null
@@ -1,21 +0,0 @@
---- src/base/init_mozc.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/base/init_mozc.cc
-@@ -35,6 +35,7 @@
- #endif // OS_WIN
-
- #include <string>
-+#include <stdlib.h>
-
- #include "base/file_util.h"
- #include "base/flags.h"
-@@ -94,7 +95,9 @@ void InitMozc(const char *arg0, int *argc, char ***arg
- mozc_flags::ParseCommandLineFlags(argc, argv, remove_flags);
-
- const string program_name = *argc > 0 ? (*argv)[0] : "UNKNOWN";
-- Logging::InitLogStream(GetLogFilePathFromProgramName(program_name));
-+ const char *nolog = getenv("MOZC_NOLOG");
-+ if (nolog == NULL)
-+ Logging::InitLogStream(GetLogFilePathFromProgramName(program_name));
-
- }
-
diff --git a/japanese/mozc-server/files/patch-src-base-password_manager.cc b/japanese/mozc-server/files/patch-src-base-password_manager.cc
new file mode 100644
index 000000000000..ea1f26cde15c
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-password_manager.cc
@@ -0,0 +1,14 @@
+--- src/base/password_manager.cc.orig 2026-10-17 19:51:09 UTC
++++ src/base/password_manager.cc
+@@ -264,9 +264,9 @@ bool WinMacPasswordManager::RemovePassword() { return
+ // We use plain text file for password storage on Linux. If you port this module
+ // to other Linux distro, you might want to implement a new password manager
+ // which adopts some secure mechanism such like gnome-keyring.
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ typedef PlainPasswordManager DefaultPasswordManager;
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+
+ // Windows or Mac
+ #if (defined(_WIN32) || defined(__APPLE__))
diff --git a/japanese/mozc-server/files/patch-src-base-port.h b/japanese/mozc-server/files/patch-src-base-port.h
new file mode 100644
index 000000000000..a8fff33567ec
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-port.h
@@ -0,0 +1,36 @@
+--- src/base/port.h.orig 2026-10-17 19:46:18 UTC
++++ src/base/port.h
+@@ -47,6 +47,7 @@ enum class PlatformType {
+ kIos, // iOS Devices or Simulator
+ kWasm, // WebAssembly
+ kChromeos, // ChromeOS
++ kFreeBSD, // FreeBSD
+ };
+
+ // kTargetPlatform is the current build target platform.
+@@ -70,9 +71,11 @@ inline constexpr PlatformType kTargetPlatform = Platfo
+ #endif // !TARGET_OS_IPHONE
+ #elif defined(__wasm__) // __APPLE__
+ inline constexpr PlatformType kTargetPlatform = PlatformType::kWasm;
+-#else // __wasm__
++#elif defined(__FreeBSD__) // __wasm__
++inline constexpr PlatformType kTargetPlatform = PlatformType::kFreeBSD;
++#else // __FreeBSD__
+ #error "Unsupported target platform."
+-#endif // !__wasm__
++#endif // !__FreeBSD__
+
+ } // namespace internal
+
+@@ -158,6 +161,11 @@ constexpr bool IsChromeos() {
+ // The build target is ChromeOS.
+ constexpr bool IsChromeos() {
+ return internal::kTargetPlatform == internal::PlatformType::kChromeos;
++}
++
++// The build target is FreeBSD.
++constexpr bool IsFreeBSD() {
++ return internal::kTargetPlatform == internal::PlatformType::kFreeBSD;
+ }
+
+ } // namespace port
diff --git a/japanese/mozc-server/files/patch-src-base-process.cc b/japanese/mozc-server/files/patch-src-base-process.cc
new file mode 100644
index 000000000000..ef6d4699f126
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-process.cc
@@ -0,0 +1,57 @@
+--- src/base/process.cc.orig 2026-10-18 06:50:24 UTC
++++ src/base/process.cc
+@@ -100,7 +100,7 @@ bool Process::OpenBrowser(absl::string_view url) {
+ L"open", win32::Utf8ToWide(url).c_str(), nullptr);
+ #endif // _WIN32
+
+-#ifdef __linux__
++#if defined(__linux__) || defined(__FreeBSD__)
+
+ #ifndef MOZC_BROWSER_COMMAND
+ // xdg-open which uses kfmclient or gnome-open internally works both on KDE
+@@ -109,7 +109,7 @@ bool Process::OpenBrowser(absl::string_view url) {
+ #endif // MOZC_BROWSER_COMMAND
+
+ return SpawnProcess(MOZC_BROWSER_COMMAND, url);
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
+
+ #ifdef __APPLE__
+ return MacProcess::OpenBrowserForMac(url);
+@@ -189,7 +189,7 @@ bool Process::SpawnProcess(absl::string_view path, abs
+ }
+ #endif // __APPLE__
+
+-#ifdef __linux__
++#if defined(__linux__) || defined(__FreeBSD__)
+ // Do not call posix_spawn() for obviously bad path.
+ if (!S_ISREG(statbuf.st_mode)) {
+ LOG(ERROR) << "Not a regular file: " << path;
+@@ -205,7 +205,9 @@ bool Process::SpawnProcess(absl::string_view path, abs
+ LOG(ERROR) << "Can't execute setuid or setgid binaries: " << path;
+ return false;
+ }
++#endif // __linux__ || __FreeBSD__
+
++#ifdef __linux__
+ // Use simple heap corruption checker in child processes. This setenv() does
+ // not affect current process behavior since Glibc never check the variable
+ // after main().
+@@ -389,7 +391,7 @@ bool Process::LaunchErrorMessageDialog(absl::string_vi
+ }
+ #endif // _WIN32
+
+-#if defined(__linux__) && !defined(__ANDROID__)
++#if (defined(__linux__) && !defined(__ANDROID__)) || defined(__FreeBSD__)
+ constexpr char kMozcTool[] = "mozc_tool";
+ const std::string arg =
+ absl::StrCat("--mode=error_message_dialog --error_type=", error_type);
+@@ -398,7 +400,7 @@ bool Process::LaunchErrorMessageDialog(absl::string_vi
+ LOG(ERROR) << "cannot launch " << kMozcTool;
+ return false;
+ }
+-#endif // __linux__ && !__ANDROID__
++#endif // (__linux__ && !__ANDROID__) || __FreeBSD__
+
+ return true;
+ }
diff --git a/japanese/mozc-server/files/patch-src-base-system_util.cc b/japanese/mozc-server/files/patch-src-base-system_util.cc
new file mode 100644
index 000000000000..3148182c4dbe
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-base-system_util.cc
@@ -0,0 +1,73 @@
+--- src/base/system_util.cc.orig 2026-10-16 12:33:33 UTC
++++ src/base/system_util.cc
+@@ -215,7 +215,7 @@ std::string UserProfileDirectoryImpl::GetUserProfileDi
+ return FileUtil::JoinPath(dir, "Mozc");
+ #endif // GOOGLE_JAPANESE_INPUT_BUILD
+
+-#elif defined(__linux__)
++#elif defined(__linux__) || defined(__FreeBSD__)
+ // 1. If "$HOME/.mozc" already exists,
+ // use "$HOME/.mozc" for backward compatibility.
+ // 2. If $XDG_CONFIG_HOME is defined
+@@ -313,7 +313,7 @@ std::string SystemUtil::GetServerDirectory() {
+ #endif // _WIN32
+
+ std::string SystemUtil::GetServerDirectory() {
+- if constexpr (port::IsLinuxBase() || port::IsWasm()) {
++ if constexpr (port::IsLinuxBase() || port::IsWasm() || port::IsFreeBSD()) {
+ return std::string(kMozcServerDir);
+ }
+
+@@ -369,7 +369,7 @@ std::string SystemUtil::GetDocumentDirectory() {
+ }
+
+ std::string SystemUtil::GetDocumentDirectory() {
+- if constexpr (port::IsLinuxBase()) {
++ if constexpr (port::IsLinuxBase() || port::IsFreeBSD()) {
+ return std::string(kMozcDocumentDir);
+ } else if constexpr (port::IsAppleBase()) {
+ return GetServerDirectory();
+@@ -562,9 +562,9 @@ std::string SystemUtil::GetDesktopNameAsString() {
+ #endif // _WIN32
+
+ std::string SystemUtil::GetDesktopNameAsString() {
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ return Environ::GetEnv("DISPLAY");
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+
+ #if defined(__APPLE__)
+ return "";
+@@ -623,9 +623,11 @@ std::string SystemUtil::GetOSVersionString() {
+ AndroidUtil::kSystemPropertyOsVersion, "Unknown"));
+ #elif defined(__linux__)
+ return "Linux";
+-#else // !_WIN32 && !__APPLE__ && !__linux__
++#elif defined(__FreeBSD__)
++ return "FreeBSD";
++#else // !_WIN32 && !__APPLE__ && !__linux__ && !__FreeBSD__
+ return "Unknown";
+-#endif // _WIN32, __APPLE__, __linux__
++#endif // _WIN32, __APPLE__, __linux__, __FreeBSD__
+ }
+
+ void SystemUtil::DisableIME() {
+@@ -660,7 +662,7 @@ uint64_t SystemUtil::GetTotalPhysicalMemory() {
+ return total_memory;
+ #endif // __APPLE__
+
+-#if defined(__linux__) || defined(__wasm__)
++#if defined(__linux__) || defined(__wasm__) || defined(__FreeBSD__)
+ #if defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
+ const int32_t page_size = sysconf(_SC_PAGESIZE);
+ const int32_t number_of_phyisical_pages = sysconf(_SC_PHYS_PAGES);
+@@ -673,7 +675,7 @@ uint64_t SystemUtil::GetTotalPhysicalMemory() {
+ #else // defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
+ return 0;
+ #endif // defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
+-#endif // __linux__ || __wasm__
++#endif // __linux__ || __wasm__ || __FreeBSD__
+
+ // If none of the above platforms is specified, the compiler raises an error
+ // because of no return value.
diff --git a/japanese/mozc-server/files/patch-src-bazel-cc_target_os-BUILD.bazel b/japanese/mozc-server/files/patch-src-bazel-cc_target_os-BUILD.bazel
new file mode 100644
index 000000000000..3a11a75a9ab9
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-bazel-cc_target_os-BUILD.bazel
@@ -0,0 +1,16 @@
+--- src/bazel/cc_target_os/BUILD.bazel.orig 2026-10-17 21:20:47 UTC
++++ src/bazel/cc_target_os/BUILD.bazel
+@@ -102,6 +102,13 @@ config_setting(
+ )
+
+ config_setting(
++ name = "oss_freebsd",
++ values = {
++ "define": "TARGET=oss_freebsd",
++ },
++)
++
++config_setting(
+ name = "wasm",
+ values = {
+ "define": "TARGET=wasm",
diff --git a/japanese/mozc-server/files/patch-src-bazel-pkg_config_repository.bzl b/japanese/mozc-server/files/patch-src-bazel-pkg_config_repository.bzl
new file mode 100644
index 000000000000..e7250370152e
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-bazel-pkg_config_repository.bzl
@@ -0,0 +1,36 @@
+--- src/bazel/pkg_config_repository.bzl.orig 2026-10-16 12:33:33 UTC
++++ src/bazel/pkg_config_repository.bzl
+@@ -181,13 +181,32 @@ def _pkg_config_repository_impl(repo_ctx):
+ if not includes or includes[0] == "":
+ includes = _exec_pkg_config(repo_ctx, ["--cflags-only-I", "--keep-system-cflags"])
+ includes = [item[len("-I/"):] for item in includes]
++
++ local_include = "%%LOCALBASE%%/include".lstrip("/")
++
++ if "ibus-1.0" in repo_ctx.attr.packages:
++ includes = [path for path in includes if path != local_include]
++
++ if "gl" in repo_ctx.attr.packages:
++ filtered_includes = []
++ for path in includes:
++ if path == local_include:
++ for subdir in ["GL", "KHR"]:
++ source = repo_ctx.path("/" + path + "/" + subdir)
++ if not source.exists:
++ fail("Required OpenGL include directory not found: %s" % source)
++ repo_ctx.symlink(source, "opengl_include/" + subdir)
++ filtered_includes.append("opengl_include")
++ else:
++ filtered_includes.append(path)
++ includes = filtered_includes
+ _symlinks(repo_ctx, includes)
+ data = {
+ "name": name,
+ "hdrs": _make_strlist([item + "/**" for item in includes]),
+ "copts": _make_strlist(_exec_pkg_config(repo_ctx, ["--cflags-only-other"])),
+ "includes": _make_strlist(includes),
+- "linkopts": _make_strlist(_exec_pkg_config(repo_ctx, ["--libs-only-l"])),
++ "linkopts": _make_strlist(_exec_pkg_config(repo_ctx, ["--libs"])),
+ }
+ build_file_data = BUILD_TEMPLATE.format(**data)
+
diff --git a/japanese/mozc-server/files/patch-src-build_defs.bzl b/japanese/mozc-server/files/patch-src-build_defs.bzl
new file mode 100644
index 000000000000..4d593b97904a
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-build_defs.bzl
@@ -0,0 +1,37 @@
+--- src/build_defs.bzl.orig 2026-10-17 21:16:39 UTC
++++ src/build_defs.bzl
+@@ -835,12 +835,14 @@ def mozc_select(
+ oss = None,
+ android = None,
+ apple = None,
++ freebsd = None,
+ ios = None,
+ chromiumos = None,
+ linux = None,
+ macos = None,
+ oss_android = None,
+ oss_linux = None,
++ oss_freebsd = None,
+ oss_macos = None,
+ oss_windows = None,
+ prod = None,
+@@ -866,9 +868,11 @@ def mozc_select(
+ ios: value for iOS build.
+ chromiumos: value for ChromeOS build.
+ linux: value for Linux build.
++ freebsd: value for FreeBSD build.
+ macos: value for macOS build.
+ oss_android: value for OSS Android build.
+ oss_linux: value for OSS Linux build.
++ oss_freebsd: value for OSS FreeBSD build.
+ oss_macos: value for OSS macOS build.
+ oss_windows: value for OSS Windows build.
+ prod: value for prod build.
+@@ -891,6 +895,7 @@ def mozc_select(
+ "//bazel/cc_target_os:linux": _get_value([linux, client, default]),
+ "//bazel/cc_target_os:oss_android": _get_value([oss_android, oss, android, client, default]),
+ "//bazel/cc_target_os:oss_linux": _get_value([oss_linux, oss, linux, client, default]),
++ "//bazel/cc_target_os:oss_freebsd": _get_value([oss_freebsd, oss_linux, oss, freebsd, linux, client, default]),
+ "//bazel/cc_target_os:oss_macos": _get_value([oss_macos, oss, macos, apple, client, default]),
+ "//bazel/cc_target_os:oss_windows": _get_value([oss_windows, oss, windows, client, default]),
+ "//bazel/cc_target_os:prod_linux": _get_value([prod_linux, prod, oss_linux, oss, linux, client, default]),
diff --git a/japanese/mozc-server/files/patch-src-client-client.cc b/japanese/mozc-server/files/patch-src-client-client.cc
new file mode 100644
index 000000000000..c77cb2ff1ce1
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-client-client.cc
@@ -0,0 +1,20 @@
+--- src/client/client.cc.orig 2026-10-18 06:52:10 UTC
++++ src/client/client.cc
+@@ -884,7 +884,7 @@ bool Client::LaunchTool(absl::string_view mode,
+ return false;
+ }
+
+-#if defined(_WIN32) || defined(__linux__)
++#if defined(_WIN32) || defined(__linux__) || defined(__FreeBSD__)
+ std::string arg = absl::StrCat("--mode=", mode);
+ if (!extra_arg.empty()) {
+ absl::StrAppend(&arg, " ", extra_arg);
+@@ -893,7 +893,7 @@ bool Client::LaunchTool(absl::string_view mode,
+ LOG(ERROR) << "Cannot execute: " << kMozcTool << " " << arg;
+ return false;
+ }
+-#endif // _WIN32 || __linux__
++#endif // _WIN32 || __linux__ || __FreeBSD__
+
+ // TODO(taku): move MacProcess inside SpawnMozcProcess.
+ // TODO(taku): support extra_arg.
diff --git a/japanese/mozc-server/files/patch-src-config.bzl b/japanese/mozc-server/files/patch-src-config.bzl
new file mode 100644
index 000000000000..85350378e21e
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-config.bzl
@@ -0,0 +1,29 @@
+--- src/config.bzl.orig 2026-10-16 12:33:33 UTC
++++ src/config.bzl
+@@ -37,16 +37,16 @@ BAZEL_TOOLS_PREFIX = "@bazel_tools"
+
+ BAZEL_TOOLS_PREFIX = "@bazel_tools"
+
+-LINUX_MOZC_BROWSER_COMMAND = "/usr/bin/xdg-open"
+-LINUX_MOZC_ICONS_DIR = "/usr/share/icons/mozc"
+-LINUX_MOZC_SERVER_DIR = "/usr/lib/mozc"
+-LINUX_MOZC_DOCUMENT_DIR = LINUX_MOZC_SERVER_DIR + "/documents"
+-IBUS_COMPONENT_DIR = "/usr/share/ibus/component"
+-IBUS_MOZC_INSTALL_DIR = "/usr/share/ibus-mozc"
+-IBUS_MOZC_ICON_PATH = IBUS_MOZC_INSTALL_DIR + "/product_icon.png"
+-IBUS_MOZC_PATH = "/usr/lib/ibus-mozc/ibus-engine-mozc"
+-EMACS_MOZC_CLIENT_DIR = "/usr/share/emacs/site-lisp/emacs-mozc"
+-EMACS_MOZC_HELPER_DIR = "/usr/bin"
++LINUX_MOZC_BROWSER_COMMAND = "%%LOCALBASE%%/bin/xdg-open"
++LINUX_MOZC_ICONS_DIR = "%%PREFIX%%/share/mozc/icons"
++LINUX_MOZC_SERVER_DIR = "%%PREFIX%%/libexec"
++LINUX_MOZC_DOCUMENT_DIR = "%%DOCSDIR%%"
++IBUS_COMPONENT_DIR = "%%PREFIX%%/share/ibus/component"
++IBUS_MOZC_INSTALL_DIR = "%%LOCALBASE%%/share/mozc/icons"
++IBUS_MOZC_ICON_PATH = IBUS_MOZC_INSTALL_DIR + "/mozc.png"
++IBUS_MOZC_PATH = "%%PREFIX%%/libexec/ibus-engine-mozc"
++EMACS_MOZC_CLIENT_DIR = "%%PREFIX%%/%%EMACS_SITE_LISPDIR%%/mozc"
++EMACS_MOZC_HELPER_DIR = "%%PREFIX%%/libexec"
+
+ MACOS_BUNDLE_ID_PREFIX = "org.mozc.inputmethod.Japanese"
+ MACOS_MIN_OS_VER = "12.0"
diff --git a/japanese/mozc-server/files/patch-src-gui-config_dialog-config_dialog.cc b/japanese/mozc-server/files/patch-src-gui-config_dialog-config_dialog.cc
new file mode 100644
index 000000000000..78dbf3e26925
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-gui-config_dialog-config_dialog.cc
@@ -0,0 +1,46 @@
+--- src/gui/config_dialog/config_dialog.cc.orig 2026-10-18 07:08:38 UTC
++++ src/gui/config_dialog/config_dialog.cc
+@@ -121,21 +121,21 @@ ConfigDialog::ConfigDialog()
+ setWindowTitle(tr("%1 Preferences").arg(GuiUtil::ProductName()));
+ #endif // __APPLE__
+
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__FreeBSD__)
+ miscDefaultIMEWidget->setVisible(false);
+ miscAdministrationWidget->setVisible(false);
+ miscStartupWidget->setVisible(false);
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
+
+ #ifdef NDEBUG
+ // disable logging options
+ miscLoggingWidget->setVisible(false);
+
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__FreeBSD__)
+ // The last "misc" tab has no valid configs on Linux
+ constexpr int kMiscTabIndex = 6;
+ configDialogTabWidget->removeTab(kMiscTabIndex);
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
+ #endif // NDEBUG
+
+ suggestionsSizeSpinBox->setRange(1, 9);
+@@ -293,7 +293,7 @@ ConfigDialog::ConfigDialog()
+ dictionaryPreloadingAndUACLabel->setVisible(false);
+ #endif // _WIN32
+
+-#ifdef __linux__
++#if defined(__linux__) || defined(__FreeBSD__)
+ // On Linux, disable all fields for UsageStats
+ usageStatsLabel->setEnabled(false);
+ usageStatsLabel->setVisible(false);
+@@ -303,7 +303,7 @@ ConfigDialog::ConfigDialog()
+ usageStatsMessage->setVisible(false);
+ usageStatsCheckBox->setEnabled(false);
+ usageStatsCheckBox->setVisible(false);
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
+
+ GuiUtil::ReplaceWidgetLabels(this);
+
diff --git a/japanese/mozc-server/files/patch-src-gui-config_dialog-keybinding_editor.cc b/japanese/mozc-server/files/patch-src-gui-config_dialog-keybinding_editor.cc
new file mode 100644
index 000000000000..3e66b0f79a6d
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-gui-config_dialog-keybinding_editor.cc
@@ -0,0 +1,31 @@
+--- src/gui/config_dialog/keybinding_editor.cc.orig 2026-10-16 12:33:33 UTC
++++ src/gui/config_dialog/keybinding_editor.cc
+@@ -111,8 +111,8 @@ constexpr auto kQtKeyModifierNonRequiredTable =
+ {Qt::Key_Hiragana_Katakana, "Hiragana"},
+ {Qt::Key_Eisu_toggle, "Eisu"},
+ {Qt::Key_Zenkaku_Hankaku, "Hankaku/Zenkaku"},
+-#ifdef __linux__
+- // On Linux (X / Wayland), Hangul and Hanja are identical with
++#if defined(__linux__) || defined(__FreeBSD__)
++ // On Linux and FreeBSD (X / Wayland), Hangul and Hanja are identical with
+ // ImeOn and ImeOff.
+ // https://github.com/google/mozc/issues/552
+ //
+@@ -120,7 +120,7 @@ constexpr auto kQtKeyModifierNonRequiredTable =
+ {Qt::Key_Hangul, "ON"},
+ // Hanja == Lang2 (USB HID) / ImeOff (Windows) / Eisu (macOS)
+ {Qt::Key_Hangul_Hanja, "OFF"},
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
+ });
+ // LINT.ThenChange(//composer/key_parser_test.cc)
+
+@@ -401,7 +401,7 @@ KeyBindingFilter::KeyState KeyBindingFilter::AddKey(co
+ return Encode(result);
+ }
+
+- unknown_key_.asprintf("<UNK:0x%x 0x%x 0x%x>", key_event.key(),
++ unknown_key_ = QString::asprintf("<UNK:0x%x 0x%x 0x%x>", key_event.key(),
+ key_event.nativeScanCode(),
+ key_event.nativeVirtualKey());
+
diff --git a/japanese/mozc-server/files/patch-src-gui-word_register_dialog-word_register_dialog.cc b/japanese/mozc-server/files/patch-src-gui-word_register_dialog-word_register_dialog.cc
new file mode 100644
index 000000000000..afe725a1f513
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-gui-word_register_dialog-word_register_dialog.cc
@@ -0,0 +1,14 @@
+--- src/gui/word_register_dialog/word_register_dialog.cc.orig 2026-10-18 07:12:43 UTC
++++ src/gui/word_register_dialog/word_register_dialog.cc
+@@ -97,9 +97,9 @@ QString GetEnv(const char* envname) {
+ }
+ return QLatin1String("");
+ #endif // _WIN32
+-#if defined(__APPLE__) || defined(__linux__)
++#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__)
+ return QString::fromUtf8(::getenv(envname));
+-#endif // __APPLE__ or __linux__
++#endif // __APPLE__ || __linux__ || __FreeBSD__
+ // TODO(team): Support other platforms.
+ return QLatin1String("");
+ }
diff --git a/japanese/mozc-server/files/patch-src-ipc-BUILD.bazel b/japanese/mozc-server/files/patch-src-ipc-BUILD.bazel
new file mode 100644
index 000000000000..01838a087023
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-ipc-BUILD.bazel
@@ -0,0 +1,25 @@
+--- src/ipc/BUILD.bazel.orig 2026-10-18 06:47:04 UTC
++++ src/ipc/BUILD.bazel
+@@ -41,6 +41,11 @@ package(default_visibility = ["//visibility:private"])
+
+ package(default_visibility = ["//visibility:private"])
+
++config_setting(
++ name = "freebsd",
++ constraint_values = ["@platforms//os:freebsd"],
++)
++
+ mozc_cc_library(
+ name = "ipc",
+ srcs = [
+@@ -126,6 +131,10 @@ mozc_cc_library(
+ "@com_microsoft_wil//:wil",
+ ],
+ ),
++ linkopts = select({
++ ":freebsd": ["-lprocstat"],
++ "//conditions:default": [],
++ }),
+ )
+
+ mozc_cc_test(
diff --git a/japanese/mozc-server/files/patch-src-ipc-ipc_path_manager.cc b/japanese/mozc-server/files/patch-src-ipc-ipc_path_manager.cc
new file mode 100644
index 000000000000..d360759e0126
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-ipc-ipc_path_manager.cc
@@ -0,0 +1,65 @@
+--- src/ipc/ipc_path_manager.cc.orig 2026-10-16 12:33:33 UTC
++++ src/ipc/ipc_path_manager.cc
+@@ -85,6 +85,14 @@
+ #include <unistd.h>
+ #endif // _WIN32
+
++#ifdef __FreeBSD__
++#include <sys/param.h>
++#include <sys/queue.h>
++#include <sys/socket.h>
++#include <sys/sysctl.h>
++#include <libprocstat.h>
++#endif // __FreeBSD__
++
+ namespace mozc {
+ namespace {
+
+@@ -389,7 +397,37 @@ bool IPCPathManager::IsValidServer(uint32_t pid,
+ server_pid_ = pid;
+ #endif // __APPLE__
+
+-#ifdef __linux__
++#if defined(__FreeBSD__)
++ struct kinfo_proc *kipp;
++ struct procstat *prstat;
++ char filename[PATH_MAX];
++ unsigned int count = 0;
++
++ prstat = procstat_open_sysctl();
++ if (prstat == NULL) {
++ LOG(ERROR) << "procstat_open_sysctl failed: " << strerror(errno);
++ return false;
++ }
++ kipp = procstat_getprocs(prstat, KERN_PROC_PID, pid, &count);
++ if (kipp == nullptr || count != 1) {
++ LOG(ERROR) << "Cannot find a unique process for pid: " << pid;
++ if (kipp != nullptr) {
++ procstat_freeprocs(prstat, kipp);
++ }
++ procstat_close(prstat);
++ return false;
++ }
++ if (procstat_getpathname(prstat, kipp, filename, sizeof(filename)) != 0) {
++ LOG(ERROR) << "procstat_getpathname failed: " << strerror(errno);
++ procstat_freeprocs(prstat, kipp);
++ procstat_close(prstat);
++ return false;
++ }
++ procstat_freeprocs(prstat, kipp);
++ procstat_close(prstat);
++ server_path_ = filename;
++ server_pid_ = pid;
++#elif defined(__linux__)
+ // load from /proc/<pid>/exe
+ std::string proc = absl::StrFormat("/proc/%u/exe", pid);
+ absl::StatusOr<std::string> filename = FileUtil::ReadSymlink(proc);
+@@ -400,7 +438,7 @@ bool IPCPathManager::IsValidServer(uint32_t pid,
+
+ server_path_ = filename.value();
+ server_pid_ = pid;
+-#endif // __linux__
++#endif // __FreeBSD__
+
+ MOZC_VLOG(1) << "server path: " << server_path << " " << server_path_;
+
diff --git a/japanese/mozc-server/files/patch-src-ipc-unix_ipc.cc b/japanese/mozc-server/files/patch-src-ipc-unix_ipc.cc
new file mode 100644
index 000000000000..f4070da66eaf
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-ipc-unix_ipc.cc
@@ -0,0 +1,133 @@
+--- src/ipc/unix_ipc.cc.orig 2026-10-17 20:10:12 UTC
++++ src/ipc/unix_ipc.cc
+@@ -28,13 +28,16 @@
+ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ // __linux__ only. Note that __ANDROID__/__wasm__ don't reach here.
+-#if defined(__linux__)
++#if defined(__linux__) || defined(__FreeBSD__)
+
+ #include <fcntl.h>
+ #include <sys/select.h>
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
++#if defined(__FreeBSD__)
++#include <sys/ucred.h>
++#endif // __FreeBSD__
+ #include <sys/un.h>
+ #include <unistd.h>
+
+@@ -55,9 +58,13 @@
+ #include "ipc/ipc.h"
+ #include "ipc/ipc_path_manager.h"
+
++#if defined(__FreeBSD__)
++#define UNIX_PATH_MAX sizeof(((struct sockaddr_un *)nullptr)->sun_path)
++#else // __FreeBSD__
+ #ifndef UNIX_PATH_MAX
+ #define UNIX_PATH_MAX 108
+ #endif // UNIX_PATH_MAX
++#endif // __FreeBSD__
+
+ namespace mozc {
+ namespace {
+@@ -121,21 +128,45 @@ bool IsPeerValid(int socket, pid_t *pid) {
+ bool IsPeerValid(int socket, pid_t *pid) {
+ *pid = 0;
+
+- struct ucred peer_cred;
+- int peer_cred_len = sizeof(peer_cred);
+- if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &peer_cred,
+- reinterpret_cast<socklen_t *>(&peer_cred_len)) < 0) {
+- LOG(ERROR) << "cannot get peer credential. Not a Unix socket?";
++#if defined(__FreeBSD__)
++ struct xucred peer_cred = {};
++ socklen_t peer_cred_len = sizeof(peer_cred);
++ if (getsockopt(socket, SOL_LOCAL, LOCAL_PEERCRED,
++ &peer_cred, &peer_cred_len) < 0) {
++ LOG(ERROR) << "cannot get peer credential: " << strerror(errno);
+ return false;
+ }
++ if (peer_cred_len != sizeof(peer_cred) ||
++ peer_cred.cr_version != XUCRED_VERSION) {
++ LOG(ERROR) << "invalid peer credential";
++ return false;
++ }
++ const uid_t peer_uid = peer_cred.cr_uid;
++ const pid_t peer_pid = peer_cred.cr_pid;
++#else
++ struct ucred peer_cred = {};
++ socklen_t peer_cred_len = sizeof(peer_cred);
++ if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED,
++ &peer_cred, &peer_cred_len) < 0) {
++ LOG(ERROR) << "cannot get peer credential: " << strerror(errno);
++ return false;
++ }
++ const uid_t peer_uid = peer_cred.uid;
++ const pid_t peer_pid = peer_cred.pid;
++#endif
+
+- if (peer_cred.uid != ::geteuid()) {
+- LOG(WARNING) << "uid mismatch." << peer_cred.uid << "!=" << ::geteuid();
++ if (peer_uid != ::geteuid()) {
++ LOG(WARNING) << "uid mismatch." << peer_uid << "!=" << ::geteuid();
+ return false;
+ }
+
+- *pid = peer_cred.pid;
++ if (peer_pid <= 0) {
++ LOG(ERROR) << "invalid peer pid: " << peer_pid;
++ return false;
++ }
+
++ *pid = peer_pid;
++
+ return true;
+ }
+
+@@ -250,9 +281,6 @@ void IPCClient::Init(absl::string_view name,
+ continue;
+ }
+ sockaddr_un address = {};
+- const size_t server_address_length =
+- (server_address.size() >= UNIX_PATH_MAX) ? UNIX_PATH_MAX - 1
+- : server_address.size();
+ if (server_address.size() >= UNIX_PATH_MAX) {
+ LOG(WARNING) << "too long path: " << server_address;
+ }
+@@ -265,7 +293,15 @@ void IPCClient::Init(absl::string_view name,
+ address.sun_family = AF_UNIX;
+ absl::SNPrintF(address.sun_path, sizeof(address.sun_path), "%s",
+ server_address);
++#if defined(__FreeBSD__)
++ address.sun_len = SUN_LEN(&address);
++ const socklen_t sun_len = address.sun_len;
++#else // __FreeBSD__
++ const size_t server_address_length =
++ (server_address.size() >= UNIX_PATH_MAX) ? UNIX_PATH_MAX - 1
++ : server_address.size();
+ const size_t sun_len = sizeof(address.sun_family) + server_address_length;
++#endif // __FreeBSD__
+ pid_t pid = 0;
+ if (::connect(socket_, reinterpret_cast<const sockaddr *>(&address),
+ sun_len) != 0 ||
+@@ -381,7 +417,12 @@ IPCServer::IPCServer(absl::string_view name, int32_t n
+ int on = 1;
+ ::setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&on),
+ sizeof(on));
++#if defined(__FreeBSD__)
++ addr.sun_len = SUN_LEN(&addr);
++ const socklen_t sun_len = addr.sun_len;
++#else // __FreeBSD__
+ const size_t sun_len = sizeof(addr.sun_family) + server_address_.size();
++#endif // __FreeBSD__
+ if (is_file_socket) {
+ // Linux does not use files for IPC.
+ ::chmod(server_address_.c_str(), 0600);
+@@ -481,4 +522,4 @@ void IPCServer::Terminate() {
+
+ } // namespace mozc
+
+-#endif // __linux__
++#endif // __linux__ || __FreeBSD__
diff --git a/japanese/mozc-server/files/patch-src-unix-emacs-mozc.el b/japanese/mozc-server/files/patch-src-unix-emacs-mozc.el
new file mode 100644
index 000000000000..638d351ff27c
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-unix-emacs-mozc.el
@@ -0,0 +1,16 @@
+--- src/unix/emacs/mozc.el.orig 2026-10-16 12:33:33 UTC
++++ src/unix/emacs/mozc.el
+@@ -1,3 +1,4 @@
++;; -*- lexical-binding: nil; -*-
+ ;;; mozc.el --- minor mode to input Japanese with Mozc
+
+ ;; Copyright 2010-2021, Google Inc. All rights reserved.
+@@ -1551,7 +1552,7 @@ Return the new value of `mozc-session-seq'."
+
+ ;;;; Communication with Mozc server through the helper process
+
+-(defvar mozc-helper-program-name "mozc_emacs_helper"
++(defvar mozc-helper-program-name "%%LOCALBASE%%/libexec/mozc_emacs_helper"
+ "Helper program's name or path to the helper program.
+ The helper program helps Emacs communicate with Mozc server,
+ which doesn't understand S-expression.")
diff --git a/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.cc b/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.cc
new file mode 100644
index 000000000000..774e626ddca7
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.cc
@@ -0,0 +1,22 @@
+--- src/unix/ibus/ibus_wrapper.cc.orig 2026-10-18 10:27:15 UTC
++++ src/unix/ibus/ibus_wrapper.cc
+@@ -36,8 +36,8 @@ static_assert(std::is_same<gint, int>::value, "gint mu
+ #include "absl/strings/string_view.h"
+
+ static_assert(std::is_same<gint, int>::value, "gint must be int.");
+-static_assert(std::is_same<guint, uint>::value, "guint must be uint.");
+-static_assert(std::is_same<gulong, ulong>::value, "guint must be ulong.");
++static_assert(std::is_same<guint, unsigned int>::value, "guint must be unsigned int.");
++static_assert(std::is_same<gulong, unsigned long>::value, "gulong must be unsigned long.");
+ static_assert(std::is_same<gchar, char>::value, "gchar must be char.");
+ static_assert(std::is_same<gboolean, int>::value, "gboolean must be int.");
+ static_assert(std::is_same<gpointer, void*>::value, "gpointer must be void*.");
+@@ -78,7 +78,7 @@ void GobjectWrapper::RefSink() {
+ g_object_ref_sink(obj);
+ }
+
+-void GobjectWrapper::SignalHandlerDisconnect(ulong id) {
++void GobjectWrapper::SignalHandlerDisconnect(unsigned long id) {
+ GObject* obj = GetGobject();
+ if (obj == nullptr) {
+ return;
diff --git a/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.h b/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.h
new file mode 100644
index 000000000000..61e2e1ec9619
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-unix-ibus-ibus_wrapper.h
@@ -0,0 +1,20 @@
+--- src/unix/ibus/ibus_wrapper.h.orig 2026-10-18 10:26:37 UTC
++++ src/unix/ibus/ibus_wrapper.h
+@@ -65,7 +65,7 @@ class GobjectWrapper {
+ }
+
+ template <typename C, typename D>
+- ulong SignalConnect(absl::string_view signal, C callback, D* user_data) {
++ unsigned long SignalConnect(absl::string_view signal, C callback, D* user_data) {
+ GObject* obj = GetGobject();
+ if (obj == nullptr) {
+ return 0;
+@@ -75,7 +75,7 @@ class GobjectWrapper {
+ reinterpret_cast<gpointer>(user_data));
+ }
+
+- void SignalHandlerDisconnect(ulong id);
++ void SignalHandlerDisconnect(unsigned long id);
+ };
+
+ class GsettingsWrapper : public GobjectWrapper {
diff --git a/japanese/mozc-server/files/patch-src-unix-ibus-property_handler.cc b/japanese/mozc-server/files/patch-src-unix-ibus-property_handler.cc
new file mode 100644
index 000000000000..3406f94ae7d5
--- /dev/null
+++ b/japanese/mozc-server/files/patch-src-unix-ibus-property_handler.cc
@@ -0,0 +1,11 @@
+--- src/unix/ibus/property_handler.cc.orig 2026-10-18 11:04:15 UTC
++++ src/unix/ibus/property_handler.cc
+@@ -132,7 +132,7 @@ constexpr MozcEngineToolProperty kMozcEngineToolProper
+ "Tool.WordRegisterDialog",
+ "word_register_dialog",
+ "Add Word",
+- "word_register.png",
++ "dictionary.png",
+ },
+ {
+ "Tool.AboutDialog",
diff --git a/japanese/mozc-server/files/patch-src-unix_emacs_mozc.el b/japanese/mozc-server/files/patch-src-unix_emacs_mozc.el
deleted file mode 100644
index 5fa1efa6a9c9..000000000000
--- a/japanese/mozc-server/files/patch-src-unix_emacs_mozc.el
+++ /dev/null
@@ -1,43 +0,0 @@
---- src/unix/emacs/mozc.el.orig 2019-03-04 18:35:55 UTC
-+++ src/unix/emacs/mozc.el
-@@ -1540,7 +1540,7 @@ Return the new value of `mozc-session-seq'."
-
- ;;;; Communication with Mozc server through the helper process
-
--(defvar mozc-helper-program-name "mozc_emacs_helper"
-+(defvar mozc-helper-program-name "%%PREFIX%%/libexec/mozc_emacs_helper"
- "Helper program's name or path to the helper program.
- The helper program helps Emacs communicate with Mozc server,
- which doesn't understand S-expression.")
-@@ -1975,12 +1975,12 @@ INPUT-METHOD is not used."
- "Deactivate function `mozc-mode' via LEIM."
- (mozc-mode nil))
-
--(defcustom mozc-leim-title "[Mozc]"
-- "Mode line string shown when function `mozc-mode' is enabled.
--This indicator is not shown when you don't use LEIM."
-- :type '(choice (const :tag "No indicator" nil)
-- (string :tag "Show an indicator"))
-- :group 'mozc)
-+;;(defcustom mozc-leim-title "[Mozc]"
-+;; "Mode line string shown when function `mozc-mode' is enabled.
-+;;This indicator is not shown when you don't use LEIM."
-+;; :type '(choice (const :tag "No indicator" nil)
-+;; (string :tag "Show an indicator"))
-+;; :group 'mozc)
-
- (defun mozc-leim-register-input-method ()
- "Register function `mozc-mode' as an input method of LEIM.
-@@ -1996,10 +1996,10 @@ Do nothing if LEIM is not available."
- ;; Register mozc-mode as an input method after the init file has been read
- ;; so the user has a chance to specify `mozc-leim-title' in the init file
- ;; after loading this file.
--(add-hook 'emacs-startup-hook #'mozc-leim-register-input-method)
-+;;(add-hook 'emacs-startup-hook #'mozc-leim-register-input-method)
- ;; In the case that `emacs-startup-hook' has already been run, especially
- ;; when the user loads this file interactively, register immediately.
--(mozc-leim-register-input-method)
-+;;(mozc-leim-register-input-method)
-
-
-
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary.cc
deleted file mode 100644
index 896ab9cf906e..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/dictionary/user_dictionary.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary.cc
-@@ -289,7 +289,7 @@ class UserDictionary::UserDictionaryRelo
- }
-
- auto_register_mode_ = false;
-- dic_->Load(*(storage.get()));
-+ dic_->Load(storage.get()->user_dictionary_storage_base);
- }
-
- private:
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session.cc
deleted file mode 100644
index c18ddb812b3a..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session.cc
+++ /dev/null
@@ -1,200 +0,0 @@
---- src/dictionary/user_dictionary_session.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary_session.cc
-@@ -69,11 +69,11 @@ class UndoCreateDictionaryCommand : publ
- }
-
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
-- if (storage->dictionaries_size() == 0) {
-+ if (storage->user_dictionary_storage_base.dictionaries_size() == 0) {
- return false;
- }
-
-- storage->mutable_dictionaries()->RemoveLast();
-+ storage->user_dictionary_storage_base.mutable_dictionaries()->RemoveLast();
- return true;
- }
-
-@@ -94,7 +94,7 @@ class UndoDeleteDictionaryCommand : publ
- }
-
- RepeatedPtrField<UserDictionary> *dictionaries =
-- storage->mutable_dictionaries();
-+ storage->user_dictionary_storage_base.mutable_dictionaries();
- dictionaries->AddAllocated(dictionary_.release());
-
- // Adjust the position of the reverted dictionary.
-@@ -120,10 +120,10 @@ class UndoDeleteDictionaryWithEnsuringNo
- }
-
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
-- if (storage->dictionaries_size() != 1) {
-+ if (storage->user_dictionary_storage_base.dictionaries_size() != 1) {
- return false;
- }
-- dictionary_->Swap(storage->mutable_dictionaries(0));
-+ dictionary_->Swap(storage->user_dictionary_storage_base.mutable_dictionaries(0));
- return true;
- }
-
-@@ -144,7 +144,7 @@ class UndoRenameDictionaryCommand : publ
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage, dictionary_id_);
-+ &storage->user_dictionary_storage_base, dictionary_id_);
- if (dictionary == NULL) {
- return false;
- }
-@@ -169,7 +169,7 @@ class UndoAddEntryCommand : public UserD
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage, dictionary_id_);
-+ &storage->user_dictionary_storage_base, dictionary_id_);
- if (dictionary == NULL || dictionary->entries_size() == 0) {
- return false;
- }
-@@ -195,7 +195,7 @@ class UndoEditEntryCommand : public User
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage, dictionary_id_);
-+ &storage->user_dictionary_storage_base, dictionary_id_);
- if (dictionary == NULL ||
- index_ < 0 || dictionary->entries_size() <= index_) {
- return false;
-@@ -240,7 +240,7 @@ class UndoDeleteEntryCommand : public Us
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage, dictionary_id_);
-+ &storage->user_dictionary_storage_base, dictionary_id_);
- if (dictionary == NULL) {
- return false;
- }
-@@ -306,7 +306,7 @@ class UndoImportFromStringCommand : publ
- virtual bool RunUndo(mozc::UserDictionaryStorage *storage) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage, dictionary_id_);
-+ &storage->user_dictionary_storage_base, dictionary_id_);
- if (dictionary == NULL) {
- return false;
- }
-@@ -345,7 +345,7 @@ UserDictionarySession::~UserDictionarySe
-
- // TODO(hidehiko) move this to header.
- const UserDictionaryStorage &UserDictionarySession::storage() const {
-- return *storage_;
-+ return storage_->user_dictionary_storage_base;
- }
- mozc::UserDictionaryStorage *UserDictionarySession::mutable_storage() {
- return storage_.get();
-@@ -464,7 +464,7 @@ UserDictionaryCommandStatus::Status User
- const string &dictionary_name, uint64 *new_dictionary_id) {
- UserDictionaryCommandStatus::Status status =
- UserDictionaryUtil::CreateDictionary(
-- storage_.get(), dictionary_name, new_dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_name, new_dictionary_id);
- if (status == UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS) {
- AddUndoCommand(new UndoCreateDictionaryCommand);
- }
-@@ -488,7 +488,7 @@ UserDictionarySession::DeleteDictionaryI
- int original_index;
- UserDictionary *deleted_dictionary;
- if (!UserDictionaryUtil::DeleteDictionary(
-- storage_.get(), dictionary_id,
-+ &storage_->user_dictionary_storage_base, dictionary_id,
- &original_index, &deleted_dictionary)) {
- // Failed to delete the dictionary.
- return UserDictionaryCommandStatus::UNKNOWN_DICTIONARY_ID;
-@@ -510,7 +510,7 @@ UserDictionaryCommandStatus::Status User
- uint64 dictionary_id, const string &dictionary_name) {
- string original_name;
- const UserDictionary *dictionary =
-- UserDictionaryUtil::GetUserDictionaryById(*storage_, dictionary_id);
-+ UserDictionaryUtil::GetUserDictionaryById(storage_->user_dictionary_storage_base, dictionary_id);
- if (dictionary != NULL) {
- // Note that if dictionary is null, it means the dictionary_id is invalid
- // so following RenameDictionary will fail, and error handling is done
-@@ -547,7 +547,7 @@ UserDictionaryCommandStatus::Status User
- uint64 dictionary_id, const UserDictionary::Entry &entry) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage_.get(), dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_id);
- if (dictionary == NULL) {
- return UserDictionaryCommandStatus::UNKNOWN_DICTIONARY_ID;
- }
-@@ -575,7 +575,7 @@ UserDictionaryCommandStatus::Status User
- uint64 dictionary_id, int index, const UserDictionary::Entry &entry) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage_.get(), dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_id);
- if (dictionary == NULL) {
- return UserDictionaryCommandStatus::UNKNOWN_DICTIONARY_ID;
- }
-@@ -604,7 +604,7 @@ UserDictionaryCommandStatus::Status User
- uint64 dictionary_id, const std::vector<int> &index_list) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage_.get(), dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_id);
- if (dictionary == NULL) {
- return UserDictionaryCommandStatus::UNKNOWN_DICTIONARY_ID;
- }
-@@ -644,7 +644,7 @@ UserDictionaryCommandStatus::Status User
- uint64 dictionary_id, const string &data) {
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage_.get(), dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_id);
- if (dictionary == NULL) {
- return UserDictionaryCommandStatus::UNKNOWN_DICTIONARY_ID;
- }
-@@ -699,7 +699,7 @@ UserDictionarySession::ImportToNewDictio
- uint64 *new_dictionary_id) {
- UserDictionaryCommandStatus::Status status =
- UserDictionaryUtil::CreateDictionary(
-- storage_.get(), dictionary_name, new_dictionary_id);
-+ &storage_->user_dictionary_storage_base, dictionary_name, new_dictionary_id);
- if (status != UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS) {
- return status;
- }
-@@ -709,7 +709,7 @@ UserDictionarySession::ImportToNewDictio
-
- UserDictionary *dictionary =
- UserDictionaryUtil::GetMutableUserDictionaryById(
-- storage_.get(), *new_dictionary_id);
-+ &storage_->user_dictionary_storage_base, *new_dictionary_id);
- if (dictionary == NULL) {
- // The dictionary should be always found.
- return UserDictionaryCommandStatus::UNKNOWN_ERROR;
-@@ -719,7 +719,7 @@ UserDictionarySession::ImportToNewDictio
- }
-
- bool UserDictionarySession::EnsureNonEmptyStorage() {
-- if (storage_->dictionaries_size() > 0) {
-+ if (storage_->user_dictionary_storage_base.dictionaries_size() > 0) {
- // The storage already has at least one dictionary. Do nothing.
- return false;
- }
-@@ -728,7 +728,7 @@ bool UserDictionarySession::EnsureNonEmp
- uint64 new_dictionary_id;
- UserDictionaryCommandStatus::Status status =
- UserDictionaryUtil::CreateDictionary(
-- storage_.get(), default_dictionary_name_, &new_dictionary_id);
-+ &storage_->user_dictionary_storage_base, default_dictionary_name_, &new_dictionary_id);
- CHECK_EQ(
- status, UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS);
- return true;
-@@ -755,7 +755,7 @@ void UserDictionarySession::AddUndoComma
-
- void UserDictionarySession::ClearDictionariesAndUndoHistory() {
- ScopedUserDictionaryLocker l(storage_.get());
-- storage_->clear_dictionaries();
-+ storage_->user_dictionary_storage_base.clear_dictionaries();
- ClearUndoHistory();
- }
-
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session__test.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session__test.cc
deleted file mode 100644
index 5112381b2081..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__session__test.cc
+++ /dev/null
@@ -1,62 +0,0 @@
---- src/dictionary/user_dictionary_session_test.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary_session_test.cc
-@@ -95,12 +95,12 @@ TEST_F(UserDictionarySessionTest, SaveAn
-
- ASSERT_EQ(UserDictionaryCommandStatus::FILE_NOT_FOUND, session.Load());
-
-- session.mutable_storage()->set_version(10);
-+ session.mutable_storage()->user_dictionary_storage_base.set_version(10);
- ASSERT_EQ(UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS,
- session.Save());
-
- // Clear once, in order to make sure that Load is actually working.
-- session.mutable_storage()->Clear();
-+ session.mutable_storage()->user_dictionary_storage_base.Clear();
- ASSERT_EQ(UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS,
- session.Load());
-
-@@ -130,7 +130,7 @@ TEST_F(UserDictionarySessionTest, DISABL
-
- // Create huge dummy data.
- {
-- UserDictionaryStorage *storage = session.mutable_storage();
-+ UserDictionaryStorage *storage = &session.mutable_storage()->user_dictionary_storage_base;
- for (int i = 0; i < 100; ++i) {
- UserDictionary *dictionary = storage->add_dictionaries();
- for (int j = 0; j < 1000; ++j) {
-@@ -147,7 +147,7 @@ TEST_F(UserDictionarySessionTest, DISABL
- ASSERT_EQ(UserDictionaryCommandStatus::FILE_SIZE_LIMIT_EXCEEDED,
- session.Save());
-
-- session.mutable_storage()->Clear();
-+ session.mutable_storage()->user_dictionary_storage_base.Clear();
- ASSERT_EQ(UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS,
- session.Load());
-
-@@ -191,7 +191,7 @@ TEST_F(UserDictionarySessionTest, Create
-
- while (session.storage().dictionaries_size() <
- ::mozc::UserDictionaryStorage::max_dictionary_size()) {
-- session.mutable_storage()->add_dictionaries();
-+ session.mutable_storage()->user_dictionary_storage_base.add_dictionaries();
- }
- EXPECT_EQ(UserDictionaryCommandStatus::DICTIONARY_SIZE_LIMIT_EXCEEDED,
- session.CreateDictionary("dictionary 2", &dummy_dictionary_id));
-@@ -204,7 +204,7 @@ TEST_F(UserDictionarySessionTest, Delete
- const uint64 kDummyId = 10;
- {
- UserDictionary *user_dictionary =
-- session.mutable_storage()->add_dictionaries();
-+ session.mutable_storage()->user_dictionary_storage_base.add_dictionaries();
- user_dictionary->set_id(kDummyId);
- }
-
-@@ -229,7 +229,7 @@ TEST_F(UserDictionarySessionTest,
- const uint64 kDummyId = 10;
- {
- UserDictionary *user_dictionary =
-- session.mutable_storage()->add_dictionaries();
-+ session.mutable_storage()->user_dictionary_storage_base.add_dictionaries();
- user_dictionary->set_id(kDummyId);
- }
-
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.cc
deleted file mode 100644
index 1350964f72cb..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.cc
+++ /dev/null
@@ -1,195 +0,0 @@
---- src/dictionary/user_dictionary_storage.cc.orig 2020-08-14 17:09:18 UTC
-+++ src/dictionary/user_dictionary_storage.cc
-@@ -108,8 +108,8 @@ bool UserDictionaryStorage::LoadInternal() {
- // wants to use more than 512MB.
- mozc::protobuf::io::IstreamInputStream zero_copy_input(&ifs);
- mozc::protobuf::io::CodedInputStream decoder(&zero_copy_input);
-- decoder.SetTotalBytesLimit(kDefaultTotalBytesLimit, -1);
-- if (!ParseFromCodedStream(&decoder)) {
-+ decoder.SetTotalBytesLimit(kDefaultTotalBytesLimit);
-+ if (!user_dictionary_storage_base.ParseFromCodedStream(&decoder)) {
- LOG(ERROR) << "Failed to parse";
- if (!decoder.ConsumedEntireMessage() || !ifs.eof()) {
- LOG(ERROR) << "ParseFromStream failed: file seems broken";
-@@ -137,11 +137,11 @@ bool UserDictionaryStorage::Load() {
- }
-
- // Check dictionary id here. if id is 0, assign random ID.
-- for (int i = 0; i < dictionaries_size(); ++i) {
-- const UserDictionary &dict = dictionaries(i);
-+ for (int i = 0; i < user_dictionary_storage_base.dictionaries_size(); ++i) {
-+ const UserDictionary &dict = user_dictionary_storage_base.dictionaries(i);
- if (dict.id() == 0) {
-- mutable_dictionaries(i)->set_id(
-- UserDictionaryUtil::CreateNewDictionaryId(*this));
-+ user_dictionary_storage_base.mutable_dictionaries(i)->set_id(
-+ UserDictionaryUtil::CreateNewDictionaryId(this->user_dictionary_storage_base));
- }
- }
-
-@@ -171,7 +171,7 @@ bool UserDictionaryStorage::Save() {
- return false;
- }
-
-- if (!SerializeToOstream(&ofs)) {
-+ if (!user_dictionary_storage_base.SerializeToOstream(&ofs)) {
- LOG(ERROR) << "SerializeToString failed";
- last_error_type_ = SYNC_FAILURE;
- return false;
-@@ -227,7 +227,7 @@ bool UserDictionaryStorage::ExportDictionary(
- return false;
- }
-
-- const UserDictionary &dic = dictionaries(index);
-+ const UserDictionary &dic = user_dictionary_storage_base.dictionaries(index);
- for (size_t i = 0; i < dic.entries_size(); ++i) {
- const UserDictionaryEntry &entry = dic.entries(i);
- ofs << entry.key() << "\t" << entry.value() << "\t"
-@@ -241,7 +241,7 @@ bool UserDictionaryStorage::ExportDictionary(
- bool UserDictionaryStorage::CreateDictionary(
- const string &dic_name, uint64 *new_dic_id) {
- UserDictionaryCommandStatus::Status status =
-- UserDictionaryUtil::CreateDictionary(this, dic_name, new_dic_id);
-+ UserDictionaryUtil::CreateDictionary(&this->user_dictionary_storage_base, dic_name, new_dic_id);
- // Update last_error_type_
- switch (status) {
- case UserDictionaryCommandStatus::DICTIONARY_NAME_EMPTY:
-@@ -273,7 +273,7 @@ bool UserDictionaryStorage::CreateDictionary(
- }
-
- bool UserDictionaryStorage::DeleteDictionary(uint64 dic_id) {
-- if (!UserDictionaryUtil::DeleteDictionary(this, dic_id, NULL, NULL)) {
-+ if (!UserDictionaryUtil::DeleteDictionary(&this->user_dictionary_storage_base, dic_id, NULL, NULL)) {
- // Failed to delete dictionary.
- last_error_type_ = INVALID_DICTIONARY_ID;
- return false;
-@@ -304,8 +304,8 @@ bool UserDictionaryStorage::RenameDictionary(uint64 di
- return true;
- }
-
-- for (int i = 0; i < dictionaries_size(); ++i) {
-- if (dic_name == dictionaries(i).name()) {
-+ for (int i = 0; i < user_dictionary_storage_base.dictionaries_size(); ++i) {
-+ if (dic_name == user_dictionary_storage_base.dictionaries(i).name()) {
- last_error_type_ = DUPLICATED_DICTIONARY_NAME;
- LOG(ERROR) << "duplicated dictionary name";
- return false;
-@@ -318,14 +318,14 @@ bool UserDictionaryStorage::RenameDictionary(uint64 di
- }
-
- int UserDictionaryStorage::GetUserDictionaryIndex(uint64 dic_id) const {
-- return UserDictionaryUtil::GetUserDictionaryIndexById(*this, dic_id);
-+ return UserDictionaryUtil::GetUserDictionaryIndexById(this->user_dictionary_storage_base, dic_id);
- }
-
- bool UserDictionaryStorage::GetUserDictionaryId(const string &dic_name,
- uint64 *dic_id) {
-- for (size_t i = 0; i < dictionaries_size(); ++i) {
-- if (dic_name == dictionaries(i).name()) {
-- *dic_id = dictionaries(i).id();
-+ for (size_t i = 0; i < user_dictionary_storage_base.dictionaries_size(); ++i) {
-+ if (dic_name == user_dictionary_storage_base.dictionaries(i).name()) {
-+ *dic_id = user_dictionary_storage_base.dictionaries(i).id();
- return true;
- }
- }
-@@ -335,7 +335,7 @@ bool UserDictionaryStorage::GetUserDictionaryId(const
-
- user_dictionary::UserDictionary *UserDictionaryStorage::GetUserDictionary(
- uint64 dic_id) {
-- return UserDictionaryUtil::GetMutableUserDictionaryById(this, dic_id);
-+ return UserDictionaryUtil::GetMutableUserDictionaryById(&this->user_dictionary_storage_base, dic_id);
- }
-
- UserDictionaryStorage::UserDictionaryStorageErrorType
-@@ -352,8 +352,8 @@ bool UserDictionaryStorage::AddToAutoRegisteredDiction
- }
-
- int auto_index = -1;
-- for (int i = 0; i < dictionaries_size(); ++i) {
-- if (dictionaries(i).name() == kAutoRegisteredDictionaryName) {
-+ for (int i = 0; i < user_dictionary_storage_base.dictionaries_size(); ++i) {
-+ if (user_dictionary_storage_base.dictionaries(i).name() == kAutoRegisteredDictionaryName) {
- auto_index = i;
- break;
- }
-@@ -361,17 +361,17 @@ bool UserDictionaryStorage::AddToAutoRegisteredDiction
-
- UserDictionary *dic = NULL;
- if (auto_index == -1) {
-- if (UserDictionaryUtil::IsStorageFull(*this)) {
-+ if (UserDictionaryUtil::IsStorageFull(this->user_dictionary_storage_base)) {
- last_error_type_ = TOO_MANY_DICTIONARIES;
- LOG(ERROR) << "too many dictionaries";
- UnLock();
- return false;
- }
-- dic = add_dictionaries();
-- dic->set_id(UserDictionaryUtil::CreateNewDictionaryId(*this));
-+ dic = user_dictionary_storage_base.add_dictionaries();
-+ dic->set_id(UserDictionaryUtil::CreateNewDictionaryId(this->user_dictionary_storage_base));
- dic->set_name(kAutoRegisteredDictionaryName);
- } else {
-- dic = mutable_dictionaries(auto_index);
-+ dic = user_dictionary_storage_base.mutable_dictionaries(auto_index);
- }
-
- if (dic == NULL) {
-@@ -410,13 +410,13 @@ bool UserDictionaryStorage::AddToAutoRegisteredDiction
- }
-
- bool UserDictionaryStorage::ConvertSyncDictionariesToNormalDictionaries() {
-- if (CountSyncableDictionaries(*this) == 0) {
-+ if (CountSyncableDictionaries(this->user_dictionary_storage_base) == 0) {
- return false;
- }
-
-- for (int dictionary_index = dictionaries_size() - 1;
-+ for (int dictionary_index = user_dictionary_storage_base.dictionaries_size() - 1;
- dictionary_index >= 0; --dictionary_index) {
-- UserDictionary *dic = mutable_dictionaries(dictionary_index);
-+ UserDictionary *dic = user_dictionary_storage_base.mutable_dictionaries(dictionary_index);
- if (!dic->syncable()) {
- continue;
- }
-@@ -433,10 +433,10 @@ bool UserDictionaryStorage::ConvertSyncDictionariesToN
-
- // Delete removed or unused sync dictionaries.
- if (dic->removed() || dic->entries_size() == 0) {
-- for (int i = dictionary_index + 1; i < dictionaries_size(); ++i) {
-- mutable_dictionaries()->SwapElements(i - 1, i);
-+ for (int i = dictionary_index + 1; i < user_dictionary_storage_base.dictionaries_size(); ++i) {
-+ user_dictionary_storage_base.mutable_dictionaries()->SwapElements(i - 1, i);
- }
-- mutable_dictionaries()->RemoveLast();
-+ user_dictionary_storage_base.mutable_dictionaries()->RemoveLast();
- continue;
- }
-
-@@ -445,7 +445,7 @@ bool UserDictionaryStorage::ConvertSyncDictionariesToN
- kDictionaryNameConvertedFromSyncableDictionary;
- int index = 0;
- while (UserDictionaryUtil::ValidateDictionaryName(
-- *this, new_dictionary_name)
-+ this->user_dictionary_storage_base, new_dictionary_name)
- != UserDictionaryCommandStatus::USER_DICTIONARY_COMMAND_SUCCESS) {
- ++index;
- new_dictionary_name = Util::StringPrintf(
-@@ -456,7 +456,7 @@ bool UserDictionaryStorage::ConvertSyncDictionariesToN
- dic->set_syncable(false);
- }
-
-- DCHECK_EQ(0, CountSyncableDictionaries(*this));
-+ DCHECK_EQ(0, CountSyncableDictionaries(this->user_dictionary_storage_base));
-
- return true;
- }
-@@ -487,7 +487,7 @@ size_t UserDictionaryStorage::max_dictionary_size() {
- bool UserDictionaryStorage::IsValidDictionaryName(const string &name) {
- UserDictionaryCommandStatus::Status status =
- UserDictionaryUtil::ValidateDictionaryName(
-- UserDictionaryStorage::default_instance(), name);
-+ user_dictionary::UserDictionaryStorage::default_instance(), name);
-
- // Update last_error_type_.
- switch (status) {
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.h b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.h
deleted file mode 100644
index 4e66fd82e9d9..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage.h
+++ /dev/null
@@ -1,21 +0,0 @@
---- src/dictionary/user_dictionary_storage.h.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary_storage.h
-@@ -72,13 +72,15 @@ namespace mozc {
- class Mutex;
- class ProcessMutex;
-
--// Inherit from ProtocolBuffer
--// TODO(hidehiko): Get rid of this implementation.
--class UserDictionaryStorage : public user_dictionary::UserDictionaryStorage {
-+class UserDictionaryStorage {
- public:
- typedef user_dictionary::UserDictionary UserDictionary;
- typedef user_dictionary::UserDictionary::Entry UserDictionaryEntry;
-
-+ // Instance of base class generated by Protocol Buffers compiler.
-+ // Regular inheritance strongly discouraged.
-+ user_dictionary::UserDictionaryStorage user_dictionary_storage_base;
-+
- enum UserDictionaryStorageErrorType {
- USER_DICTIONARY_STORAGE_NO_ERROR = 0, // default
- FILE_NOT_EXISTS,
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage__test.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage__test.cc
deleted file mode 100644
index a51fe28908f9..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__storage__test.cc
+++ /dev/null
@@ -1,188 +0,0 @@
---- src/dictionary/user_dictionary_storage_test.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary_storage_test.cc
-@@ -118,13 +118,13 @@ TEST_F(UserDictionaryStorageTest, BasicO
- const size_t kDictionariesSize = 3;
- uint64 id[kDictionariesSize];
-
-- const size_t dict_size = storage.dictionaries_size();
-+ const size_t dict_size = storage.user_dictionary_storage_base.dictionaries_size();
-
- for (size_t i = 0; i < kDictionariesSize; ++i) {
- EXPECT_TRUE(storage.CreateDictionary(
- "test" + std::to_string(static_cast<uint32>(i)),
- &id[i]));
-- EXPECT_EQ(i + 1 + dict_size, storage.dictionaries_size());
-+ EXPECT_EQ(i + 1 + dict_size, storage.user_dictionary_storage_base.dictionaries_size());
- }
-
- for (size_t i = 0; i < kDictionariesSize; ++i) {
-@@ -133,7 +133,7 @@ TEST_F(UserDictionaryStorageTest, BasicO
- }
-
- for (size_t i = 0; i < kDictionariesSize; ++i) {
-- EXPECT_EQ(storage.mutable_dictionaries(i + dict_size),
-+ EXPECT_EQ(storage.user_dictionary_storage_base.mutable_dictionaries(i + dict_size),
- storage.GetUserDictionary(id[i]));
- EXPECT_EQ(NULL, storage.GetUserDictionary(id[i] + 1));
- }
-@@ -165,7 +165,7 @@ TEST_F(UserDictionaryStorageTest, BasicO
- EXPECT_FALSE(storage.DeleteDictionary(0));
-
- EXPECT_TRUE(storage.DeleteDictionary(id[1]));
-- EXPECT_EQ(kDictionariesSize + dict_size - 1, storage.dictionaries_size());
-+ EXPECT_EQ(kDictionariesSize + dict_size - 1, storage.user_dictionary_storage_base.dictionaries_size());
- }
-
- TEST_F(UserDictionaryStorageTest, DeleteTest) {
-@@ -174,7 +174,7 @@ TEST_F(UserDictionaryStorageTest, Delete
-
- // repeat 10 times
- for (int i = 0; i < 10; ++i) {
-- storage.Clear();
-+ storage.user_dictionary_storage_base.Clear();
- std::vector<uint64> ids(100);
- for (size_t i = 0; i < ids.size(); ++i) {
- EXPECT_TRUE(storage.CreateDictionary(
-@@ -191,10 +191,10 @@ TEST_F(UserDictionaryStorageTest, Delete
- alive.push_back(ids[i]);
- }
-
-- EXPECT_EQ(alive.size(), storage.dictionaries_size());
-+ EXPECT_EQ(alive.size(), storage.user_dictionary_storage_base.dictionaries_size());
-
- for (size_t i = 0; i < alive.size(); ++i) {
-- EXPECT_EQ(alive[i], storage.dictionaries(i).id());
-+ EXPECT_EQ(alive[i], storage.user_dictionary_storage_base.dictionaries(i).id());
- }
- }
- }
-@@ -268,7 +268,7 @@ TEST_F(UserDictionaryStorageTest, Serial
- const size_t entry_size = Util::Random(100) + 1;
- for (size_t j = 0; j < entry_size; ++j) {
- UserDictionaryStorage::UserDictionary *dic =
-- storage1.mutable_dictionaries(i);
-+ storage1.user_dictionary_storage_base.mutable_dictionaries(i);
- UserDictionaryStorage::UserDictionaryEntry *entry =
- dic->add_entries();
- entry->set_key(GenRandomString(10));
-@@ -288,7 +288,7 @@ TEST_F(UserDictionaryStorageTest, Serial
- EXPECT_TRUE(storage2.Load());
- }
-
-- EXPECT_EQ(storage1.DebugString(), storage2.DebugString());
-+ EXPECT_EQ(storage1.user_dictionary_storage_base.DebugString(), storage2.user_dictionary_storage_base.DebugString());
- }
- }
-
-@@ -352,7 +352,7 @@ TEST_F(UserDictionaryStorageTest, Conver
- uint64 dict_id = 0;
- ASSERT_TRUE(storage.CreateDictionary(data.dictionary_name, &dict_id));
- UserDictionaryStorage::UserDictionary *dict =
-- storage.mutable_dictionaries(storage.GetUserDictionaryIndex(dict_id));
-+ storage.user_dictionary_storage_base.mutable_dictionaries(storage.GetUserDictionaryIndex(dict_id));
- dict->set_syncable(data.is_sync_dictionary);
- dict->set_removed(data.is_removed_dictionary);
- if (data.has_normal_entry) {
-@@ -369,7 +369,7 @@ TEST_F(UserDictionaryStorageTest, Conver
- entry->set_removed(true);
- }
- }
-- EXPECT_EQ(9, UserDictionaryStorage::CountSyncableDictionaries(storage));
-+ EXPECT_EQ(9, UserDictionaryStorage::CountSyncableDictionaries(storage.user_dictionary_storage_base));
-
- ASSERT_TRUE(storage.ConvertSyncDictionariesToNormalDictionaries());
-
-@@ -385,12 +385,12 @@ TEST_F(UserDictionaryStorageTest, Conver
- { true, kDictionaryNameConvertedFromSyncableDictionary },
- };
-
-- EXPECT_EQ(0, UserDictionaryStorage::CountSyncableDictionaries(storage));
-- ASSERT_EQ(arraysize(expected_data), storage.dictionaries_size());
-+ EXPECT_EQ(0, UserDictionaryStorage::CountSyncableDictionaries(storage.user_dictionary_storage_base));
-+ ASSERT_EQ(arraysize(expected_data), storage.user_dictionary_storage_base.dictionaries_size());
- for (size_t i = 0; i < arraysize(expected_data); ++i) {
- SCOPED_TRACE(Util::StringPrintf("verify %d", static_cast<int>(i)));
- const ExpectedData &expected = expected_data[i];
-- const UserDictionaryStorage::UserDictionary &dict = storage.dictionaries(i);
-+ const UserDictionaryStorage::UserDictionary &dict = storage.user_dictionary_storage_base.dictionaries(i);
-
- EXPECT_EQ(expected.dictionary_name, dict.name());
- EXPECT_FALSE(dict.syncable());
-@@ -404,42 +404,42 @@ TEST_F(UserDictionaryStorageTest, Conver
- }
-
- // Test duplicated dictionary name.
-- storage.Clear();
-+ storage.user_dictionary_storage_base.Clear();
- {
- uint64 dict_id = 0;
- storage.CreateDictionary(
- UserDictionaryStorage::default_sync_dictionary_name(), &dict_id);
- storage.CreateDictionary(
- kDictionaryNameConvertedFromSyncableDictionary, &dict_id);
-- ASSERT_EQ(2, storage.dictionaries_size());
-+ ASSERT_EQ(2, storage.user_dictionary_storage_base.dictionaries_size());
- UserDictionaryStorage::UserDictionary *dict;
-- dict = storage.mutable_dictionaries(0);
-+ dict = storage.user_dictionary_storage_base.mutable_dictionaries(0);
- dict->set_syncable(true);
- dict->add_entries()->set_key("0");
-- dict = storage.mutable_dictionaries(1);
-+ dict = storage.user_dictionary_storage_base.mutable_dictionaries(1);
- dict->set_syncable(false);
- dict->add_entries()->set_key("1");
- }
- ASSERT_TRUE(storage.ConvertSyncDictionariesToNormalDictionaries());
-- EXPECT_EQ(0, UserDictionaryStorage::CountSyncableDictionaries(storage));
-- EXPECT_EQ(2, storage.dictionaries_size());
-+ EXPECT_EQ(0, UserDictionaryStorage::CountSyncableDictionaries(storage.user_dictionary_storage_base));
-+ EXPECT_EQ(2, storage.user_dictionary_storage_base.dictionaries_size());
- EXPECT_EQ(Util::StringPrintf("%s_1",
- kDictionaryNameConvertedFromSyncableDictionary),
-- storage.dictionaries(0).name());
-+ storage.user_dictionary_storage_base.dictionaries(0).name());
- EXPECT_EQ(kDictionaryNameConvertedFromSyncableDictionary,
-- storage.dictionaries(1).name());
-+ storage.user_dictionary_storage_base.dictionaries(1).name());
- }
-
- TEST_F(UserDictionaryStorageTest, AddToAutoRegisteredDictionary) {
- {
- UserDictionaryStorage storage(GetUserDictionaryFile());
-- EXPECT_EQ(0, storage.dictionaries_size());
-+ EXPECT_EQ(0, storage.user_dictionary_storage_base.dictionaries_size());
- EXPECT_TRUE(storage.AddToAutoRegisteredDictionary(
- "key1", "value1", UserDictionary::NOUN));
-- EXPECT_EQ(1, storage.dictionaries_size());
-- EXPECT_EQ(1, storage.dictionaries(0).entries_size());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries_size());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries(0).entries_size());
- const UserDictionaryStorage::UserDictionaryEntry &entry1 =
-- storage.dictionaries(0).entries(0);
-+ storage.user_dictionary_storage_base.dictionaries(0).entries(0);
- EXPECT_EQ("key1", entry1.key());
- EXPECT_EQ("value1", entry1.value());
- EXPECT_EQ(UserDictionary::NOUN, entry1.pos());
-@@ -447,10 +447,10 @@ TEST_F(UserDictionaryStorageTest, AddToA
-
- EXPECT_TRUE(storage.AddToAutoRegisteredDictionary(
- "key2", "value2", UserDictionary::NOUN));
-- EXPECT_EQ(1, storage.dictionaries_size());
-- EXPECT_EQ(2, storage.dictionaries(0).entries_size());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries_size());
-+ EXPECT_EQ(2, storage.user_dictionary_storage_base.dictionaries(0).entries_size());
- const UserDictionaryStorage::UserDictionaryEntry &entry2 =
-- storage.dictionaries(0).entries(1);
-+ storage.user_dictionary_storage_base.dictionaries(0).entries(1);
- EXPECT_EQ("key2", entry2.key());
- EXPECT_EQ("value2", entry2.value());
- EXPECT_EQ(UserDictionary::NOUN, entry2.pos());
-@@ -474,7 +474,7 @@ TEST_F(UserDictionaryStorageTest, Export
- {
- UserDictionaryStorage storage(GetUserDictionaryFile());
- {
-- UserDictionary *dictionary = storage.add_dictionaries();
-+ UserDictionary *dictionary = storage.user_dictionary_storage_base.add_dictionaries();
- dictionary->set_id(kDummyDictionaryId);
- UserDictionary::Entry *entry = dictionary->add_entries();
- entry->set_key("key");
diff --git a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__test.cc b/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__test.cc
deleted file mode 100644
index f83e4380c832..000000000000
--- a/japanese/mozc-server/files/patch-src_dictionary_user__dictionary__test.cc
+++ /dev/null
@@ -1,229 +0,0 @@
---- src/dictionary/user_dictionary_test.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/dictionary/user_dictionary_test.cc
-@@ -334,9 +334,9 @@ class UserDictionaryTest : public ::test
- std::istringstream is(contents);
- CHECK(is.good());
-
-- storage->Clear();
-+ storage->user_dictionary_storage_base.Clear();
- UserDictionaryStorage::UserDictionary *dic
-- = storage->add_dictionaries();
-+ = storage->user_dictionary_storage_base.add_dictionaries();
- CHECK(dic);
-
- string line;
-@@ -389,7 +389,7 @@ TEST_F(UserDictionaryTest, TestLookupPre
- {
- UserDictionaryStorage storage("");
- UserDictionaryTest::LoadFromString(kUserDictionary0, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // A normal lookup operation.
-@@ -425,7 +425,7 @@ TEST_F(UserDictionaryTest, TestLookupPre
- {
- UserDictionaryStorage storage("");
- LoadFromString(kUserDictionary1, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // A normal lookup again.
-@@ -450,7 +450,7 @@ TEST_F(UserDictionaryTest, TestLookupPre
- {
- UserDictionaryStorage storage("");
- LoadFromString(kUserDictionary0, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // A normal lookup operation.
-@@ -480,7 +480,7 @@ TEST_F(UserDictionaryTest, TestLookupPre
- {
- UserDictionaryStorage storage("");
- LoadFromString(kUserDictionary1, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // A normal lookup.
-@@ -504,7 +504,7 @@ TEST_F(UserDictionaryTest, TestLookupExa
- {
- UserDictionaryStorage storage("");
- LoadFromString(kUserDictionary0, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // A normal lookup operation.
-@@ -540,7 +540,7 @@ TEST_F(UserDictionaryTest, TestLookupExa
- uint64 id = 0;
- EXPECT_TRUE(storage.CreateDictionary("test", &id));
- UserDictionaryStorage::UserDictionary *dic =
-- storage.mutable_dictionaries(0);
-+ storage.user_dictionary_storage_base.mutable_dictionaries(0);
-
- // "名詞"
- UserDictionaryStorage::UserDictionaryEntry *entry =
-@@ -555,7 +555,7 @@ TEST_F(UserDictionaryTest, TestLookupExa
- entry->set_value("suggest_only");
- entry->set_pos(user_dictionary::UserDictionary::SUGGESTION_ONLY);
-
-- user_dic->Load(storage);
-+ user_dic->Load(storage.user_dictionary_storage_base);
- }
-
- // "suggestion_only" should not be looked up.
-@@ -577,7 +577,7 @@ TEST_F(UserDictionaryTest, IncognitoMode
- {
- UserDictionaryStorage storage("");
- UserDictionaryTest::LoadFromString(kUserDictionary0, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- TestLookupPrefixHelper(nullptr, 0, "start", 4, *dic);
-@@ -612,7 +612,7 @@ TEST_F(UserDictionaryTest, AsyncLoadTest
- uint64 id = 0;
- EXPECT_TRUE(storage.CreateDictionary("test", &id));
- UserDictionaryStorage::UserDictionary *dic =
-- storage.mutable_dictionaries(0);
-+ storage.user_dictionary_storage_base.mutable_dictionaries(0);
- for (size_t j = 0; j < 10000; ++j) {
- UserDictionaryStorage::UserDictionaryEntry *entry =
- dic->add_entries();
-@@ -681,15 +681,15 @@ TEST_F(UserDictionaryTest, AddToAutoRegi
- UserDictionaryStorage storage(filename);
- EXPECT_TRUE(storage.Load());
- int index = 0;
-- EXPECT_EQ(1, storage.dictionaries_size());
-- EXPECT_EQ(100, storage.dictionaries(index).entries_size());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries_size());
-+ EXPECT_EQ(100, storage.user_dictionary_storage_base.dictionaries(index).entries_size());
- for (int i = 0; i < 100; ++i) {
- EXPECT_EQ("key" + std::to_string(i),
-- storage.dictionaries(index).entries(i).key());
-+ storage.user_dictionary_storage_base.dictionaries(index).entries(i).key());
- EXPECT_EQ("value" + std::to_string(i),
-- storage.dictionaries(index).entries(i).value());
-+ storage.user_dictionary_storage_base.dictionaries(index).entries(i).value());
- EXPECT_EQ(user_dictionary::UserDictionary::NOUN,
-- storage.dictionaries(index).entries(i).pos());
-+ storage.user_dictionary_storage_base.dictionaries(index).entries(i).pos());
- }
- }
-
-@@ -722,12 +722,12 @@ TEST_F(UserDictionaryTest, AddToAutoRegi
- {
- UserDictionaryStorage storage(filename);
- EXPECT_TRUE(storage.Load());
-- EXPECT_EQ(1, storage.dictionaries_size());
-- EXPECT_EQ(1, storage.dictionaries(0).entries_size());
-- EXPECT_EQ("key", storage.dictionaries(0).entries(0).key());
-- EXPECT_EQ("value", storage.dictionaries(0).entries(0).value());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries_size());
-+ EXPECT_EQ(1, storage.user_dictionary_storage_base.dictionaries(0).entries_size());
-+ EXPECT_EQ("key", storage.user_dictionary_storage_base.dictionaries(0).entries(0).key());
-+ EXPECT_EQ("value", storage.user_dictionary_storage_base.dictionaries(0).entries(0).value());
- EXPECT_EQ(user_dictionary::UserDictionary::NOUN,
-- storage.dictionaries(0).entries(0).pos());
-+ storage.user_dictionary_storage_base.dictionaries(0).entries(0).pos());
- }
- }
-
-@@ -746,7 +746,7 @@ TEST_F(UserDictionaryTest, TestSuppressi
- uint64 id = 0;
- EXPECT_TRUE(storage.CreateDictionary("test", &id));
- UserDictionaryStorage::UserDictionary *dic =
-- storage.mutable_dictionaries(0);
-+ storage.user_dictionary_storage_base.mutable_dictionaries(0);
- for (size_t j = 0; j < 10000; ++j) {
- UserDictionaryStorage::UserDictionaryEntry *entry =
- dic->add_entries();
-@@ -770,7 +770,7 @@ TEST_F(UserDictionaryTest, TestSuppressi
-
- suppression_dictionary_->Lock();
- EXPECT_TRUE(suppression_dictionary_->IsLocked());
-- user_dic->Load(storage);
-+ user_dic->Load(storage.user_dictionary_storage_base);
- EXPECT_FALSE(suppression_dictionary_->IsLocked());
-
- for (size_t j = 0; j < 10; ++j) {
-@@ -782,11 +782,11 @@ TEST_F(UserDictionaryTest, TestSuppressi
-
- // Remove suppression entry
- {
-- storage.Clear();
-+ storage.user_dictionary_storage_base.Clear();
- uint64 id = 0;
- EXPECT_TRUE(storage.CreateDictionary("test", &id));
- UserDictionaryStorage::UserDictionary *dic =
-- storage.mutable_dictionaries(0);
-+ storage.user_dictionary_storage_base.mutable_dictionaries(0);
- for (size_t j = 0; j < 10000; ++j) {
- UserDictionaryStorage::UserDictionaryEntry *entry =
- dic->add_entries();
-@@ -798,7 +798,7 @@ TEST_F(UserDictionaryTest, TestSuppressi
- }
-
- suppression_dictionary_->Lock();
-- user_dic->Load(storage);
-+ user_dic->Load(storage.user_dictionary_storage_base);
- EXPECT_FALSE(suppression_dictionary_->IsLocked());
-
- for (size_t j = 0; j < 10; ++j) {
-@@ -825,7 +825,7 @@ TEST_F(UserDictionaryTest, TestSuggestio
- uint64 id = 0;
- EXPECT_TRUE(storage.CreateDictionary("test", &id));
- UserDictionaryStorage::UserDictionary *dic =
-- storage.mutable_dictionaries(0);
-+ storage.user_dictionary_storage_base.mutable_dictionaries(0);
-
- for (size_t j = 0; j < 10; ++j) {
- UserDictionaryStorage::UserDictionaryEntry *entry =
-@@ -845,7 +845,7 @@ TEST_F(UserDictionaryTest, TestSuggestio
- entry->set_pos(user_dictionary::UserDictionary::SUGGESTION_ONLY);
- }
-
-- user_dic->Load(storage);
-+ user_dic->Load(storage.user_dictionary_storage_base);
- }
-
- {
-@@ -878,7 +878,7 @@ TEST_F(UserDictionaryTest, TestUsageStat
- UserDictionaryStorage storage("");
-
- {
-- UserDictionaryStorage::UserDictionary *dic1 = storage.add_dictionaries();
-+ UserDictionaryStorage::UserDictionary *dic1 = storage.user_dictionary_storage_base.add_dictionaries();
- CHECK(dic1);
- UserDictionaryStorage::UserDictionaryEntry *entry;
- entry = dic1->add_entries();
-@@ -893,7 +893,7 @@ TEST_F(UserDictionaryTest, TestUsageStat
- entry->set_pos(user_dictionary::UserDictionary::NOUN);
- }
- {
-- UserDictionaryStorage::UserDictionary *dic2 = storage.add_dictionaries();
-+ UserDictionaryStorage::UserDictionary *dic2 = storage.user_dictionary_storage_base.add_dictionaries();
- CHECK(dic2);
- UserDictionaryStorage::UserDictionaryEntry *entry;
- entry = dic2->add_entries();
-@@ -912,7 +912,7 @@ TEST_F(UserDictionaryTest, TestUsageStat
- entry->set_value("value5");
- entry->set_pos(user_dictionary::UserDictionary::NOUN);
- }
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
-
- EXPECT_INTEGER_STATS("UserRegisteredWord", 5);
- }
-@@ -925,7 +925,7 @@ TEST_F(UserDictionaryTest, LookupComment
- {
- UserDictionaryStorage storage("");
- UserDictionaryTest::LoadFromString(kUserDictionary0, &storage);
-- dic->Load(storage);
-+ dic->Load(storage.user_dictionary_storage_base);
- }
-
- // Entry is in user dictionary but has no comment.
diff --git a/japanese/mozc-server/files/patch-src_gui_word__register__dialog_word__register__dialog.cc b/japanese/mozc-server/files/patch-src_gui_word__register__dialog_word__register__dialog.cc
deleted file mode 100644
index adc89a244b9f..000000000000
--- a/japanese/mozc-server/files/patch-src_gui_word__register__dialog_word__register__dialog.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/word_register_dialog/word_register_dialog.cc.orig 2026-09-15 04:45:41 UTC
-+++ src/gui/word_register_dialog/word_register_dialog.cc
-@@ -298,7 +299,7 @@ WordRegisterDialog::ErrorCode WordRegisterDialog::Save
- }
-
- UserDictionary *dic =
-- session_->mutable_storage()->mutable_dictionaries(index);
-+ session_->mutable_storage()->user_dictionary_storage_base.mutable_dictionaries(index);
- CHECK(dic);
-
- if (dic->name() != DictionarycomboBox->currentText().toStdString()) {
diff --git a/japanese/mozc-server/files/patch-src_prediction_gen__zero__query__data.py b/japanese/mozc-server/files/patch-src_prediction_gen__zero__query__data.py
deleted file mode 100644
index b2d7778710a1..000000000000
--- a/japanese/mozc-server/files/patch-src_prediction_gen__zero__query__data.py
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/prediction/gen_zero_query_data.py.orig 2020-08-14 17:09:18 UTC
-+++ src/prediction/gen_zero_query_data.py
-@@ -72,7 +72,7 @@ def RemoveTrailingNumber(string):
- def RemoveTrailingNumber(string):
- if not string:
- return b''
-- return re.sub(br'^([^0-9]+)[0-9]+$', r'\1', string)
-+ return re.sub(br'^([^0-9]+)[0-9]+$', br'\1', string)
-
-
- def GetReadingsFromDescription(description):
diff --git a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.cc b/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.cc
deleted file mode 100644
index 780f53e55b04..000000000000
--- a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.cc
+++ /dev/null
@@ -1,63 +0,0 @@
---- src/prediction/user_history_predictor.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/prediction/user_history_predictor.cc
-@@ -291,23 +291,23 @@ bool UserHistoryStorage::Load() {
- return false;
- }
-
-- if (!ParseFromString(input)) {
-+ if (!user_history_base.ParseFromString(input)) {
- LOG(ERROR) << "ParseFromString failed. message looks broken";
- return false;
- }
-
-- VLOG(1) << "Loaded user histroy, size=" << entries_size();
-+ VLOG(1) << "Loaded user histroy, size=" << user_history_base.entries_size();
- return true;
- }
-
- bool UserHistoryStorage::Save() const {
-- if (entries_size() == 0) {
-+ if (user_history_base.entries_size() == 0) {
- LOG(WARNING) << "etries size is 0. Not saved";
- return false;
- }
-
- string output;
-- if (!AppendToString(&output)) {
-+ if (!user_history_base.AppendToString(&output)) {
- LOG(ERROR) << "AppendToString failed";
- return false;
- }
-@@ -494,12 +494,12 @@ bool UserHistoryPredictor::Load() {
- return false;
- }
-
-- for (size_t i = 0; i < history.entries_size(); ++i) {
-- dic_->Insert(EntryFingerprint(history.entries(i)),
-- history.entries(i));
-+ for (size_t i = 0; i < history.user_history_base.entries_size(); ++i) {
-+ dic_->Insert(EntryFingerprint(history.user_history_base.entries(i)),
-+ history.user_history_base.entries(i));
- }
-
-- VLOG(1) << "Loaded user histroy, size=" << history.entries_size();
-+ VLOG(1) << "Loaded user histroy, size=" << history.user_history_base.entries_size();
-
- return true;
- }
-@@ -521,13 +521,13 @@ bool UserHistoryPredictor::Save() {
-
- UserHistoryStorage history(filename);
- for (const DicElement *elm = tail; elm != nullptr; elm = elm->prev) {
-- history.add_entries()->CopyFrom(elm->value);
-+ history.user_history_base.add_entries()->CopyFrom(elm->value);
- }
-
- // Updates usage stats here.
- UsageStats::SetInteger(
- "UserHistoryPredictorEntrySize",
-- static_cast<int>(history.entries_size()));
-+ static_cast<int>(history.user_history_base.entries_size()));
-
- if (!history.Save()) {
- LOG(ERROR) << "UserHistoryStorage::Save() failed";
diff --git a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.h b/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.h
deleted file mode 100644
index c060862eafd3..000000000000
--- a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor.h
+++ /dev/null
@@ -1,19 +0,0 @@
---- src/prediction/user_history_predictor.h.orig 2019-03-04 18:35:55 UTC
-+++ src/prediction/user_history_predictor.h
-@@ -61,11 +61,15 @@ class Segments;
- class UserHistoryPredictorSyncer;
-
- // Added serialization method for UserHistory.
--class UserHistoryStorage : public mozc::user_history_predictor::UserHistory {
-+class UserHistoryStorage {
- public:
- explicit UserHistoryStorage(const string &filename);
- ~UserHistoryStorage();
-
-+ // Instance of base class generated by Protocol Buffers compiler.
-+ // Regular inheritance strongly discouraged.
-+ mozc::user_history_predictor::UserHistory user_history_base;
-+
- // Loads from encrypted file.
- bool Load();
-
diff --git a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor__test.cc b/japanese/mozc-server/files/patch-src_prediction_user__history__predictor__test.cc
deleted file mode 100644
index be7ccea9c5b9..000000000000
--- a/japanese/mozc-server/files/patch-src_prediction_user__history__predictor__test.cc
+++ /dev/null
@@ -1,20 +0,0 @@
---- src/prediction/user_history_predictor_test.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/prediction/user_history_predictor_test.cc
-@@ -2222,7 +2222,7 @@ TEST_F(UserHistoryPredictorTest, UserHis
-
- UserHistoryStorage storage1(filename);
-
-- UserHistoryPredictor::Entry *entry = storage1.add_entries();
-+ UserHistoryPredictor::Entry *entry = storage1.user_history_base.add_entries();
- CHECK(entry);
- entry->set_key("key");
- entry->set_key("value");
-@@ -2230,7 +2230,7 @@ TEST_F(UserHistoryPredictorTest, UserHis
- UserHistoryStorage storage2(filename);
- storage2.Load();
-
-- EXPECT_EQ(storage1.DebugString(), storage2.DebugString());
-+ EXPECT_EQ(storage1.user_history_base.DebugString(), storage2.user_history_base.DebugString());
- FileUtil::Unlink(filename);
- }
-
diff --git a/japanese/mozc-server/files/patch-src_rewriter_usage__rewriter__test.cc b/japanese/mozc-server/files/patch-src_rewriter_usage__rewriter__test.cc
deleted file mode 100644
index 8e6e6030b28f..000000000000
--- a/japanese/mozc-server/files/patch-src_rewriter_usage__rewriter__test.cc
+++ /dev/null
@@ -1,20 +0,0 @@
---- src/rewriter/usage_rewriter_test.cc.orig 2019-03-04 18:35:55 UTC
-+++ src/rewriter/usage_rewriter_test.cc
-@@ -312,7 +312,7 @@ TEST_F(UsageRewriterTest, CommentFromUse
- // Load mock data
- {
- UserDictionaryStorage storage("");
-- UserDictionaryStorage::UserDictionary *dic = storage.add_dictionaries();
-+ UserDictionaryStorage::UserDictionary *dic = storage.user_dictionary_storage_base.add_dictionaries();
-
- UserDictionaryStorage::UserDictionaryEntry *entry = dic->add_entries();
- entry->set_key("うま");
-@@ -320,7 +320,7 @@ TEST_F(UsageRewriterTest, CommentFromUse
- entry->set_pos(user_dictionary::UserDictionary::NOUN);
- entry->set_comment("アルパカコメント");
-
-- user_dictionary_->Load(storage);
-+ user_dictionary_->Load(storage.user_dictionary_storage_base);
- }
-
- // Emulates the conversion of key="うま".
diff --git a/japanese/mozc-server/files/patch-src_unix_fcitx_eim.cc b/japanese/mozc-server/files/patch-src_unix_fcitx_eim.cc
deleted file mode 100644
index 4c4b39a686d3..000000000000
--- a/japanese/mozc-server/files/patch-src_unix_fcitx_eim.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-Obtained from: https://github.com/fcitx/mozc/commit/131f6bf4ea9d1f49200f7ccd149fd30eae89ee97
-
---- src/unix/fcitx/eim.cc.orig 2020-08-14 17:09:18 UTC
-+++ src/unix/fcitx/eim.cc
-@@ -33,6 +33,10 @@
- #include <fcitx/module.h>
- #include <fcitx/keys.h>
- #include <fcitx-config/xdg.h>
-+
-+// Resolve macro naming conflict with absl.
-+#undef InvokeFunction
-+
- #include "fcitx_mozc.h"
- #include "mozc_connection.h"
- #include "mozc_response_parser.h"
diff --git a/japanese/fcitx-mozc/files/pkg-message.in b/japanese/mozc-server/files/pkg-message-fcitx.in
index ff54c7a8a50d..ff54c7a8a50d 100644
--- a/japanese/fcitx-mozc/files/pkg-message.in
+++ b/japanese/mozc-server/files/pkg-message-fcitx.in
diff --git a/japanese/mozc-server/files/pkg-message-ibus.in b/japanese/mozc-server/files/pkg-message-ibus.in
new file mode 100644
index 000000000000..50f9c133696b
--- /dev/null
+++ b/japanese/mozc-server/files/pkg-message-ibus.in
@@ -0,0 +1,27 @@
+[
+{ type: install
+ message: <<EOM
+To enable Mozc, open ibus-setup and add Japanese > Mozc
+to the Input Method list.
+
+For an X11 session that does not configure IBus automatically,
+set the following environment variables before starting applications:
+
+export GTK_IM_MODULE=ibus
+export QT_IM_MODULE=ibus
+export XMODIFIERS=@im=ibus
+
+For example, place these settings in ~/.xinitrc before the command
+that starts your desktop or window manager.
+
+If your desktop does not start IBus automatically, also run:
+
+%%LOCALBASE%%/bin/ibus-daemon --daemonize --xim
+
+Do not start a second IBus daemon if your desktop already manages it.
+For Wayland sessions, use your desktop's input method configuration.
+
+The Mozc server starts automatically when needed.
+EOM
+}
+]
diff --git a/japanese/mozc-server/files/pkg-message-uim.in b/japanese/mozc-server/files/pkg-message-uim.in
new file mode 100644
index 000000000000..f3a4ac66c326
--- /dev/null
+++ b/japanese/mozc-server/files/pkg-message-uim.in
@@ -0,0 +1,33 @@
+[
+{ type: install
+ message: <<EOM
+Select Mozc as your input method in the uim preferences.
+
+For an X11 session, set the following environment variables before
+starting applications:
+
+export GTK_IM_MODULE=uim
+export QT_IM_MODULE=uim
+export XMODIFIERS=@im=uim
+
+For example, place these settings in ~/.xinitrc before the command
+that starts your desktop or window manager.
+
+Install the uim input module matching your applications:
+ GTK3: textproc/uim-gtk3
+ GTK4: textproc/uim-gtk4
+ Qt5: textproc/uim-qt5
+ Qt6: textproc/uim-qt6
+
+For XIM applications, start uim-xim if your session does not
+already start it:
+
+%%LOCALBASE%%/bin/uim-xim &
+
+uim-xim requires uim built with X11 support.
+For Wayland sessions, use the setup appropriate to your compositor.
+
+The Mozc server starts automatically when needed.
+EOM
+}
+]
diff --git a/japanese/mozc-server/files/qt6/patch-src_build__mozc.py b/japanese/mozc-server/files/qt6/patch-src_build__mozc.py
deleted file mode 100644
index 13054d9a7105..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_build__mozc.py
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/build_mozc.py.orig 2026-09-15 02:12:59 UTC
-+++ src/build_mozc.py
-@@ -620,7 +620,7 @@ def GypMain(options, unused_args):
- gyp_options.extend(['-D', 'qt_dir='])
-
- # Check if Qt libraries are installed.
-- if not PkgExists('Qt5Core', 'Qt5Gui', 'Qt5Widgets'):
-+ if not PkgExists('Qt6Core'):
- PrintErrorAndExit('Qt is required to build GUI Tool. '
- 'Specify --noqt to skip building GUI Tool.')
-
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette.cc b/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette.cc
deleted file mode 100644
index 3728f106d808..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette.cc
+++ /dev/null
@@ -1,40 +0,0 @@
---- src/gui/character_pad/character_palette.cc.orig 2026-09-15 04:12:45 UTC
-+++ src/gui/character_pad/character_palette.cc
-@@ -177,9 +177,7 @@ CharacterPalette::CharacterPalette(QWidget *parent)
- showLocalTable(kCP932Map, kCP932MapSize);
- categoryTreeWidget->setCurrentItem(sjis_item);
-
-- categoryTreeWidget->setItemExpanded(
-- categoryTreeWidget->topLevelItem(0)->parent(),
-- true);
-+ categoryTreeWidget->topLevelItem(0)->parent()->setExpanded(true);
-
- // Select "Shift-JIS" item as a default.
- categoryTreeWidget->setCurrentItem(sjis_item);
-@@ -245,7 +243,7 @@ void CharacterPalette::updateTableSize() {
- // here we use "龍" to calc font size, as it looks almsot square
- const char kHexBaseChar[]= "龍";
- const QRect rect =
-- QFontMetrics(tableWidget->font()).boundingRect(trUtf8(kHexBaseChar));
-+ QFontMetrics(tableWidget->font()).boundingRect(tr(kHexBaseChar));
-
- #ifdef OS_MACOSX
- const int width = static_cast<int>(rect.width() * 2.2);
-@@ -319,7 +317,7 @@ void CharacterPalette::showUnicodeTableByRange(const U
- QStringList row_header;
- for (char32 ucs4 = range.first; ucs4 <= range.last; ucs4 += kHexBase) {
- QString str;
-- str.sprintf("U+%3.3X0", ucs4 / kHexBase);
-+ str.asprintf("U+%3.3X0", ucs4 / kHexBase);
- row_header << str;
- }
-
-@@ -401,7 +399,7 @@ void CharacterPalette::showLocalTable(const LocalChara
- QStringList row_header;
- for (int i = from_start; i < from_end; i += kHexBase) {
- QString str;
-- str.sprintf("0x%X0", i / kHexBase);
-+ str.asprintf("0x%X0", i / kHexBase);
- row_header << str;
- }
-
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette__table__widget.cc b/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette__table__widget.cc
deleted file mode 100644
index 49cf556b393e..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_character__palette__table__widget.cc
+++ /dev/null
@@ -1,10 +0,0 @@
---- src/gui/character_pad/character_palette_table_widget.cc.orig 2026-09-15 03:55:32 UTC
-+++ src/gui/character_pad/character_palette_table_widget.cc
-@@ -30,7 +30,6 @@
- #include "gui/character_pad/character_palette_table_widget.h"
-
- #include <QtGui/QtGui>
--#include <QtCore/QTextCodec>
- #include <QtWidgets/QToolTip>
-
- #include "gui/character_pad/selection_handler.h"
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_unicode__util.cc b/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_unicode__util.cc
deleted file mode 100644
index 63e84e967aeb..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_character__pad_unicode__util.cc
+++ /dev/null
@@ -1,41 +0,0 @@
---- src/gui/character_pad/unicode_util.cc.orig 2026-09-15 04:03:16 UTC
-+++ src/gui/character_pad/unicode_util.cc
-@@ -148,7 +148,7 @@ QString toCodeInUcs4(const QString &str) {
- return "";
- }
- QString result;
-- result.sprintf("U+%04X", ucs4);
-+ result.asprintf("U+%04X", ucs4);
- return result;
- }
-
-@@ -160,7 +160,7 @@ QString toHexUTF8(const QString &str) {
- QString result;
- for (int i = 0; i < array.size(); ++i) {
- QString tmp;
-- tmp.sprintf("%02X ", static_cast<uint8>(array[i]));
-+ tmp.asprintf("%02X ", static_cast<uint8>(array[i]));
- result += tmp;
- }
- return result;
-@@ -174,9 +174,9 @@ QString Hexify(uint16 code) {
- const uint16 high = (code >> 8) & 0xFF;
- const uint16 low = code & 0xFF;
- if (high == 0) {
-- tmp.sprintf("%02X", low);
-+ tmp.asprintf("%02X", low);
- } else {
-- tmp.sprintf("%02X %02X", high, low);
-+ tmp.asprintf("%02X %02X", high, low);
- }
- return tmp;
- }
-@@ -245,7 +245,7 @@ QString UnicodeUtil::GetToolTip(const QFont &font, con
- // }
- // if (unihan->total_strokes > 0) {
- // QString tmp;
-- // tmp.sprintf("%d", unihan->total_strokes);
-+ // tmp.asprintf("%d", unihan->total_strokes);
- // info += "<tr><td>" + QObject::tr("Total Strokes") + ":</td><td>";
- // info += toHtmlEscaped(tmp);
- // info += "</td></tr>";
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_character__form__editor.cc b/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_character__form__editor.cc
deleted file mode 100644
index b954ebd2f332..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_character__form__editor.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/config_dialog/character_form_editor.cc.orig 2026-09-15 03:57:29 UTC
-+++ src/gui/config_dialog/character_form_editor.cc
-@@ -153,7 +153,7 @@ void CharacterFormEditor::Load(const config::Config &c
- // Preedit Katakan is always FULLWIDTH
- // This item should not be editable
- if (group == QObject::tr("Katakana")) {
-- item_preedit->setFlags(0); // disable flag
-+ item_preedit->setFlags(Qt::ItemFlags(0)); // disable flag
- }
-
- setItem(row, 0, item_group);
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_config__dialog__libmain.cc b/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_config__dialog__libmain.cc
deleted file mode 100644
index 31c33c0ccc11..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_config__dialog__libmain.cc
+++ /dev/null
@@ -1,10 +0,0 @@
---- src/gui/config_dialog/config_dialog_libmain.cc.orig 2026-09-15 03:56:50 UTC
-+++ src/gui/config_dialog/config_dialog_libmain.cc
-@@ -30,7 +30,6 @@
- // The main function of configure dialog for Mozc.
-
- #include <QtCore/QStringList>
--#include <QtCore/QTextCodec>
- #include <QtGui/QtGui>
- #include <QtWidgets/QApplication>
- #include <QtWidgets/QDialog>
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_generic__table__editor.cc b/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_generic__table__editor.cc
deleted file mode 100644
index 35a956b84c70..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_generic__table__editor.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/config_dialog/generic_table_editor.cc.orig 2026-09-15 04:00:28 UTC
-+++ src/gui/config_dialog/generic_table_editor.cc
-@@ -56,7 +56,7 @@ int GetTableHeight(QTableWidget *widget) {
- // Here we use "龍" to calc font size, as it looks almsot square
- const char kHexBaseChar[] = "龍";
- const QRect rect =
-- QFontMetrics(widget->font()).boundingRect(QObject::trUtf8(kHexBaseChar));
-+ QFontMetrics(widget->font()).boundingRect(QObject::tr(kHexBaseChar));
- #ifdef OS_WIN
- return static_cast<int>(rect.height() * 1.3);
- #else
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_keybinding__editor.cc b/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_keybinding__editor.cc
deleted file mode 100644
index 59b5c0137b68..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_config__dialog_keybinding__editor.cc
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/config_dialog/keybinding_editor.cc.orig 2026-09-15 03:56:19 UTC
-+++ src/gui/config_dialog/keybinding_editor.cc
-@@ -453,7 +453,7 @@ KeyBindingFilter::KeyState KeyBindingFilter::AddKey(
- return Encode(result);
- }
-
-- unknown_key_.sprintf("<UNK:0x%x 0x%x 0x%x>",
-+ unknown_key_.asprintf("<UNK:0x%x 0x%x 0x%x>",
- key_event.key(),
- key_event.nativeScanCode(),
- key_event.nativeVirtualKey());
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool.cc b/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool.cc
deleted file mode 100644
index 8c18beac0047..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool.cc
+++ /dev/null
@@ -1,44 +0,0 @@
---- src/gui/dictionary_tool/dictionary_tool.cc.orig 2026-09-15 04:25:06 UTC
-+++ src/gui/dictionary_tool/dictionary_tool.cc
-@@ -34,13 +34,13 @@
- #endif // OS_ANDROID || OS_NACL
-
- #include <QtCore/QTimer>
-+#include <QtGui/QShortcut>
- #include <QtGui/QtGui>
- #include <QtWidgets/QProgressDialog>
- #include <QtWidgets/QMessageBox>
- #include <QtWidgets/QFileDialog>
- #include <QtWidgets/QMenu>
- #include <QtWidgets/QInputDialog>
--#include <QtWidgets/QShortcut>
-
- #ifdef OS_WIN
- #include <Windows.h>
-@@ -88,7 +88,7 @@ int GetTableHeight(QTableWidget *widget) {
- // Here we use "龍" to calc font size, as it looks almsot square
- const char kHexBaseChar[] = "龍";
- const QRect rect =
-- QFontMetrics(widget->font()).boundingRect(QObject::trUtf8(kHexBaseChar));
-+ QFontMetrics(widget->font()).boundingRect(QObject::tr(kHexBaseChar));
- return static_cast<int>(rect.height() * 1.4);
- }
-
-@@ -129,7 +129,7 @@ class UTF16TextLineIterator
- LOG(ERROR) << "Cannot open: " << filename;
- }
- stream_->setDevice(&file_);
-- stream_->setCodec("UTF-16");
-+ stream_->setEncoding(QStringConverter::Utf16);
- progress_.reset(CreateProgressDialog(message, parent, file_.size()));
- }
-
-@@ -168,7 +168,7 @@ class UTF16TextLineIterator
- file_.seek(0);
- stream_.reset(new QTextStream);
- stream_->setDevice(&file_);
-- stream_->setCodec("UTF-16");
-+ stream_->setEncoding(QStringConverter::Utf16);
- }
-
- private:
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool__libmain.cc b/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool__libmain.cc
deleted file mode 100644
index a336342dd4dd..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_dictionary__tool_dictionary__tool__libmain.cc
+++ /dev/null
@@ -1,10 +0,0 @@
---- src/gui/dictionary_tool/dictionary_tool_libmain.cc.orig 2026-09-15 04:19:52 UTC
-+++ src/gui/dictionary_tool/dictionary_tool_libmain.cc
-@@ -27,7 +27,6 @@
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
--#include <QtCore/QTextCodec>
- #include <QtCore/QTranslator>
- #include <QtGui/QGuiApplication>
-
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_qt__libraries.gypi b/japanese/mozc-server/files/qt6/patch-src_gui_qt__libraries.gypi
deleted file mode 100644
index feaaf8e283ce..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_qt__libraries.gypi
+++ /dev/null
@@ -1,13 +0,0 @@
---- src/gui/qt_libraries.gypi.orig 2026-09-15 05:11:10 UTC
-+++ src/gui/qt_libraries.gypi
-@@ -99,8 +99,8 @@
- ]
- }],
- ['target_platform=="Linux"', {
-- 'cflags': ['<!@(pkg-config --cflags Qt5Widgets Qt5Gui Qt5Core)'],
-- 'libraries': ['<!@(pkg-config --libs Qt5Widgets Qt5Gui Qt5Core)'],
-+ 'cflags': ['<!@(pkg-config --cflags Qt6Widgets Qt6Gui Qt6Core)'],
-+ 'libraries': ['<!@(pkg-config --libs Qt6Widgets Qt6Gui Qt6Core)'],
- }],
- # Workarounds related with clang.
- ['(_toolset=="target" and compiler_target=="clang") or '
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_qt__moc.gypi b/japanese/mozc-server/files/qt6/patch-src_gui_qt__moc.gypi
deleted file mode 100644
index 2042db90fae7..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_qt__moc.gypi
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/qt_moc.gypi.orig 2026-09-15 02:15:11 UTC
-+++ src/gui/qt_moc.gypi
-@@ -34,7 +34,7 @@
- 'variables': {
- 'conditions': [
- ['target_platform=="Linux"', {
-- 'moc_path': '<!(pkg-config --variable=host_bins Qt5Core)/moc',
-+ 'moc_path': '<!(pkg-config --variable=libexecdir Qt6Core)/moc',
- }, 'qt_dir', {
- 'moc_path': '<(qt_dir)/bin/moc<(EXECUTABLE_SUFFIX)',
- }, {
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_qt__rcc.gypi b/japanese/mozc-server/files/qt6/patch-src_gui_qt__rcc.gypi
deleted file mode 100644
index ec93388151e7..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_qt__rcc.gypi
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/qt_rcc.gypi.orig 2026-09-15 02:16:00 UTC
-+++ src/gui/qt_rcc.gypi
-@@ -34,7 +34,7 @@
- 'variables': {
- 'conditions': [
- ['target_platform=="Linux"', {
-- 'rcc_path': '<!(pkg-config --variable=host_bins Qt5Core)/rcc',
-+ 'rcc_path': '<!(pkg-config --variable=libexecdir Qt6Core)/rcc',
- }, 'qt_dir', {
- 'rcc_path': '<(qt_dir)/bin/rcc<(EXECUTABLE_SUFFIX)',
- }, {
diff --git a/japanese/mozc-server/files/qt6/patch-src_gui_qt__uic.gypi b/japanese/mozc-server/files/qt6/patch-src_gui_qt__uic.gypi
deleted file mode 100644
index 014387e729bb..000000000000
--- a/japanese/mozc-server/files/qt6/patch-src_gui_qt__uic.gypi
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/gui/qt_uic.gypi.orig 2026-09-15 02:22:01 UTC
-+++ src/gui/qt_uic.gypi
-@@ -34,7 +34,7 @@
- 'variables': {
- 'conditions': [
- ['target_platform=="Linux"', {
-- 'uic_path': '<!(pkg-config --variable=host_bins Qt5Core)/uic',
-+ 'uic_path': '<!(pkg-config --variable=libexecdir Qt6Core)/uic',
- }, 'qt_dir', {
- 'uic_path': '<(qt_dir)/bin/uic<(EXECUTABLE_SUFFIX)',
- }, {
diff --git a/japanese/mozc-server/files/test-bazel-fetch.py b/japanese/mozc-server/files/test-bazel-fetch.py
new file mode 100644
index 000000000000..2d71818b037f
--- /dev/null
+++ b/japanese/mozc-server/files/test-bazel-fetch.py
@@ -0,0 +1,158 @@
+#!/usr/bin/env python3
+"""Regression checks for merging independent fetch logs and publication failures."""
+import argparse
+import importlib.util
+import json
+from pathlib import Path
+import tempfile
+import unittest
+import sys
+from unittest.mock import patch
+
+sys.dont_write_bytecode = True
+
+HERE = Path(__file__).resolve().parent
+
+
+def load(name, filename):
+ spec = importlib.util.spec_from_file_location(name, HERE / filename)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+ return module
+
+
+logs = load("logs", "bazel-fetch-log.py")
+matrix = load("matrix", "bazel-fetch-matrix.py")
+
+
+def varint(value):
+ result = bytearray()
+ while value >= 128:
+ result.append((value & 127) | 128)
+ value >>= 7
+ return bytes(result + bytes([value]))
+
+
+def field(number, value):
+ value = value.encode() if isinstance(value, str) else value
+ return varint(number * 8 + 2) + varint(len(value)) + value
+
+
+def event(url, sha256):
+ request = field(1, url) + field(3, sha256)
+ message = field(5, request)
+ return varint(len(message)) + message
+
+
+class MergeTests(unittest.TestCase):
+ def test_union_deduplicates_and_sorts(self):
+ first = event("https://example.org/a.tar.gz", "a" * 64)
+ second = event("https://example.org/b.tar.gz", "b" * 64)
+ output, _, count = logs.definitions([first, second, first])
+ self.assertEqual(count, 2)
+ self.assertEqual(output, logs.definitions([second, first])[0])
+
+ def test_collision_across_versions(self):
+ first = event("https://one.example/archive.tar.gz", "a" * 64)
+ second = event("https://two.example/archive.tar.gz", "b" * 64)
+ output, _, count = logs.definitions([first, second])
+ self.assertEqual(count, 2)
+ for digest in ("a" * 64, "b" * 64):
+ self.assertIn("bazel/sha256/" + digest + "/archive.tar.gz", output)
+
+ def test_distinct_bcr_roots_are_relocatable(self):
+ streams = [event(f"file:///tmp/{v}/bazel-central-registry-abc/modules/x/1/MODULE.bazel",
+ "a" * 64) for v in ("9.2.0", "9.3.0")]
+ output, _, _ = logs.definitions(streams)
+ self.assertEqual(output.count('${WRKSRC_bcr}/modules/x/1"'), 1)
+ self.assertNotIn("/tmp/", output)
+
+ def test_truncated_second_log_fails(self):
+ good = event("https://example.org/a.tar.gz", "a" * 64)
+ with self.assertRaises(ValueError):
+ logs.definitions([good, good[:-1]])
+
+
+class PublishTests(unittest.TestCase):
+ def test_successful_matrix_and_missing_version(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ root = Path(tmp)
+ (root / "Makefile").touch()
+ (root / "files").mkdir()
+ entries = [{"version": v, "commit": "abc"}
+ for v in ("9.0.1", "9.1.0", "9.1.1", "9.2.0", "9.3.0")]
+ versions = root / "versions.json"
+ versions.write_text(json.dumps(entries))
+ args = argparse.Namespace(versions=versions, bin_dir=root / "bin",
+ work_root=root / "work", port=root,
+ make="make", make_arg=[], output=root / "generated")
+
+ def fake_version(command, **kwargs):
+ return "bazel " + Path(command[0]).parent.name + "\n"
+
+ def fake_fetch(command, **kwargs):
+ work = Path(next(arg[7:] for arg in command if arg.startswith("WRKDIR=")))
+ work.mkdir(parents=True, exist_ok=True)
+ logfile = next((Path(arg.split("=", 1)[1]) for arg in command
+ if arg.startswith("BAZEL_FETCH_LOG=")), work / "bazel-fetch.log")
+ logfile.write_bytes(
+ event("https://example.org/a.tar.gz", "a" * 64))
+
+ with patch.object(matrix.subprocess, "check_output", side_effect=fake_version), \
+ patch.object(matrix.subprocess, "run", side_effect=fake_fetch):
+ matrix.collect(args)
+ matrix.generate(args)
+ self.assertIn("9.0.1, 9.1.0, 9.1.1, 9.2.0, 9.3.0", args.output.read_text())
+ self.assertEqual(args.output.read_text().count("DISTFILES+="), 1)
+ manifest_path = args.work_root / "manifest.json"
+ original_manifest = manifest_path.read_bytes()
+ with patch.object(matrix.subprocess, "check_output", side_effect=fake_version), \
+ patch.object(matrix.subprocess, "run", side_effect=fake_fetch) as run:
+ matrix.collect(args, offline=True)
+ self.assertEqual(run.call_count, 5)
+ for call in run.call_args_list:
+ command = call.args[0]
+ self.assertIn("BAZEL_FETCH_FLAGS=--repository_disable_download", command)
+ self.assertTrue(any(arg.startswith("BAZEL_FETCH_OUTPUT=") for arg in command))
+ self.assertTrue(any(arg.startswith("BAZEL_FETCH_CACHE=") for arg in command))
+ self.assertEqual(manifest_path.read_bytes(), original_manifest)
+ manifest = json.loads(manifest_path.read_text())
+ manifest["versions"].pop()
+ manifest_path.write_text(json.dumps(manifest))
+ old = args.output.read_bytes()
+ with self.assertRaises(ValueError):
+ matrix.generate(args)
+ self.assertEqual(args.output.read_bytes(), old)
+
+ def test_incomplete_or_modified_collection_preserves_output(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ root = Path(tmp)
+ versions = root / "versions.json"
+ entries = [{"version": "9.2.0", "commit": "abc"}]
+ versions.write_text(json.dumps(entries))
+ output = root / "Makefile.distfiles"
+ output.write_text("original\n")
+ logfile = root / "fetch.log"
+ logfile.write_bytes(event("https://example.org/a.tar.gz", "a" * 64))
+ manifest = {"schema": 1, "versions": [dict(entries[0], log=str(logfile),
+ sha256=matrix.digest(logfile))]}
+ (root / "manifest.json").write_text(json.dumps(manifest))
+ args = argparse.Namespace(work_root=root, versions=versions, output=output)
+ (root / "pending").touch()
+ with self.assertRaises(ValueError):
+ matrix.generate(args)
+ self.assertEqual(output.read_text(), "original\n")
+ (root / "pending").unlink()
+ args.port = root
+ (root / "Makefile").touch()
+ (root / "files").mkdir()
+ manifest["inputs"] = matrix.inputs(root)
+ (root / "manifest.json").write_text(json.dumps(manifest))
+ logfile.write_bytes(logfile.read_bytes() + b"\x80")
+ with self.assertRaises(ValueError):
+ matrix.generate(args)
+ self.assertEqual(output.read_text(), "original\n")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/japanese/uim-mozc/Makefile b/japanese/uim-mozc/Makefile
index 84854a869e22..c9e3c76fb3f6 100644
--- a/japanese/uim-mozc/Makefile
+++ b/japanese/uim-mozc/Makefile
@@ -1,12 +1,11 @@
-PORTREVISION= 13
PKGNAMEPREFIX= ja-uim-
COMMENT= Mozc engine for uim
MASTERDIR= ${.CURDIR}/../../japanese/mozc-server
-FILESDIR= ${.CURDIR}/files
DATADIR= ${PREFIX}/share/uim
-SUB_FILES= pkg-message
+SUB_FILES= pkg-message-uim
+PKGMESSAGE= ${WRKDIR}/pkg-message-uim
BUILD_MOZC_LIST=uim_mozc
diff --git a/japanese/uim-mozc/files/pkg-message.in b/japanese/uim-mozc/files/pkg-message.in
deleted file mode 100644
index 42bbe916e7d2..000000000000
--- a/japanese/uim-mozc/files/pkg-message.in
+++ /dev/null
@@ -1,15 +0,0 @@
-[
-{ type: install
- message: <<EOM
-To activate uim-mozc, please add the following into ~/.xinitrc,
-~/.xsession, or ~/.kde4/env (for KDE4):
-
-export GTK_IM_MODULE=uim
-export QT_IM_MODULE=uim
-export XMODIFIERS=@im=uim
-export XIM=uim
-%%PREFIX%%/bin/mozc start
-uim-xim &
-EOM
-}
-]