Files
linux-kernel-module-cheat/build-modules
Ciro Santilli 六四事件 法轮功 146e568db8 move all our stuff into /lkmc in guest
Motivation: userland is getting several new subdirectories, it would be
too insane to just dump all of that in the guest root filesystem.

To alleviate the cd pain, .profile puts user inside /lkmc by default.
2019-05-05 00:00:00 +00:00

123 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
import distutils.dir_util
import os
import platform
import shutil
import common
from shell_helpers import LF
class Main(common.BuildCliFunction):
def __init__(self):
super().__init__(
description='''\
Build our Linux kernel modules without using Buildroot.
See also: https://github.com/cirosantilli/linux-kernel-module-cheat#host
''')
self.add_argument(
'--make-args',
default='',
)
self.add_argument(
'--host',
default=False,
help='''\
Build the Linux kernel modules against the host kernel.
Place the modules on a separate magic directory from non --host builds.
''',
)
self.add_argument(
'kernel-modules',
default=[],
help='Which kernel modules to build. Default: build all',
nargs='*',
)
def build(self):
build_dir = self.get_build_dir()
os.makedirs(build_dir, exist_ok=True)
# I kid you not, out-of-tree build is not possible, O= does not work as for the kernel build:
#
# * https://stackoverflow.com/questions/5718899/building-an-out-of-tree-linux-kernel-module-in-a-separate-object-directory
# * https://stackoverflow.com/questions/12244979/build-kernel-module-into-a-specific-directory
# * https://stackoverflow.com/questions/18386182/out-of-tree-kernel-modules-multiple-module-single-makefile-same-source-file
#
# This copies only modified files as per:
# https://stackoverflow.com/questions/5718899/building-an-out-of-tree-linux-kernel-module-in-a-separate-object-directory
distutils.dir_util.copy_tree(
self.env['kernel_modules_source_dir'],
os.path.join(build_dir, self.env['kernel_modules_subdir']),
update=1,
)
distutils.dir_util.copy_tree(
self.env['include_source_dir'],
os.path.join(build_dir, self.env['include_subdir']),
update=1,
)
all_kernel_modules = []
for basename in os.listdir(self.env['kernel_modules_source_dir']):
src = os.path.join(self.env['kernel_modules_source_dir'], basename)
if os.path.isfile(src):
noext, ext = os.path.splitext(basename)
if ext == self.env['c_ext']:
all_kernel_modules.append(noext)
if self.env['kernel_modules'] == []:
kernel_modules = all_kernel_modules
else:
kernel_modules = map(lambda x: os.path.splitext(os.path.split(x)[1])[0], self.env['kernel_modules'])
object_files = map(lambda x: x + self.env['obj_ext'], kernel_modules)
if self.env['host']:
build_subdir = self.env['kernel_modules_build_host_subdir']
else:
build_subdir = self.env['kernel_modules_build_subdir']
tool = 'gcc'
gcc = self.get_toolchain_tool(tool)
prefix = gcc[:-len(tool)]
ccache = shutil.which('ccache')
if ccache is not None:
cc = '{} {}'.format(ccache, gcc)
else:
cc = gcc
if self.env['verbose']:
verbose = ['V=1']
else:
verbose = []
if self.env['host']:
linux_dir = os.path.join('/lib', 'modules', platform.uname().release, 'build')
else:
linux_dir = self.env['linux_build_dir']
self.sh.run_cmd(
(
[
'make', LF,
'-j', str(self.env['nproc']), LF,
'ARCH={}'.format(self.env['linux_arch']), LF,
'CC={}'.format(cc), LF,
'CROSS_COMPILE={}'.format(prefix), LF,
'LINUX_DIR={}'.format(linux_dir), LF,
'M={}'.format(build_subdir), LF,
'OBJECT_FILES={}'.format(' '.join(object_files)), LF,
] +
self.sh.shlex_split(self.env['make_args']) +
verbose
),
cwd=os.path.join(self.env['kernel_modules_build_subdir']),
)
if not self.env['host']:
self.sh.copy_dir_if_update_non_recursive(
srcdir=self.env['kernel_modules_build_subdir'],
destdir=self.env['out_rootfs_overlay_lkmc_dir'],
filter_ext=self.env['kernel_module_ext'],
)
def get_build_dir(self):
if self.env['host']:
return self.env['kernel_modules_build_host_dir']
else:
return self.env['kernel_modules_build_dir']
if __name__ == '__main__':
Main().cli()