pkg/60654: inputmethod/mozc-*: the 2.29 family does not build; mozc-elisp needs X11 and no mozc-server; add a gyp option where bazel is not available

"[email protected] via gnats" <[email protected]>
Newsgroups gmane.os.netbsd.devel.pkgsrc.bugs
Message-ID <[email protected]>
>Number:         60654
>Category:       pkg
>Synopsis:       inputmethod/mozc-*: the 2.29 family does not build; mozc-elisp needs X11 and no mozc-server; add a gyp option where bazel is not available
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 27 00:15:00 +0000 2026
>Originator:     Showta Ishizaki
>Release:        NetBSD 11.0, pkgsrc CVS as of 2026-08-27
>Organization:
>Environment:
System: NetBSD 11.0 amd64
Architecture: x86_64
Machine: amd64
>Description:
	Four things.  The first stops all seven mozc packages in the
	2.29 family, the next two are mozc-elisp's own, and the last one
	is why the patch also adds a build option.  None of the seven
	are in the NetBSD 11.0/x86_64 binary set, which fits the first.

	First: the tree does not build with clang 21, and it fails
	twice.

	  external/com_google_absl/absl/meta/type_traits.h:841:36: error:
	  builtin __is_trivially_relocatable is deprecated; use
	  __builtin_is_cpp_trivially_relocatable instead
	  [-Werror,-Wdeprecated-builtins]
	    841 |     : std::integral_constant<bool,
	          |       __is_trivially_relocatable(T)> {};
	  Target //unix/emacs:mozc_emacs_helper failed to build

	clang 21 deprecated __is_trivially_relocatable.  The bundled
	abseil (third_party/abseil-cpp, c2435f83) guards its use with
	ABSL_HAVE_BUILTIN(__is_trivially_relocatable), which is still
	true — the builtin is deprecated, not gone — so the header keeps
	using it.  In abseil's own translation units that is a warning.
	It becomes an error in protobuf's, because
	third_party/protobuf/build_defs/cpp_opts.bzl adds -Werror and
	protobuf includes absl/algorithm/container.h.

	--copt on its own does not fix it.  The action that fails is
	protoc, which bazel builds in the exec configuration
	(bazel-out/netbsd-opt-exec-...), so --host_copt is needed as
	well.

	The second failure only shows up once mozc-server is built:

	  ./dictionary/pos_matcher.h:103:33: error: 'lifetimebound'
	  attribute cannot be applied to a parameter of a function that
	  returns void; did you mean 'lifetime_capture_by(X)'
	    103 |   void Set(const uint16_t *data
	          |            ABSL_ATTRIBUTE_LIFETIME_BOUND) { data_ = data; }

	That one is an error and not a warning, so there is no
	-Wno-error to reach for; it needs a patch.  The attribute says
	the return value borrows from the parameter, which says nothing
	about a function returning void, and dropping it changes no
	behaviour.  Upstream removed the setter entirely — PosMatcher
	now takes an absl::Span in its constructor — but that came with
	a larger rewrite of the class.

	Building mozc-elisp alone never reaches it: the Emacs helper
	does not compile rewriter/dictionary_generator.cc.  It turned up
	only because of the third problem below.

	Second: mozc-elisp requires X11 for nothing.

	The package installs three files — bin/mozc_emacs_helper, and
	mozc.el with its .elc.  ldd on the helper is

	  -lpthread.1 -lc.12 -lm.0 -lstdc++.9 -lgcc_s.1

	and nothing else.  It links no Qt, GL, GTK or glib.  But
	Makefile.common has

	  .if empty(PKGPATH:Minputmethod/mozc-server)
	  .include "../../graphics/MesaLib/buildlink3.mk"
	  .include "../../x11/qt6-qtbase/buildlink3.mk"
	  .endif

	so everything except mozc-server gets them, mozc-elisp included.
	The built package records

	  @pkgdep emacs30-nox11>=30.1<31
	  @pkgdep qt6-qtbase>=6.11.1nb1

	and USE_X11 is set, so on a machine with no X11 the package
	stops before it can even be fetched:

	  ERROR: [bsd.pkg.mk] mozc-elisp-2.29.5268.102nb13 uses X11, but
	  /usr/X11R7 not found

	A headless machine running an Emacs built without X11 — which is
	the usual reason to be using mozc.el rather than a GUI input
	method — cannot install the Emacs input method at all.

	Third: mozc-elisp does not depend on mozc-server, and the helper
	is useless without it.

	mozc.el does no conversion of its own.  It starts
	bin/mozc_emacs_helper, which is a client of
	libexec/mozc_server, and only mozc-server installs that.  With
	no server present the failure is quiet and late: the session is
	created and the first key fails.

	  (1 CreateSession) -> ((emacs-event-id . 1)(emacs-session-id . 1)
	                        (output . ()))
	  (2 SendKey 1 97)  -> ((error . session-error)
	                        (message . "Session failed"))

	So mozc-mode turns on and the mode line changes, and nothing
	looks wrong until someone types a character.

	With the 2.26 server from mozc-server226 installed instead, it
	is refused on version — from
	~/.config/mozc/mozc_emacs_helper.log:

	  client/client.cc(767) Version Mismatch: 2.26.4282.108
	                                          2.29.5268.102 3 3 1
	  client/client.cc(772) Server version mismatch even after server
	                        reboot
	  client/client.cc(200) CreateSession failed
	  base/process.cc(177)  Can't stat /usr/pkg/libexec/mozc_tool: No
	                        such file or directory

	The two mozc families install side by side, so a user can end up
	with mozc-elisp and mozc-server226, or mozc-elisp226 and
	mozc-server, and get "Session failed" with nothing to point at.
	Note the last line: on a fatal error mozc launches mozc_tool to
	put up a dialog, so what the user actually sees is a complaint
	about mozc_tool being missing, which is a consequence and not
	the cause — installing mozc-tool does not help.

	This is a gap in two front-ends rather than a policy:

	  declares it   fcitx5-mozc  ibus-mozc  mozc-renderer
	                ibus-mozc226  mozc-renderer226  uim-mozc226
	  does not      mozc-elisp   mozc-elisp226
	                mozc-tool    mozc-tool226
	                uim-mozc

	mozc-elisp is the only front-end missing it in both families.  I
	have left mozc-tool and uim-mozc alone since I have built
	neither, but they look like the same oversight: mozc_tool reads
	and writes the configuration through the client, and uim-mozc226
	declares the dependency while uim-mozc does not.

	Fourth: none of this can be built at all on 32-bit platforms,
	because bazel is not there.  devel/bazel says so itself:

	  BROKEN_ON_PLATFORM=	${LP32PLATFORMS}

	and the binary sets agree.  On the NetBSD 11.0 sets bazel-6.4.0
	exists for x86_64 and aarch64 and nowhere else:

	  i386      bazel 404
	  x86_64    bazel 200
	  aarch64   bazel 200
	  earmv7hf  bazel 404
	  sparc64   bazel 404
	  powerpc   bazel 404

	That is not a bug in the mozc packages, but it does mean a whole
	class of machines has no way to get to the Emacs input method,
	or to the server it needs.

	mozc still ships the gyp build.  2.29.5268.102 has
	build_mozc.py, 73 .gyp files outside third_party, and
	docs/build_mozc_in_docker.md documents

	  python3 build_mozc.py gyp
	  python3 build_mozc.py build -c Release package --no_ibus_build --no_gtk_build

	while saying the gyp build is in maintenance mode and no longer
	supports the ibus client or the GTK candidate window.  In the
	tree, gyp files exist for unix/emacs, renderer, gui and server;
	unix/ibus has only BUILD.bazel, and unix/uim and unix/fcitx5
	have neither, since their sources come from elsewhere.  So the
	gyp build can cover mozc-server and mozc-elisp, and the option
	in this patch covers those two only.

>How-To-Repeat:
	The build failure, on a machine with X11 so that it gets past
	the check below:

	  # cd /usr/pkgsrc/inputmethod/mozc-elisp
	  # make

	bazel compiles for some minutes and stops in protobuf with the
	deprecated-builtins error quoted above.  With that suppressed,
	building inputmethod/mozc-server stops in
	rewriter/dictionary_generator.cc with the lifetimebound error.

	The X11 requirement, on a machine with no X11 installed:

	  # cd /usr/pkgsrc/inputmethod/mozc-elisp
	  # make fetch
	  ERROR: [can-be-built-here.mk] This package has PKG_FAIL_REASON set:
	  ERROR: [bsd.pkg.mk] mozc-elisp-2.29.5268.102nb13 uses X11, but
	  /usr/X11R7 not found

	The missing dependency, with mozc-elisp installed and no
	mozc-server:

	  $ printf '(1 CreateSession)\n(2 SendKey 1 97)\n' | mozc_emacs_helper

	which gives the two replies quoted above.  In Emacs the same
	thing looks like this:

	  (require 'mozc)
	  M-x set-input-method RET japanese-mozc RET

	the mode line changes, and then the first key of "nihongo"
	fails.

	On a 32-bit platform, make stops in devel/bazel, and there is no
	binary package for it there either.

>Fix:
	The clang failures first.

	Makefile.common gains BAZEL_ARGS with the two flags the first
	failure needs, and the do-build lines pick it up, so the flags
	live in one place instead of being repeated seven times.

	Three Makefile.commons are involved, not one.  fcitx5-mozc and
	uim-mozc do not read inputmethod/mozc-server/Makefile.common;
	each has its own, with its own copy of the bazel TOOL_DEPENDS
	and OSDEST.  Adding ${BAZEL_ARGS} to their do-build without
	defining it there expands to nothing, and make says nothing
	about it, so those two files get the same two lines as well.

	patch-dictionary_pos__matcher.h drops the attribute for the
	second failure, and distinfo gains its line.

	Then mozc-elisp's own two.

	The MesaLib and qt6-qtbase includes skip mozc-elisp as well as
	mozc-server.  With that, USE_X11 is empty and the package's only
	dependencies are mozc-server and emacs30-nox11.

	mozc-elisp gains the pinned DEPENDS on mozc-server.  The version
	is pinned rather than >= because that is what the client
	enforces: CheckVersionOrRestartServer compares the full version
	string, restarts the server once, and gives up.  ibus-mozc and
	fcitx5-mozc use >=2.29 and mozc-renderer uses -[0-9]*, either of
	which would have caught the 2.26 case above, but neither would
	catch a 2.29 client against a 2.30 server.

	Then the option.

	options.mk adds a "gyp" option, and mozc-server and mozc-elisp
	include it.  When it is on, Makefile.common asks for devel/gyp,
	lang/py-six and devel/ninja-build instead of devel/bazel, runs
	build_mozc.py gyp in do-configure, and OSDEST changes because
	the two build systems write to different directories:

	  bazel  bazel-out/${OSDEST}/bin/server/mozc_server
	  gyp    out_${OSDEST}/${MOZC_BUILD_MODE}/mozc_server

	The gyp run needs --noqt.  Without it GypMain reads
	options.qtdir, which the option parser only defines on the
	Windows branch, and dies with AttributeError.  That fits what
	upstream says about the GTK candidate window being gone.

	The option is suggested, not merely supported, on the platforms
	where devel/bazel is broken:

	  .for _mozc_platform_ in ${LP32PLATFORMS}
	  .  if !empty(MACHINE_PLATFORM:M${_mozc_platform_})
	  PKG_SUGGESTED_OPTIONS+=	gyp
	  .  endif
	  .endfor

	rather than naming architectures, so that it follows
	devel/bazel's own declaration if that list changes.  Everywhere
	else the default is unchanged and bazel is used.

	The gyp driver has no NetBSD support upstream and never has —
	build_mozc.py, build_tools/util.py and
	build_tools/mozc_version.py have no NetBSD branch in 2.26, 2.28
	or 2.29.  What makes inputmethod/mozc-server226 work is your
	patches, and four of them are what this forward ports.  Without
	them the first command dies before it parses anything:

	  UnboundLocalError: cannot access local variable 'default_target'
	    build_mozc.py:191, AddTargetPlatformOption

	One of the four differs from mozc-server226 deliberately.
	build_tools/mozc_version.py has

	  TARGET_PLATFORM_TO_DIGIT = {
	      'Windows': '0', 'Mac': '1', 'Linux': '2', ...
	  }

	and _GetRevisionForPlatform does revision[0:-1] + last_digit —
	the digit replaces the last digit of the version string, and
	that string is what the client and the server compare when a
	session is created.  mozc-server226 uses '8', which is right
	there: it has no bazel build to agree with, and its server and
	its helper come out of the same gyp run.  Here there is a bazel
	build, it does not go through this table, and it produces the
	version in DISTNAME unchanged — 2.29.5268.102, whose last digit
	is the Linux digit.  Using '8' would give 2.29.5268.108, and
	since PKGNAME comes from DISTNAME and not from that string, the
	two builds would carry the same PKGNAME and refuse to talk to
	each other.  So this uses '2'.

	I measured that before settling on it.  A gyp-built helper
	against the bazel-built server:

	  ((mozc-emacs-helper . t)(version . "2.29.5268.108"))
	  (2 SendKey 1 97) -> ((error . session-error)
	                       (message . "Session failed"))

	which is indistinguishable from having no server at all.

	patch-gyp_common.gypi is mozc-server226's, minus the
	make_global_settings hunk, which hardcodes the compiler with
	which(1); pkgsrc supplies the compiler through its wrappers.
	Without the ldflags in it, linking protoc fails with an
	undefined reference to pthread_getschedparam.

	Only mozc-elisp's PKGREVISION moves.  The flags do not change
	what the other packages produce, and none of them are in the
	binary set to be rebuilt.

	Tested on NetBSD 11.0/amd64 with clang-21.1.8 and bazel-6.4.0.
	All seven build with bazel, in this order, each installed before
	the next:

	  mozc-elisp-2.29.5268.102nb14.tgz
	  mozc-server-2.29.5268.102nb14.tgz
	  mozc-tool-2.29.5268.102nb14.tgz
	  mozc-renderer-2.29.5268.102nb14.tgz
	  ibus-mozc-2.29.5268.102nb14.tgz
	  fcitx5-mozc-2.29.5268.102nb13.tgz
	  uim-mozc-2.29.5268.102nb14.tgz

	which is also what says the four gyp patches do not disturb the
	bazel build: they are applied unconditionally and all seven were
	built with them in place.

	  # pkg_info -n mozc-elisp
	  Requires:
	  mozc-server-2.29.5268.102{,nb*}
	  emacs30-nox11>=30.1<31

	With mozc-server and mozc-elisp installed, the helper converts:

	  (1 CreateSession), then n i h o n g o
	  ((emacs-event-id . 8)(emacs-session-id . 1)(output .
	    ((preedit . ((segment ((value . "にほんご") ...))))
	     (candidates . ((size . 3)
	       (candidate ((index . 0)(value . "日本語")(id . 0))
	                  ((index . 1)(value . "日本語字幕")(id . 1))
	                  ((index . 2)(value . "日本語訳")(id . 2)))) ...)))))

	The mozc_emacs_helper binary is byte for byte identical with and
	without patch-dictionary_pos__matcher.h, as expected, since no
	translation unit in that package includes the header.

	With PKG_OPTIONS.mozc=gyp, mozc-server and mozc-elisp build the
	same way and convert the same way, the helper reports
	2.29.5268.102 as the bazel one does, and the binary package
	records which build it came from:

	  # tar zxOf mozc-server-2.29.5268.102nb14.tgz +BUILD_INFO | grep PKG_OPTIONS
	  PKG_OPTIONS=gyp

	The gyp build took 11 minutes against 38 for bazel, and needs
	neither bazel nor openjdk11.

	The platform default was checked on real hardware, on a NetBSD
	10.1/i386 machine with this patch applied to a pkgsrc tree:

	  $ make show-vars VARNAMES="MACHINE_PLATFORM PKG_OPTIONS OSDEST"
	  NetBSD-10.1-i386
	  gyp
	  bsd

	Setting PKG_OPTIONS.mozc=-gyp there gives PKG_OPTIONS empty and
	OSDEST netbsd-opt again, so the choice stays with whoever is
	building.

	Two notes on things I have not touched.

	Moving to mozc 2.30.5544.102 does not avoid any of the clang
	failures.  2.30 is still WORKSPACE.bazel plus build_mozc.py, so
	the version bump itself would work, but its abseil pin
	(2f9e432c) has the same branch — it only adds exclusions for
	Windows and NVCC — its protobuf pin (a978b757) still has
	-Werror, and dictionary/pos_matcher.h still has the attribute.
	2.31 moves to MODULE.bazel and 3.x drops build_mozc.py
	entirely, which is a different and much larger question.

	And devel/bazel's Makefile has

	  BROKEN_ON_PLATFORM=	${LP32PLATFORMS}
	  # ...
	  BROKEN_ON_PLATFORM=	NetBSD-11.99.*-*

	The second assignment is = and not +=, so it discards the first,
	and 32-bit platforms are no longer declared broken.  That looks
	like a typo rather than a decision.

Index: inputmethod/fcitx5-mozc/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/fcitx5-mozc/Makefile,v
retrieving revision 1.40
diff -u -u -r1.40 Makefile
--- inputmethod/fcitx5-mozc/Makefile	14 May 2026 16:41:19 -0000	1.40
+++ inputmethod/fcitx5-mozc/Makefile	27 Aug 2026 00:11:00 -0000
@@ -38,6 +38,7 @@
 			--action_env=PATH=${PATH} \
 			--sandbox_debug \
 			--verbose_failures \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt
 
 
Index: inputmethod/fcitx5-mozc/Makefile.common
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/fcitx5-mozc/Makefile.common,v
retrieving revision 1.7
diff -u -u -r1.7 Makefile.common
--- inputmethod/fcitx5-mozc/Makefile.common	10 Feb 2024 12:26:00 -0000	1.7
+++ inputmethod/fcitx5-mozc/Makefile.common	27 Aug 2026 00:11:00 -0000
@@ -44,6 +44,17 @@
 
 .include "../../mk/bsd.prefs.mk"
 
+# clang 21 deprecated __is_trivially_relocatable, which the bundled abseil
+# still uses, and the bundled protobuf is built with -Werror, so every
+# protobuf translation unit that includes an abseil header fails.  The action
+# that fails is protoc, which bazel builds in the exec configuration, so
+# --copt alone has no effect and --host_copt is needed as well.
+#
+# inputmethod/mozc-server/Makefile.common needs the same two lines: this
+# package does not read that file, it has its own Makefile.common.
+BAZEL_ARGS+=	--host_copt=-Wno-error=deprecated-builtins
+BAZEL_ARGS+=	--copt=-Wno-error=deprecated-builtins
+
 OPSYSVARS+=	OSDEST
 OSDEST.Linux=	linux-opt
 OSDEST.NetBSD=	netbsd-opt
Index: inputmethod/ibus-mozc/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/ibus-mozc/Makefile,v
retrieving revision 1.105
diff -u -u -r1.105 Makefile
--- inputmethod/ibus-mozc/Makefile	14 May 2026 16:41:19 -0000	1.105
+++ inputmethod/ibus-mozc/Makefile	27 Aug 2026 00:11:00 -0000
@@ -27,6 +27,7 @@
 			--sandbox_debug \
 			--verbose_failures \
 			--subcommands \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt
 
 do-install:
Index: inputmethod/mozc-elisp/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-elisp/Makefile,v
retrieving revision 1.95
diff -u -u -r1.95 Makefile
--- inputmethod/mozc-elisp/Makefile	14 May 2026 16:41:19 -0000	1.95
+++ inputmethod/mozc-elisp/Makefile	27 Aug 2026 00:11:00 -0000
@@ -1,15 +1,25 @@
 # $NetBSD: Makefile,v 1.95 2026/05/14 16:41:19 ryoon Exp $
 
 PKGNAME=	${EMACS_PKGNAME_PREFIX}${DISTNAME:S/mozc-/mozc-elisp-/}
-PKGREVISION=	13
+PKGREVISION=	14
 CATEGORIES=	inputmethod editors
 
+# mozc_emacs_helper does not convert anything itself; it talks to
+# ${PREFIX}/libexec/mozc_server.  Without the server, CreateSession succeeds
+# and the first key gives ((error . session-error)(message . "Session
+# failed")).  The client refuses a server whose version does not match
+# (client.cc, CheckVersionOrRestartServer), so lock the version.
+DEPENDS+=	mozc-server-${PKGVERSION_NOREV}{,nb*}:../../inputmethod/mozc-server
+
+.include "../../inputmethod/mozc-server/options.mk"
+
 EMACS_MODULES=	base leim
 
 .include "../../editors/emacs/modules.mk"
 
 INSTALLATION_DIRS=	${EMACS_LISPPREFIX} bin
 
+.if empty(PKG_OPTIONS:Mgyp)
 do-build:
 	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
 		${PREFIX}/bin/bazel \
@@ -26,6 +36,7 @@
 			--sandbox_debug \
 			--verbose_failures \
 			--subcommands \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt && \
 		${EMACS_BIN} --no-init-file --no-site-file -batch \
 			-f batch-byte-compile ${WRKSRC}/unix/emacs/mozc.el
@@ -37,6 +48,22 @@
 		${DESTDIR}${EMACS_LISPPREFIX}
 	${INSTALL_DATA} ${WRKSRC}/unix/emacs/mozc.elc \
 		${DESTDIR}${EMACS_LISPPREFIX}
+.else
+do-build:
+	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
+		${PYTHONBIN} build_mozc.py build -c ${MOZC_BUILD_MODE} \
+			unix/emacs/emacs.gyp:mozc_emacs_helper && \
+		${EMACS_BIN} --no-init-file --no-site-file -batch \
+			-f batch-byte-compile ${WRKSRC}/unix/emacs/mozc.el
+
+do-install:
+	${INSTALL_PROGRAM} ${WRKSRC}/out_${OSDEST}/${MOZC_BUILD_MODE}/mozc_emacs_helper \
+		${DESTDIR}${PREFIX}/bin
+	${INSTALL_DATA} ${WRKSRC}/unix/emacs/mozc.el \
+		${DESTDIR}${EMACS_LISPPREFIX}
+	${INSTALL_DATA} ${WRKSRC}/unix/emacs/mozc.elc \
+		${DESTDIR}${EMACS_LISPPREFIX}
+.endif
 
 .include "../../inputmethod/mozc-server/Makefile.common"
 .include "../../mk/bsd.pkg.mk"
Index: inputmethod/mozc-renderer/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-renderer/Makefile,v
retrieving revision 1.86
diff -u -u -r1.86 Makefile
--- inputmethod/mozc-renderer/Makefile	14 May 2026 16:41:20 -0000	1.86
+++ inputmethod/mozc-renderer/Makefile	27 Aug 2026 00:11:00 -0000
@@ -26,6 +26,7 @@
 			--sandbox_debug \
 			--verbose_failures \
 			--subcommands \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt
 
 do-install:
Index: inputmethod/mozc-server/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-server/Makefile,v
retrieving revision 1.104
diff -u -u -r1.104 Makefile
--- inputmethod/mozc-server/Makefile	14 May 2026 16:41:20 -0000	1.104
+++ inputmethod/mozc-server/Makefile	27 Aug 2026 00:11:00 -0000
@@ -1,15 +1,18 @@
 # $NetBSD: Makefile,v 1.104 2026/05/14 16:41:20 ryoon Exp $
 
 PKGNAME=	${DISTNAME:S/mozc-/mozc-server-/}
-PKGREVISION=	13
+PKGREVISION=	14
 
 INSTALLATION_DIRS+=	libexec
 
+.include "../../inputmethod/mozc-server/options.mk"
+
 post-configure:
 	cd ${WRKSRC}/dist && \
 		unzip -d ../dictionary jigyosyo.zip && \
 		unzip -d ../dictionary ken_all.zip
 
+.if empty(PKG_OPTIONS:Mgyp)
 do-build:
 	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
 		${PREFIX}/bin/bazel \
@@ -26,11 +29,22 @@
 			--subcommands \
 			--distdir=${WRKSRC}/dist \
 			--jobs=${MAKE_JOBS:U1} \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt
 
 do-install:
 	${INSTALL_PROGRAM} ${WRKSRC}/bazel-out/${OSDEST}/bin/server/mozc_server \
 		${DESTDIR}${PREFIX}/libexec/mozc_server
+.else
+do-build:
+	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
+		${PYTHONBIN} build_mozc.py build -c ${MOZC_BUILD_MODE} \
+			server/server.gyp:mozc_server
+
+do-install:
+	${INSTALL_PROGRAM} ${WRKSRC}/out_${OSDEST}/${MOZC_BUILD_MODE}/mozc_server \
+		${DESTDIR}${PREFIX}/libexec/mozc_server
+.endif
 
 .include "../../inputmethod/mozc-server/Makefile.common"
 .include "../../mk/bsd.pkg.mk"
Index: inputmethod/mozc-server/Makefile.common
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-server/Makefile.common,v
retrieving revision 1.43
diff -u -u -r1.43 Makefile.common
--- inputmethod/mozc-server/Makefile.common	11 Dec 2024 03:07:20 -0000	1.43
+++ inputmethod/mozc-server/Makefile.common	27 Aug 2026 00:11:00 -0000
@@ -114,7 +114,13 @@
 
 USE_CXX_FEATURES+=	c++14
 
+.if empty(PKG_OPTIONS:Mgyp)
 TOOL_DEPENDS+=		bazel-[0-9]*:../../devel/bazel
+.else
+TOOL_DEPENDS+=		${PYPKGPREFIX}-gyp>=0.1pre20200512.caa60026e223fc501e8b337fd5086ece4028b1c6:../../devel/gyp
+TOOL_DEPENDS+=		${PYPKGPREFIX}-six-[0-9]*:../../lang/py-six
+TOOL_DEPENDS+=		ninja-build-[0-9]*:../../devel/ninja-build
+.endif
 
 SUBST_CLASSES+=		prefix
 SUBST_STAGE.prefix=	pre-configure
@@ -128,9 +134,32 @@
 
 .include "../../mk/bsd.prefs.mk"
 
+# clang 21 deprecated __is_trivially_relocatable, which the bundled abseil
+# (third_party/abseil-cpp, c2435f83) still uses, and the bundled protobuf is
+# built with -Werror by third_party/protobuf/build_defs/cpp_opts.bzl, so
+# every protobuf translation unit that includes an abseil header fails.
+#
+# The action that fails is protoc, which bazel builds in the exec
+# configuration (bazel-out/netbsd-opt-exec-...), so --copt alone has no
+# effect and --host_copt is needed as well.
+BAZEL_ARGS+=	--host_copt=-Wno-error=deprecated-builtins
+BAZEL_ARGS+=	--copt=-Wno-error=deprecated-builtins
+
 OPSYSVARS+=	OSDEST
+.if empty(PKG_OPTIONS:Mgyp)
 OSDEST.Linux=	linux-opt
 OSDEST.NetBSD=	netbsd-opt
+.else
+OSDEST.Linux=	linux
+OSDEST.NetBSD=	bsd
+MOZC_BUILD_MODE?=	Release
+
+do-configure:
+	cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} \
+		${PYTHONBIN} build_mozc.py gyp \
+			--gypdir=${LOCALBASE}/bin \
+			--noqt
+.endif
 
 CHECK_PIE_SUPPORTED=	no
 pre-configure:
@@ -140,7 +169,13 @@
 .endfor
 	${RM} -r ${WRKDIR}/.cwrapper
 
-.if empty(PKGPATH:Minputmethod/mozc-server)
+# mozc-elisp builds only //unix/emacs:mozc_emacs_helper, which links against
+# nothing but libc, libstdc++, libm, libpthread and libgcc_s.  Pulling in
+# MesaLib and qt6-qtbase records qt6-qtbase as a run-time dependency of it
+# and sets USE_X11, so on a machine without X11 the package stops in
+# can-be-built-here.mk before it can even be fetched.
+.if empty(PKGPATH:Minputmethod/mozc-server) && \
+    empty(PKGPATH:Minputmethod/mozc-elisp)
 .include "../../graphics/MesaLib/buildlink3.mk"
 .include "../../x11/qt6-qtbase/buildlink3.mk"
 .endif
Index: inputmethod/mozc-server/distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-server/distinfo,v
retrieving revision 1.30
diff -u -u -r1.30 distinfo
--- inputmethod/mozc-server/distinfo	11 Dec 2024 03:07:20 -0000	1.30
+++ inputmethod/mozc-server/distinfo	27 Aug 2026 00:11:00 -0000
@@ -103,15 +103,20 @@
 SHA1 (patch-base_system__util.cc) = 893cac24fbdd1fa5ff02a1cb6f6ca2539021c8f7
 SHA1 (patch-base_system__util__test.cc) = 0195f3bd34d695ff047bf44152923cdcbc6e61f1
 SHA1 (patch-bazel_pkg__config__repository.bzl) = 1f0be3d001e14af31e75052aa6e3e1c8b31b12c3
+SHA1 (patch-build__mozc.py) = ee93bd98eec0f744c75d4a1354b47b0dd27f4042
+SHA1 (patch-build__tools_mozc__version.py) = 9f932f1b0d0208b1f99e27399876ea34d9a2daa6
+SHA1 (patch-build__tools_util.py) = e1fa482b7fa4c2b63efb071b06f7a4110cf5279f
 SHA1 (patch-client_client.cc) = 2094c8d9fa9c3806fc343373ac34b7cfd441c1e8
 SHA1 (patch-config.bzl) = 2c35cc8a89ecda745604911b0430df4834548bc3
 SHA1 (patch-config_stats__config__util__test.cc) = a51e1c239c54c406b21375be526facf29d924c53
 SHA1 (patch-dictionary_BUILD.bazel) = 6a0a527ff9768f9d4da6500ea7bcf46e3889a172
+SHA1 (patch-dictionary_pos__matcher.h) = 18835bdb4ee5ddc5b441791dc874a3749ca70401
 SHA1 (patch-gui_config__dialog_config__dialog.cc) = b7761985e9150da19deeeda9b751d6e65d488071
 SHA1 (patch-gui_config__dialog_keybinding__editor.cc) = a2e22f214f943c9d91b091432749f24900675f94
 SHA1 (patch-gui_config__dialog_keymap__editor.cc) = 12671f74b38944f908c20a48bae8e83f140732e8
 SHA1 (patch-gui_dictionary__tool_dictionary__tool.cc) = eeb6427662b121dfd0fe5cf09b8d3eba4cdc6cd2
 SHA1 (patch-gui_word__register__dialog_word__register__dialog.cc) = b90573e75df98a477441bb992722b5dba060b016
+SHA1 (patch-gyp_common.gypi) = b50469d6fd69993352591e3e7ad8d91ffb9b0e23
 SHA1 (patch-ipc_ipc__path__manager.cc) = 1366d8a7258fbe0268f032540bd1dc5edfd350bf
 SHA1 (patch-ipc_unix__ipc.cc) = 8ab319397184fed222bc597c6494db65e46066f1
 SHA1 (patch-session_session.cc) = 4f2629d6831c2f1caf00f7bcc2b5a377c3db50d3
Index: inputmethod/mozc-server/options.mk
===================================================================
RCS file: inputmethod/mozc-server/options.mk
diff -N inputmethod/mozc-server/options.mk
--- /dev/null
+++ inputmethod/mozc-server/options.mk
@@ -0,0 +1,29 @@
+# $NetBSD$
+
+PKG_OPTIONS_VAR=	PKG_OPTIONS.mozc
+PKG_SUPPORTED_OPTIONS=	gyp
+
+.include "../../mk/bsd.prefs.mk"
+
+# mozc can be built either with bazel, which is what upstream tests, or with
+# gyp, which upstream keeps in maintenance mode.  The gyp build needs neither
+# bazel nor a JDK, but upstream has dropped the ibus client and the GTK
+# candidate window from it, so only inputmethod/mozc-server and
+# inputmethod/mozc-elisp include this file.
+#
+# devel/bazel does not build on 32-bit platforms -- its Makefile carries
+# BROKEN_ON_PLATFORM= ${LP32PLATFORMS} -- and there is no bazel binary
+# package for any of them; on the NetBSD 11.0 binary sets bazel exists for
+# x86_64 and aarch64 only.  Default to the gyp build everywhere else, so that
+# the Emacs input method can be built at all on those platforms.
+.for _mozc_platform_ in ${LP32PLATFORMS}
+.  if !empty(MACHINE_PLATFORM:M${_mozc_platform_})
+PKG_SUGGESTED_OPTIONS+=	gyp
+.  endif
+.endfor
+
+.include "../../mk/bsd.options.mk"
+
+# Both builds produce the same version string, so packages built either way
+# are interchangeable at run time; see patch-build__tools_mozc__version.py
+# for why that needs saying.
Index: inputmethod/mozc-server/patches/patch-build__mozc.py
===================================================================
RCS file: inputmethod/mozc-server/patches/patch-build__mozc.py
diff -N inputmethod/mozc-server/patches/patch-build__mozc.py
--- /dev/null
+++ inputmethod/mozc-server/patches/patch-build__mozc.py
@@ -0,0 +1,46 @@
+$NetBSD$
+
+NetBSD support for the GYP build, needed by the "gyp" package option.
+
+Upstream build_mozc.py has no NetBSD branch in any release; the gyp
+command dies in AddTargetPlatformOption with UnboundLocalError before it
+parses anything.
+
+--- build_mozc.py.orig
++++ build_mozc.py
+@@ -54,6 +54,7 @@
+ from build_tools.util import ColoredText
+ from build_tools.util import CopyFile
+ from build_tools.util import IsLinux
++from build_tools.util import IsNetBSD
+ from build_tools.util import IsMac
+ from build_tools.util import IsWindows
+ from build_tools.util import PrintErrorAndExit
+@@ -98,6 +99,7 @@
+       'Windows': 'out_win',
+       'Mac': 'out_mac',
+       'Linux': 'out_linux',
++      'NetBSD': 'out_bsd',
+   }
+ 
+   if target_platform not in platform_dict:
+@@ -160,7 +162,7 @@
+   # Include subdirectory of win32 and breakpad for Windows
+   if options.target_platform == 'Windows':
+     gyp_file_names.extend(glob.glob('%s/win32/*/*.gyp' % OSS_SRC_DIR))
+-  elif options.target_platform == 'Linux':
++  elif options.target_platform in ('Linux', 'NetBSD'):
+     gyp_file_names.extend(glob.glob('%s/unix/emacs/*.gyp' % OSS_SRC_DIR))
+   gyp_file_names.sort()
+   return gyp_file_names
+@@ -181,7 +183,9 @@
+ 
+ # TODO(b/68382821): Remove this method. We no longer need --target_platform.
+ def AddTargetPlatformOption(parser):
+-  if IsLinux():
++  if IsNetBSD():
++    default_target = 'NetBSD'
++  elif IsLinux():
+     default_target = 'Linux'
+   elif IsWindows():
+     default_target = 'Windows'
Index: inputmethod/mozc-server/patches/patch-build__tools_mozc__version.py
===================================================================
RCS file: inputmethod/mozc-server/patches/patch-build__tools_mozc__version.py
diff -N inputmethod/mozc-server/patches/patch-build__tools_mozc__version.py
--- /dev/null
+++ inputmethod/mozc-server/patches/patch-build__tools_mozc__version.py
@@ -0,0 +1,26 @@
+$NetBSD$
+
+NetBSD support for the GYP build, needed by the "gyp" package option.
+
+The digit replaces the last digit of the version string (see
+_GetRevisionForPlatform), and the resulting string is what the client and
+the server compare when a session is created.  It is deliberately the same
+digit as Linux, so that a package built with the gyp option reports the
+same version as one built with bazel; bazel does not go through this table
+and produces the version in DISTNAME unchanged.  With a different digit the
+two builds carry the same PKGNAME but refuse to talk to each other.
+
+inputmethod/mozc-server226 uses '8' here.  That is correct there: it has no
+bazel build to agree with, and both its server and its helper come out of
+the same gyp run.
+
+--- build_tools/mozc_version.py.orig
++++ build_tools/mozc_version.py
+@@ -67,6 +67,7 @@
+     'iOS': '6',
+     'iOS_sim': '6',
+     'Wasm': '7',
++    'NetBSD': '2',
+ }
+ 
+ VERSION_PROPERTIES = [
Index: inputmethod/mozc-server/patches/patch-build__tools_util.py
===================================================================
RCS file: inputmethod/mozc-server/patches/patch-build__tools_util.py
diff -N inputmethod/mozc-server/patches/patch-build__tools_util.py
--- /dev/null
+++ inputmethod/mozc-server/patches/patch-build__tools_util.py
@@ -0,0 +1,18 @@
+$NetBSD$
+
+NetBSD support for the GYP build, needed by the "gyp" package option.
+
+--- build_tools/util.py.orig
++++ build_tools/util.py
+@@ -103,6 +103,11 @@
+   return abs_path
+ 
+ 
++def IsNetBSD():
++  """Returns true if the platform is NetBSD."""
++  return os.name == 'posix' and os.uname()[0] == 'NetBSD'
++
++
+ def GetNumberOfProcessors():
+   """Returns the number of CPU cores available.
+ 
Index: inputmethod/mozc-server/patches/patch-dictionary_pos__matcher.h
===================================================================
RCS file: inputmethod/mozc-server/patches/patch-dictionary_pos__matcher.h
diff -N inputmethod/mozc-server/patches/patch-dictionary_pos__matcher.h
--- /dev/null
+++ inputmethod/mozc-server/patches/patch-dictionary_pos__matcher.h
@@ -0,0 +1,25 @@
+$NetBSD$
+
+clang 21 rejects [[clang::lifetimebound]] on a parameter of a function that
+returns void:
+
+  ./dictionary/pos_matcher.h:103:33: error: 'lifetimebound' attribute cannot
+  be applied to a parameter of a function that returns void; did you mean
+  'lifetime_capture_by(X)'
+
+The attribute says the return value borrows from the parameter, so on a void
+function it says nothing; dropping it changes no behaviour.  Upstream removed
+this setter entirely -- PosMatcher now takes an absl::Span in its constructor
+-- but that came with a larger rewrite of the class.
+
+--- dictionary/pos_matcher.h.orig
++++ dictionary/pos_matcher.h
+@@ -100,7 +100,7 @@
+   PosMatcher(const PosMatcher &) = default;
+   PosMatcher &operator=(const PosMatcher &) = default;
+ 
+-  void Set(const uint16_t *data ABSL_ATTRIBUTE_LIFETIME_BOUND) { data_ = data; }
++  void Set(const uint16_t *data) { data_ = data; }
+ 
+  private:
+   // Used in pos_matcher_impl.inc.
Index: inputmethod/mozc-server/patches/patch-gyp_common.gypi
===================================================================
RCS file: inputmethod/mozc-server/patches/patch-gyp_common.gypi
diff -N inputmethod/mozc-server/patches/patch-gyp_common.gypi
--- /dev/null
+++ inputmethod/mozc-server/patches/patch-gyp_common.gypi
@@ -0,0 +1,66 @@
+$NetBSD$
+
+NetBSD support for the GYP build, needed by the "gyp" package option.
+
+Without the ldflags, linking protoc fails with an undefined reference to
+pthread_getschedparam.
+
+inputmethod/mozc-server226 also flips the make_global_settings block for
+NetBSD, which hardcodes the compiler with which(1).  That is left out here;
+pkgsrc supplies the compiler through its wrappers.
+
+--- gyp/common.gypi.orig
++++ gyp/common.gypi
+@@ -74,6 +74,14 @@
+       '-fstack-protector',
+       '--param=ssp-buffer-size=4',
+     ],
++    # netbsd_cflags will be used for NetBSD.
++    'netbsd_cflags': [
++      '<@(gcc_cflags)',
++      '-fPIC',
++      '-D_NETBSD_SOURCE',
++      '-fno-exceptions',
++      '<!(echo $CFLAGS)',
++    ],
+     # mac_cflags will be used in Mac.
+     # Xcode 4.5 which we are currently using does not support ssp-buffer-size.
+     # TODO(horo): When we can use Xcode 4.6 which supports ssp-buffer-size,
+@@ -103,6 +111,12 @@
+         'compiler_target': 'gcc',
+         'compiler_host': 'gcc',
+       }],
++      ['target_platform=="NetBSD"', {
++        'compiler_target': 'gcc',
++        'compiler_target_version_int': 409,  # GCC 4.9 or higher
++        'compiler_host': 'gcc',
++        'compiler_host_version_int': 409,  # GCC 4.9 or higher
++      }],
+     ],
+   },
+   'target_defaults': {
+@@ -228,6 +242,24 @@
+           }],
+         ],
+       }],
++      ['OS=="netbsd"', {
++        'defines': [
++          'OS_NETBSD',
++        ],
++        'cflags': [
++          '<@(netbsd_cflags)',
++          '-fPIC',
++          '-fno-exceptions',
++        ],
++        'cflags_cc': [
++          # We use deprecated <hash_map> and <hash_set> instead of upcoming
++          # <unordered_map> and <unordered_set>.
++          '-Wno-deprecated',
++        ],
++        'ldflags': [
++          '-pthread',
++        ],
++      }],
+       ['OS=="mac"', {
+         'defines': [
+           '__APPLE__',
Index: inputmethod/mozc-tool/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/mozc-tool/Makefile,v
retrieving revision 1.100
diff -u -u -r1.100 Makefile
--- inputmethod/mozc-tool/Makefile	14 May 2026 16:41:20 -0000	1.100
+++ inputmethod/mozc-tool/Makefile	27 Aug 2026 00:11:00 -0000
@@ -19,6 +19,7 @@
 			--action_env=PATH=${PATH} \
 			--sandbox_debug \
 			--verbose_failures \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt
 
 do-install:
Index: inputmethod/uim-mozc/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/uim-mozc/Makefile,v
retrieving revision 1.86
diff -u -u -r1.86 Makefile
--- inputmethod/uim-mozc/Makefile	14 May 2026 16:41:21 -0000	1.86
+++ inputmethod/uim-mozc/Makefile	27 Aug 2026 00:11:00 -0000
@@ -23,6 +23,7 @@
 			--distdir=${WRKSRC}/dist \
 			--jobs=${MAKE_JOBS:U1} \
 			--subcommands \
+			${BAZEL_ARGS} \
 			--config oss_linux --compilation_mode opt \
 			--experimental_cc_shared_library
 
Index: inputmethod/uim-mozc/Makefile.common
===================================================================
RCS file: /cvsroot/pkgsrc/inputmethod/uim-mozc/Makefile.common,v
retrieving revision 1.2
diff -u -u -r1.2 Makefile.common
--- inputmethod/uim-mozc/Makefile.common	18 Dec 2024 02:44:32 -0000	1.2
+++ inputmethod/uim-mozc/Makefile.common	27 Aug 2026 00:11:00 -0000
@@ -104,6 +104,17 @@
 
 .include "../../mk/bsd.prefs.mk"
 
+# clang 21 deprecated __is_trivially_relocatable, which the bundled abseil
+# still uses, and the bundled protobuf is built with -Werror, so every
+# protobuf translation unit that includes an abseil header fails.  The action
+# that fails is protoc, which bazel builds in the exec configuration, so
+# --copt alone has no effect and --host_copt is needed as well.
+#
+# inputmethod/mozc-server/Makefile.common needs the same two lines: this
+# package does not read that file, it has its own Makefile.common.
+BAZEL_ARGS+=	--host_copt=-Wno-error=deprecated-builtins
+BAZEL_ARGS+=	--copt=-Wno-error=deprecated-builtins
+
 OPSYSVARS+=	OSDEST
 OSDEST.Linux=	linux-opt
 OSDEST.NetBSD=	netbsd-opt
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.