Implement minimal depmod-compatible applet for vx

- Added depmod.cpp to scan kernel module ELF files, read .modinfo, and emit metadata files.
- Implemented functionality to write binary trie indexes for libkmod/modprobe.
- Introduced command-line options for module processing.
- Created test script test_depmod.sh to verify help and version commands.
This commit is contained in:
2026-07-08 22:08:15 -05:00
parent 26e2527492
commit bb503eec83
7 changed files with 1355 additions and 2 deletions
+2 -1
View File
@@ -14,6 +14,7 @@ It bundles a growing set of FreeBSD-derived userland tools into a single `vx` bi
- `find` - `find`
- `xargs` - `xargs`
- `lspci`, `setpci` - `lspci`, `setpci`
- `depmod`
## Build ## Build
@@ -47,4 +48,4 @@ or via installed symlinks such as `grep`, `find`, or `patch`.
## Notes ## Notes
- The project force-includes `src/compat-headers/compat.h` to provide Linux compatibility shims for BSD userland code. - The project force-includes `src/compat-headers/compat.h` to provide Linux compatibility shims for BSD userland code.
- Some behavior is intentionally BSD-flavored, even where GNU tools differ. - Some behavior is intentionally BSD-flavored, even where GNU tools differ.
+23 -1
View File
@@ -1,7 +1,8 @@
project('vx', 'c', project('vx', 'c', 'cpp',
version : '0.2.0', version : '0.2.0',
default_options : [ default_options : [
'c_std=c11', 'c_std=c11',
'cpp_std=c++17',
'warning_level=2', 'warning_level=2',
], ],
) )
@@ -19,6 +20,7 @@ all_utils = [
'xargs', 'xargs',
'lspci', 'lspci',
'setpci', 'setpci',
'depmod',
] ]
requested_utils = get_option('utils') requested_utils = get_option('utils')
@@ -45,6 +47,7 @@ enable_find = enabled_utils.contains('find')
enable_xargs = enabled_utils.contains('xargs') enable_xargs = enabled_utils.contains('xargs')
enable_lspci = enabled_utils.contains('lspci') enable_lspci = enabled_utils.contains('lspci')
enable_setpci = enabled_utils.contains('setpci') enable_setpci = enabled_utils.contains('setpci')
enable_depmod = enabled_utils.contains('depmod')
vx_cfg = configuration_data() vx_cfg = configuration_data()
vx_cfg.set10('VX_ENABLE_PATCH', enable_patch) vx_cfg.set10('VX_ENABLE_PATCH', enable_patch)
@@ -59,6 +62,7 @@ vx_cfg.set10('VX_ENABLE_FIND', enable_find)
vx_cfg.set10('VX_ENABLE_XARGS', enable_xargs) vx_cfg.set10('VX_ENABLE_XARGS', enable_xargs)
vx_cfg.set10('VX_ENABLE_LSPCI', enable_lspci) vx_cfg.set10('VX_ENABLE_LSPCI', enable_lspci)
vx_cfg.set10('VX_ENABLE_SETPCI', enable_setpci) vx_cfg.set10('VX_ENABLE_SETPCI', enable_setpci)
vx_cfg.set10('VX_ENABLE_DEPMOD', enable_depmod)
configure_file(output : 'vx-config.h', configuration : vx_cfg) configure_file(output : 'vx-config.h', configuration : vx_cfg)
# --- Portability shim for building BSD userland on Linux --- # --- Portability shim for building BSD userland on Linux ---
@@ -163,6 +167,10 @@ setpci_src = files(
'src/pci/setpci.c', 'src/pci/setpci.c',
) )
depmod_src = files(
'src/depmod/depmod.cpp',
)
pci_inc = include_directories('src/pci') pci_inc = include_directories('src/pci')
gzip_defines = [ gzip_defines = [
@@ -248,6 +256,11 @@ if enable_setpci
vx_sources += setpci_src vx_sources += setpci_src
endif endif
if enable_depmod
vx_sources += depmod_src
vx_dependencies += [dependency('zlib'), dependency('libzstd')]
endif
vx = executable('vx', vx = executable('vx',
vx_sources, vx_sources,
include_directories : vx_include_dirs, include_directories : vx_include_dirs,
@@ -295,6 +308,9 @@ endif
if enable_setpci if enable_setpci
install_applets += ['setpci'] install_applets += ['setpci']
endif endif
if enable_depmod
install_applets += ['depmod']
endif
foreach name : install_applets foreach name : install_applets
meson.add_install_script('sh', '-c', meson.add_install_script('sh', '-c',
@@ -348,6 +364,9 @@ endif
if enable_setpci if enable_setpci
manpages += ['src/pci/setpci.8'] manpages += ['src/pci/setpci.8']
endif endif
if enable_depmod
manpages += ['src/depmod/depmod.8']
endif
install_man(manpages) install_man(manpages)
@@ -409,6 +428,9 @@ endif
if enable_setpci if enable_setpci
test_targets += ['test_setpci'] test_targets += ['test_setpci']
endif endif
if enable_depmod
test_targets += ['test_depmod']
endif
foreach t : test_targets foreach t : test_targets
test(t, find_program('tests/' + t + '.sh'), test(t, find_program('tests/' + t + '.sh'),
+1
View File
@@ -15,6 +15,7 @@ option('utils',
'xargs', 'xargs',
'lspci', 'lspci',
'setpci', 'setpci',
'depmod',
], ],
description : 'Utilities to include in vx (default: all)' description : 'Utilities to include in vx (default: all)'
) )
+69
View File
@@ -0,0 +1,69 @@
.Dd July 8, 2026
.Dt DEPMOD 8
.Os
.Sh NAME
.Nm depmod
.Nd generate Linux kernel module dependency metadata
.Sh SYNOPSIS
.Nm
.Op Fl aAenvwVh
.Op Fl b Ar basedir
.Op Fl m Ar moduledir
.Op Fl o Ar outdir
.Op Fl C Ar config
.Op Fl E Ar Module.symvers
.Op Fl F Ar System.map
.Op Fl P Ar prefix
.Op Ar version
.Op Ar module ...
.Sh DESCRIPTION
The
.Nm
applet scans Linux kernel modules below
.Pa /lib/modules/<version>
and writes the usual module metadata files, including
.Pa modules.dep ,
.Pa modules.alias ,
.Pa modules.symbols ,
and the matching kmod binary index files.
.Pp
This implementation is intentionally small and does not use libkmod. It reads
uncompressed modules plus gzip and zstd compressed modules.
.Sh OPTIONS
.Bl -tag -width Ds
.It Fl a , Fl -all
Scan all modules. This is the default when no module files are named.
.It Fl A , Fl -quick
Exit without regenerating output when
.Pa modules.dep
is newer than the scanned modules.
.It Fl b Ar basedir , Fl -basedir Ns = Ns Ar basedir
Use
.Ar basedir
as the input root.
.It Fl m Ar moduledir , Fl -moduledir Ns = Ns Ar moduledir
Use a module directory other than
.Pa /lib/modules .
.It Fl o Ar outdir , Fl -outdir Ns = Ns Ar outdir
Use
.Ar outdir
as the output root.
.It Fl n , Fl -show , Fl -dry-run
Print text output to standard output instead of writing files.
.It Fl e , Fl -errsyms
Warn about unresolved module dependencies and symbols.
.It Fl P Ar prefix , Fl -symbol-prefix Ns = Ns Ar prefix
Ignore an architecture symbol prefix while matching symbols.
.It Fl V , Fl -version
Print version information.
.It Fl h , Fl -help
Print usage information.
.El
.Sh COMPATIBILITY
The options
.Fl C ,
.Fl E ,
and
.Fl F
are accepted for command-line compatibility, but this implementation does not
parse depmod.d configuration, Module.symvers, or System.map content.
File diff suppressed because it is too large Load Diff
+6
View File
@@ -41,6 +41,9 @@ int lspci_main(int argc, char *argv[]);
#if VX_ENABLE_SETPCI #if VX_ENABLE_SETPCI
int setpci_main(int argc, char *argv[]); int setpci_main(int argc, char *argv[]);
#endif #endif
#if VX_ENABLE_DEPMOD
int depmod_main(int argc, char *argv[]);
#endif
struct applet { struct applet {
const char *name; const char *name;
@@ -91,6 +94,9 @@ static const struct applet applets[] = {
#if VX_ENABLE_SETPCI #if VX_ENABLE_SETPCI
{ "setpci", setpci_main }, { "setpci", setpci_main },
#endif #endif
#if VX_ENABLE_DEPMOD
{ "depmod", depmod_main },
#endif
}; };
static const size_t n_applets = sizeof(applets) / sizeof(applets[0]); static const size_t n_applets = sizeof(applets) / sizeof(applets[0]);
+4
View File
@@ -0,0 +1,4 @@
#!/bin/sh
set -eu
"$VX" depmod --help >/dev/null
"$VX" depmod --version >/dev/null