How to Create a Custom Makefile that Can Build a Linux Kernel Module for a Local or Target Host Device

In this article, we will show how to create a custom makefile that can build a linux kernel module for a local or target host device.
A makefile can be used to build a linux kernel module. It converts a main.c file and creates a main.ko file, which is the file type of a linux kernel module.
If we customize this makefile, we can do a build for either a local host (the computer) or a target host (a microcomputer such as a beaglebone device).
This allows for easy straightforward builds on either on a local environment or a target device.
So, in order to do this, we create a makefile (if you don't already have one) or simply edit the existing makefile if you have one.
This makefile should be in the same directory in which you created the main.c file which contains your linux kernel module source code.
This is shown below.
Within this makefile, we place in the following code.
obj-m := main.o
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
KERN_DIR=/home/david/linux/
HOST_KERN_DIR= /lib/modules/$(shell uname -r)/build/
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) modules
clean:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) clean
help:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) help
host:
make -C $(HOST_KERN_DIR) M=$(PWD) modules
host-clean:
make -C $(HOST_KERN_DIR) M=$(PWD) clean
This Makefile is shown in our terminal below.
So let's now go over this code, so that you understand it.
So the first line makes all the modules built loadable dynamic modules and creates the main.o files (as long as main.ko files).
We then create a number of variables. These aren't mandatory, but it makes our code more modular and simple to read, so this is the reason they're used.
ARCH=arm represents the architecture of our target host.
CROSS_COMPILE=arm-linux-gnueabihf- represents our cross compilation toolchain.
KERN_DIR=/home/david/linux/ reprents the location of our linux source code for the target device.
HOST_KERN_DIR= /lib/modules/$(shell uname -r)/build/
We then have our first target, all
all represents the default selection if make is selected without any additional keywords. all represents the default target when make is used alone
The next target is clean, which cleans the modules directory of all files except for the main.c and the Makefile.
The next target is help, which shows us various commands we can run.
We then have our next target, which is host. This allows us to compile the modules for a build on our local host.
Our last target is host-clean, which cleans all generated files from our host build.
Now we will run these commands in our linux terminal, so that you can see how this Makefile actually operates.
Below we build the linux kernel module for our target host device.
So you can see that with the all target in a Makefile, this signifies that make alone just needs to specified. This will run the build process for the linux kernel module for our target host device.
Next we run the command, make clean, which removes the generated files in the modules directory.
This is shown below.
Next we run the help command from our custom makefile.
The help command operates the same whether the device is local or not, so there was no need to have this command repeated under the host operations.
Next, we go to our host device.
The command, make host, builds our linux kernel module for the host device.
Next we run the command, make host-clean, which removes the generated files in the modules directory created from the host build process.
This is shown below.
So this is how to create a custom makefile that can build a linux kernel module on a local or target host device.
Related Resources