Trying to compile a kernel module with the Yocto SDK toolchain. Using CMakeLists inside CLion with ExternalProject_Add directive.
Makefile:
# Makefile for uio48
ifneq ($(KERNELRELEASE),) # called by kbuild
obj-m := uio48.o
else # called from command line
KERNEL_VERSION = `uname -r`
KERNELDIR := /lib/modules/$(KERNEL_VERSION)/build
PWD := $(shell pwd)
MODULE_INSTALLDIR = /lib/modules/$(KERNEL_VERSION)/kernel/drivers/gpio/
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
uio48io.o: uio48io.c uio48.h Makefile
#gcc -c $(EXTRA_CFLAGS) uio48io.c
$(CC) -c $(EXTRA_CFLAGS) uio48io.c
libuio48io.a: uio48io.o
ar rcs libuio48io.a uio48io.o
libs: libuio48io.a
all: default libs
install:
#mkdir -p ${PREFIX}/$(MODULE_INSTALLDIR)
#rm -f $(MODULE_INSTALLDIR)uio48.ko
#install -c -m 0644 ${PREFIX}/lib/modules/${KERNEL_VERSION}/extra/uio48.ko ${PREFIX}/$(MODULE_INSTALLDIR)
#install -m 0755 ${PREFIX}flash ${D}${bindir}
#/sbin/depmod -a
uninstall:
rm -f $(MODULE_INSTALLDIR)uio48.ko
/sbin/depmod -a
flash: flash.c uio48.h uio48io.o Makefile
#gcc -static flash.c uio48io.o -o flash
$(CC) flash.c uio48io.o -o flash
chmod a+x flash
diotest: diosetpintest.c uio48.h uio48io.o Makefile
#gcc -static flash.c uio48io.o -o flash
${CC} diosetpintest.c uio48io.o -o diotest
chmod a+x diotest
poll: poll.c uio48.h uio48io.o Makefile
#gcc -D_REENTRANT -static poll.c uio48io.o -o poll -lpthread
${CC} -D_REENTRANT -static poll.c uio48io.o -o poll -lpthread
chmod a+x poll
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions /dev/uio48?
spotless:
rm -rf ioctl poll flash Module.* *.o *~ core .depend .*.cmd *.ko *.mod.c *.order .tmp_versions /dev/uio48?
As you can see I've already modified the make file provided by the vendor. I replaced some build lines with $(CC) to make sure it uses the toolchain compiler. Commented out the Install section because I couldn't figure out how to stop CMake ExternalProject from running the install command; just want to build it.
CMakeLists.txt:
project(driver)
cmake_minimum_required(VERSION 3.17)
enable_language(C ASM CXX)
set(CMAKE_CXX_STANDARD 11)
set(SHARED_LIBRARY_ROOT "$ENV{OECORE_TARGET_SYSROOT}/usr/lib")
set(SHARED_LIBRARY_INCLUDE "$ENV{OECORE_TARGET_SYSROOT}/usr/include")
set(CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} $ENV{OECORE_NATIVE_SYSROOT} )
set(TARGET_PLATFORM_INCLUDE "$ENV{OECORE_TARGET_SYSROOT}/usr/src/kernel/include/linux")
set(TARGET_KERNEL_DIR "$ENV{OECORE_TARGET_SYSROOT}/usr/src/kernel")
set(TP_INCLUDE_CFLAG "-I${TARGET_PLATFORM_INCLUDE} -I${SHARED_LIBRARY_INCLUDE}")
MESSAGE(STATUS "CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}")
MESSAGE(STATUS "TARGET_PLATFORM_INCLUDE ${TARGET_PLATFORM_INCLUDE}")
MESSAGE(STATUS "CMake C compiler ${CMAKE_C_COMPILER}")
include_directories(${CMAKE_CURRENT_LIST_DIR})
include_directories(${SHARED_LIBRARY_ROOT})
include_directories(${SHARED_LIBRARY_INCLUDE})
include(ExternalProject)
ExternalProject_Add(
uio48
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND make all CC=${CMAKE_C_COMPILER} KERNEL_DIR=${TARGET_KERNEL_DIR} EXTRA_CFLAGS=${TP_INCLUDE_CFLAG}
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
BUILD_IN_SOURCE 1
BUILD_ALWAYS 1)
If I leave The Makefile the way it is, I can see from the output I am changing directory to my host kernel source. partial output:
make[5]: Entering directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
Building modules, stage 2.
MODPOST 1 modules
make[5]: Leaving directory `/usr/src/kernels/3.10.0-957.el7.x86_64'
so I modified these lines in the make file:
#ifneq ($(KERNELRELEASE),) # called by kbuild
# obj-m := uio48.o
#else # called from command line
KERNEL_VERSION = `uname -r`
KERNELDIR := /lib/modules/$(KERNEL_VERSION)/build
PWD := $(shell pwd)
MODULE_INSTALLDIR = /lib/modules/$(KERNEL_VERSION)/kernel/drivers/gpio/
When I do this, I change directory into my kernel source in the toolchain as the output shows, however...:
ake[5]: Entering directory `/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/src/kernel'
Building modules, stage 2.
MODPOST 0 modules
make[5]: Leaving directory `/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/src/kernel'
#gcc -c -I/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/src/kernel/include/linux -I/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/include uio48io.c
/opt/poky-sdk/2.4.2/sysroots/x86_64-pokysdk-linux/usr/bin/x86_64-poky-linux/x86_64-poky-linux-gcc -c -I/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/src/kernel/include/linux -I/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/include uio48io.c
In file included from /opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/include/stdio.h:33:0,
from uio48io.c:35:
/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/src/kernel/include/linux/stddef.h:4:10: fatal error: uapi/linux/stddef.h: No such file or directory
#include <uapi/linux/stddef.h>
^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
now i'm getting an error for a missing header file that is an include from another Linux kernel header file.
After searching for the 'uapi', it shows up under different architectures in the source; ./usr/src/kernel/tools/arch/powerpc/include/uapi for example. so, Im guessing i need to specify the arch in order for it to include the right header but I'm not having any luck.
I tried adding: -march=x86-64 here:
set(TP_INCLUDE_CFLAG "-I${TARGET_PLATFORM_INCLUDE} -I${SHARED_LIBRARY_INCLUDE} -march=x86-64")
.
.
.
BUILD_COMMAND make all CC=${CMAKE_C_COMPILER} KERNELDIR=${TARGET_KERNEL_DIR} EXTRA_CFLAGS=${TP_INCLUDE_CFLAG}
but that didn't seem to work. Any ideas?
UPDATE if I include the 'uapi' directory, it solves one problem and spawns another. Now I'm getting errors from the linux header files themselves...
example:
set(TARGET_KERNEL_DIR "$ENV{OECORE_TARGET_SYSROOT}/usr/src/kernel")
set(TARGET_PLATFORM_INCLUDE "$ENV{OECORE_TARGET_SYSROOT}/usr/src/kernel/include/linux")
set(TARGET_ARCH_DIR_INCLUDE "$ENV{OECORE_TARGET_SYSROOT}/usr/src/kernel/include/uapi/linux/")
set(USER_INCLUDE "$ENV{OECORE_TARGET_SYSROOT}/usr/include")
set(TP_INCLUDE_CFLAG "-I${TARGET_ARCH_DIR_INCLUDE} -I${TARGET_PLATFORM_INCLUDE} -I${USER_INCLUDE}")
.
.
.
BUILD_COMMAND make all CC=${CMAKE_C_COMPILER} KERNELDIR=${TARGET_KERNEL_DIR} EXTRA_CFLAGS=${TP_INCLUDE_CFLAG}
one of these errors for example:
n file included from /opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/include/stdio.h:41:0,
from uio48io.c:35:
/opt/poky-sdk/2.4.2/sysroots/corei7-64-poky-linux/usr/include/libio.h:302:3: error: unknown type name ‘size_t’
size_t __pad5;
^~~~~~