From: Thomas Walker Lynch Date: Thu, 16 Oct 2025 14:18:00 +0000 (+0000) Subject: kmod build environment X-Git-Url: https://git.reasoningtechnology.com/style/%7Bstyle.link%7D?a=commitdiff_plain;h=f9a2e04cb2518f4d94c0fa8e5443560454fe86d6;p=RT-project-share kmod build environment --- diff --git a/developer/bash/git-tar b/developer/bash/git-tar index 85723df..ec2b6eb 100755 --- a/developer/bash/git-tar +++ b/developer/bash/git-tar @@ -31,7 +31,7 @@ stamp="$(Z)" stamp="${stamp//$'\n'/}" mkdir -p "${repo_top}/scratchpad" -out="${repo_top}/scratchpad/${repo_name}_${ref_label}_${stamp}.tar.gz" +out="${repo_top}/scratchpad/${repo_name}__${ref_label}__${stamp}.tar.gz" # 4) create archive of HEAD (tracked files only; .gitignore’d stuff omitted) git -C "$repo_top" archive --format=tar --prefix="${repo_name}/" HEAD | gzip > "$out" diff --git a/developer/make/environment_RT_1.mk b/developer/make/environment_RT_1.mk new file mode 100644 index 0000000..aaeb95c --- /dev/null +++ b/developer/make/environment_RT_1.mk @@ -0,0 +1,24 @@ +# makefile environment variable defaults. +# cc is the name of the C compiler +# .c is C source code. + +SHELL=/bin/bash + +#ECHO= echo -e +#ECHO= echo +ECHO := printf "%b\n" + + +# sources found in these subdirectories: +SRCDIR_List=cc + +LIBDIR=scratchpad +EXECDIR=machine +SCRATCHPAD=scratchpad + +LIBFILE=$(SCRATCHPAD)/lib.a + +C=gcc +CFLAGS=-std=gnu11 -Wall -Wextra -Wpedantic -finput-charset=UTF-8 +CFLAGS += -MMD -MP +LINKFLAGS=-L$(LIBDIR) -L/lib64 -L/lib diff --git a/developer/make/target_kmod.mk b/developer/make/target_kmod.mk new file mode 100644 index 0000000..c2c7968 --- /dev/null +++ b/developer/make/target_kmod.mk @@ -0,0 +1,38 @@ +# make/targets_kmod.mk +# make a Linux kernel module + +ifndef REPO_HOME + $(error REPO_HOME is not set; build must be done in a project environment) +endif + +KBUILD_BASE_List := $(basename $(notdir $(wildcard $(REPO_HOME)/developer/cc/*.mod.c))) +KMOD_BUILD_DPath := /lib/modules/$(shell uname -r)/build +KBUILD_OUTPUT_DIR := $(REPO_HOME)/$(SCRATCHPAD) + +# Basenames → kbuild objects and final .ko targets in scratchpad +KERNEL_OBJS_M := $(addsuffix .o, $(KBUILD_BASE_List)) +KMOD_TARGETS := $(addsuffix .ko, $(addprefix $(KBUILD_OUTPUT_DIR)/, $(KBUILD_BASE_List))) + +.PHONY: usage +usage: + @printf "Usage: make [usage|kmod|clean]\n"; exit 2 + +# Build every module +.PHONY: kmod +kmod: $(KMOD_TARGETS) + +# Link each module via kbuild (M points at project root) +$(KBUILD_OUTPUT_DIR)/%.ko: $(KBUILD_OUTPUT_DIR)/%.c + @echo "--- Invoking Kbuild for Module: $* ---" + $(MAKE) -C $(KMOD_BUILD_DPath) M=$(REPO_HOME) O=$(KBUILD_OUTPUT_DIR) obj-m=$*.o + +# Prepare kbuild-compatible .c in scratchpad from authored .mod.c in developer/cc +$(KBUILD_OUTPUT_DIR)/%.c: $(REPO_HOME)/developer/cc/%.mod.c + @echo "--- Preparing Kbuild Source: $@ ---" + cp $< $@ + +# Clean kbuild artifacts (confined to scratchpad) +.PHONY: clean +clean: + @echo "--- Cleaning Kbuild Artifacts in $(KBUILD_OUTPUT_DIR) ---" + $(MAKE) -C $(KMOD_BUILD_DPath) M=$(REPO_HOME) O=$(KBUILD_OUTPUT_DIR) obj-m="$(KERNEL_OBJS_M)" clean diff --git a/developer/make/target_lib_cli.mk b/developer/make/target_lib_cli.mk new file mode 100644 index 0000000..cba5bcf --- /dev/null +++ b/developer/make/target_lib_cli.mk @@ -0,0 +1,105 @@ +.SUFFIXES: + +#-------------------------------------------------------------------------------- +# files have two suffixes by convention, e.g.: X.lib.c or Y.cli.c +# + +# bail early if there is no compiler +ifeq ($(C),) + $(error No C compiler specified.) +endif + +# keep only the source directories that are in the file system +SRCDIR_List := $(wildcard $(SRCDIR_List)) + +# bail early if the SRCDIR_list is empty +ifeq ($(SRCDIR_List),) + $(error source directory found so nothing to do) +endif + +# duplicate source file names in different directories will cause +# problems with this makefile + +C_SOURCE_LIB := $(foreach dir, $(SRCDIR_List), $(wildcard $(dir)/*.lib.c)) +C_SOURCE_EXEC := $(foreach dir, $(SRCDIR_List), $(wildcard $(dir)/*.cli.c)) + +#remove the suffix to get base name +C_BASE_LIB= $(sort $(patsubst %.lib.c, %, $(notdir $(C_SOURCE_LIB)))) +C_BASE_EXEC= $(sort $(patsubst %.cli.c, %, $(notdir $(C_SOURCE_EXEC)))) + +# two sets of object files, one for the lib, and one for the command line interface progs +OBJECT_LIB= $(patsubst %, $(SCRATCHPAD)/%.lib.o, $(C_BASE_LIB)) +OBJECT_EXEC= $(patsubst %, $(SCRATCHPAD)/%.cli.o, $(C_BASE_EXEC)) + +-include $(OBJECT_LIB:.o=.d) $(OBJECT_EXEC:.o=.d) + +# executables are made from EXEC sources +EXEC= $(patsubst %, $(EXECDIR)/%, $(C_BASE_EXEC)) + +# the new C programming style gated sections in source instead of header filesheader +INCFLAG_List := $(foreach dir, $(SRCDIR_List), -I $(dir)) +CFLAGS += $(INCFLAG_List) + +#-------------------------------------------------------------------------------- +# targets + +# when no target is given make uses the first target, this one +.PHONY: usage +usage: + @echo example usage: make clean + @echo example usage: make library + @echo example usage: make cli + @echo example usage: make library cli + +.PHONY: version +version: + @echo makefile version 7.1 + if [ ! -z "$(C)" ]; then $(C) -v; fi + /bin/make -v + +.PHONY: information +information: + @printf "· → Unicode middle dot — visible: [%b]\n" "·" + @echo "SRCDIR_List: " $(SRCDIR_List) + @echo "C_SOURCE_LIB: " $(C_SOURCE_LIB) + @echo "C_SOURCE_EXEC: " $(C_SOURCE_EXEC) + @echo "C_BASE_LIB: " $(C_BASE_LIB) + @echo "C_BASE_EXEC: " $(C_BASE_EXEC) + @echo "OBJECT_LIB: " $(OBJECT_LIB) + @echo "OBJECT_EXEC: " $(OBJECT_EXEC) + @echo "EXEC: " $(EXEC) + @echo "INCFLAG_List: " $(INCFLAG_List) + +.PHONY: library +library: $(LIBFILE) + +#$(LIBFILE): $(OBJECT_LIB) $(DEPFILE) +$(LIBFILE): $(OBJECT_LIB) + ar rcs $(LIBFILE) $(OBJECT_LIB) + + +.PHONY: cli +#cli: $(LIBFILE) $(DEPFILE) +cli: $(LIBFILE) + make sub_cli + +.PHONY: sub_cli +sub_cli: $(EXEC) + +# generally better to use the project local clean scripts, but this will make it so that the make targets can be run again + +.PHONY: clean +clean: + rm -f $(LIBFILE) + for obj in $(OBJECT_LIB) $(OBJECT_EXEC); do rm -f $$obj $${obj%.o}.d || true; done + for i in $(EXEC); do [ -e $$i ] && rm $$i || true; done + + +# recipes +vpath %.c $(SRCDIR_List) +$(SCRATCHPAD)/%.o: %.c + $(C) $(CFLAGS) -o $@ -c $< + +$(EXECDIR)/%: $(SCRATCHPAD)/%.cli.o $(LIBFILE) + $(C) -o $@ $< $(LIBFILE) $(LINKFLAGS) + diff --git a/developer/make/targets_developer b/developer/make/targets_developer index 32b6be1..6576cd1 100644 --- a/developer/make/targets_developer +++ b/developer/make/targets_developer @@ -1,3 +1,6 @@ +# This has been deprecated in favor of target_lib_cli.mk. +# It is still here for backwards compatibility but will be going away soon. +# .SUFFIXES: #-------------------------------------------------------------------------------- @@ -106,8 +109,8 @@ sub_cli: $(EXEC) # generally better to use the project local clean scripts, but this will make it so that the make targets can be run again -.PHONY: clean_developer -clean_developer: +.PHONY: clean +clean: rm -f $(DEPFILE) $(LIBFILE) for obj in $(OBJECT_LIB) $(OBJECT_EXEC); do rm -f $$obj || true; done for i in $(EXEC); do [ -e $$i ] && rm $$i || true; done diff --git a/developer/make/targets_kernel b/developer/make/targets_kernel deleted file mode 100644 index 065fc8f..0000000 --- a/developer/make/targets_kernel +++ /dev/null @@ -1,60 +0,0 @@ -# targets_kernel - -# KBUILD ABSTRACTION -# -# Assumes the following variables are defined by the project's tool/makefile: -# KBUILD_BASE_List: The basenames of all kernel modules (e.g. 'rabbit_module_no-op'). -# PWD: Project root directory. -# TMPDIR: Shared scratchpad directory for all output. - -KDIR := /lib/modules/$(shell uname -r)/build -# Use KBUILD_OUTPUT_DIR to direct Kbuild output to the scratchpad - -# PATH CORRECTION: Define REPO_ROOT (the Rabbit/ directory) relative to the shell's PWD. -# Assuming PWD is the developer/ directory, REPO_ROOT is the parent directory. -REPO_ROOT := $(dir $(PWD)) - -# The scratchpad directory is relative to the REPO_ROOT, not the execution directory. -KBUILD_OUTPUT_DIR := $(REPO_ROOT)/$(TMPDIR) - -# Convert KBUILD_BASE_List (e.g. "no-op") into Kbuild-compatible object list (e.g. "no-op.o") -KERNEL_OBJS_M := $(addsuffix .o, $(KBUILD_BASE_List)) - -# KERNEL_MODULE_TARGETS holds the full, scratchpad-prefixed path to the final .ko files -KERNEL_MODULE_TARGETS := $(addsuffix .ko, $(addprefix $(KBUILD_OUTPUT_DIR)/, $(KBUILD_BASE_List))) - -.PHONY: kernel_module clean_kernel - -# PRIMARY KERNEL BUILD TARGET -# -# The 'kernel_module' target builds all final .ko files. -kernel_module: $(KERNEL_MODULE_TARGETS) - -# --- Implicit Rule to Compile a Single Module --- -# Target: The final .ko file in the scratchpad (e.g. scratchpad/rabbit_module_no-op.ko) -# Dependency: The temporary Kbuild source file (e.g. scratchpad/rabbit_module_no-op.c) -$(KBUILD_OUTPUT_DIR)/%.ko: $(KBUILD_OUTPUT_DIR)/%.c - @echo "--- Invoking Kbuild for Module: $* ---" - # M=$(REPO_ROOT): Tells Kbuild to look for source (cc/) relative to the project root, - # which is the directory containing the 'developer/' directory. - # O=$(KBUILD_OUTPUT_DIR): tells Kbuild where to place ALL output (scratchpad/). - $(MAKE) -C $(KDIR) M=$(REPO_ROOT) O=$(KBUILD_OUTPUT_DIR) \ - obj-m=$*.o - -# --- Rule to Create Kbuild-Compatible Source Link --- -# Kbuild expects a .c file, but our source is .mod.c and is read-only in cc/. -# Action: Copy the read-only source file to the scratchpad under the expected Kbuild name (.c). -$(KBUILD_OUTPUT_DIR)/%.c: $(REPO_ROOT)/cc/%.mod.c - @echo "--- Preparing Kbuild Source Link: $@ ---" - cp $< $@ - -# Ensure 'all' calls the kernel compilation -all: kernel_module - -# --- Callable Kernel Module Cleanup Target --- -# This target ensures that only the artifacts created by Kbuild are cleaned from the scratchpad. -clean_kernel: - @echo "--- Cleaning Kbuild Artifacts for Modules in $(KBUILD_OUTPUT_DIR) ---" - # M=$(REPO_ROOT): We use the correct project root again for Kbuild to find its context. - $(MAKE) -C $(KDIR) M=$(REPO_ROOT) O=$(KBUILD_OUTPUT_DIR) \ - obj-m="$(KERNEL_OBJS_M)" clean