project-lakitu: add cos-linux-mod class

Add cos-linux-mod class to encapsulate module building logic. Because
of different USE flags in kernel and module builds the toolchain
being used in both cases are slightly different. This can be fixed at
the module ebuild level but to avoid copy-pasting logic from one
ebuild to another - encapsulate it in a singe eclass that makes sure
kernel and modules are built the same way.

This still requires certain manual synchronization between cros-kernel2
and cos-linux-mod classes but it's more preferable to synchronize
single code unit instead of multiple.

BUG=b/186269275
TEST=presubmit
RELEASE_NOTE=None

Change-Id: Idf57d4b8397629d88b509871dbf3ca0bc4a35b38
Reviewed-on: https://cos-review.googlesource.com/c/cos/overlays/board-overlays/+/16032
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Reviewed-by: Roy Yang <royyang@google.com>
diff --git a/project-lakitu/eclass/cos-linux-mod.eclass b/project-lakitu/eclass/cos-linux-mod.eclass
new file mode 100644
index 0000000..af5e31a
--- /dev/null
+++ b/project-lakitu/eclass/cos-linux-mod.eclass
@@ -0,0 +1,74 @@
+#
+# Copyright 2021 Google LLC
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# version 2 as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# Check for EAPI 5+
+case "${EAPI:-0}" in
+0|1|2|3|4) die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}" ;;
+5|6) inherit eapi7-ver ;;
+7) ;;
+esac
+
+inherit linux-info linux-mod toolchain-funcs
+
+IUSE="
+	+clang
+	+llvm_ias
+	module_sign
+"
+
+REQUIRED_USE="
+	llvm_ias? ( clang )
+"
+
+# Because our kernel version string ends with '+' (e.g.
+# "4.4.21+"), Gentoo Linux's linux-info.eclass cannot locate the kernel build
+# output directory. Hence we set it up here.
+KBUILD_OUTPUT="${KERNEL_DIR}"/build
+
+pkg_setup() {
+	CONFIG_CHECK=""
+	MODULE_NAMES="${MODULE_NAME}(::)"
+	linux-mod_pkg_setup
+	BUILD_PARAMS="KERNEL_SOURCES=${KV_DIR} KBUILD_OUTPUT=${KBUILD_OUTPUT}"
+}
+
+cos-linux-mod_src_prepare() {
+	# Allowing gcc to be used when clang is not set.
+	# This is copied from cros-kernel2.eclass to make sure the third
+	# party kernel module uses the same compiler as kernel.
+	use clang || cros_use_gcc
+
+	default
+}
+
+cos-linux-mod_src_compile() {
+	# Assemble with LLVM's integrated assembler on x86_64 and aarch64
+	if use llvm_ias; then
+		export LLVM_IAS=1
+	fi
+	BUILD_TARGETS="module" linux-mod_src_compile
+}
+
+cos-linux-mod_src_install() {
+	if use module_sign ; then
+		# Sign the module first.
+		cp ${MODULE_NAME}.ko ${MODULE_NAME}.ko.orig
+		"${KBUILD_OUTPUT}"/scripts/sign-file \
+			sha256 \
+			"${KBUILD_OUTPUT}"/certs/signing_key.pem \
+			"${KBUILD_OUTPUT}"/certs/signing_key.x509 \
+			${MODULE_NAME}.ko
+	fi
+
+	linux-mod_src_install
+}