With Yocto 1.8 (fido), I am using a simple yocto recipe to run a Makefile.
SUMMARY = "PCI kernel module"
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://COPYING;md5=4a0f8ad6a793571b331b0e19e3dd925c"
inherit module
PR = "r0"
PV = "1.0"
SRC_URI = "file://Makefile \
file://COPYING \
file://code.c \
file://code.h \
"
S = "${WORKDIR}"
And here is the Makefile.
obj-m := code.o
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
When running bitbake on this recipe, I get the following compilation errors.
error: no include path in which to search for stdint.h
| # include_next <stdint.h>
| ^
How do I configure this recipe to include gcc when compiling?
What does does your code.c look like?
You can't use userspace headers in a module, and as far as I know, stdint.h is header from userspace.
i think that is toolchain problem
if your files are .c file use ${CC} in make file to compile in yocto.
files are .cpp use ${CXX} in make file
then it will compile with yocto default toolchain
Related
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;
^~~~~~
I am not able to compile the following kernel module https://github.com/Freescale/kernel-module-imx-gpu-viv/tree/upstream/6.2.4.p1.2/kernel-module-imx-gpu-viv-src for my IMX6Q board.
What i have done so far is :
Downloaded the sources from the git repo above in a separate directory
Modified the Makefile to set the correct path to the kernel sources KERNEL_SRC i am building (3.14.52) with :
Makefile :
obj-m := galcore.o
SRC := $(shell pwd)
KERNEL_SRC := /path/to/kernel_imx/
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)/kernel-module-imx-gpu-viv-src AQROOT=${PWD}/kernel-module-imx-gpu-viv-src
cp $(SRC)/kernel-module-imx-gpu-viv-src/Module.symvers $(PWD)
cp $(SRC)/kernel-module-imx-gpu-viv-src/modules.order $(PWD)
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC)/kernel-module-imx-gpu-viv-src modules_install
clean:
rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -f Module.markers Module.symvers modules.order
rm -rf .tmp_versions Modules.symvers
compiled with : make ARCH=arm CROSS_COMPILE=/path/to/buildroot/buildroot/output/host/usr/bin/arm-linux-gnueabihf-
As a result of the compilation, i have no galcore.ko at all, only those 3 files generated :
built-in.o
modules.order ( empty )
Module.symvers ( empty )
I have tried also using buildroot but in the end, i have the same files in the directory output/build/kernel-module-imx-gpu-viv-9bbacfe7753626956a449c6a4f7dffcf6285b4d7
Thanks.
There is already a Buildroot package for this kernel driver: https://git.buildroot.org/buildroot/tree/package/freescale-imx/kernel-module-imx-gpu-viv
Finally i forgot to set MXC_GPU_VIV=m in the kernel configuration, that means to compile this driver as a module.
Now i have the expected galcore.ko correctly built.
i want to use iostream or stdlib.h in my linux kernel driver and i have this MakeFile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
.PHONY: build clean
build:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
else
$(info Building with KERNELRELEASE = ${KERNELRELEASE})
obj-m := mydev.o
endif
when i use #include in my driver code, make returns this
mydev.c:10:20: fatal error: iostream: No such file or directory
#include <iostream>
what should i add to my makefile?
iostream is a C++ header. The Kernel is written in C
This is my makefile:
ifneq ($(KERNELRELEASE),)
obj-m := dmcdus_dd.o
else
KDIR := /usr/src/linux-headers-3.13.0-24-generic/
all:
$(MAKE) INSTALL_MOD_DIR=kernel/drivers/input/touchscreen -C $(KDIR) M=$$PWD modules_install
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions sample Module.symvers
I have specified my required path where i have to move my dmcdus_dd.ko file using INSTALL_MOD_DIR & install it by modules_install. When i type "make" in the console i get the following results in the console:
make INSTALL_MOD_DIR=kernel/drivers/input/touchscreen -C /usr/src/linux-headers-3.5.0-49-generic/ M=$PWD modules_install
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-49-generic'
DEPMOD 3.5.0-49-generic
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-49-generic'
But when i go to the location "/lib/modules/3.5.0-49-generic/kernel/drivers/input/touchscreen" i dont see dmcdus.ko file in that directory... How can i copy my driver to that location?
Before installing first you need to make module using make -C $(KDIR) M=$(PWD) modules.
If you want to make little change in your makefile then write in following way:
ifneq ($(KERNELRELEASE),)
obj-m := dmcdus_dd.o
else
KDIR := /usr/src/linux-headers-3.13.0-24-generic/
all:
make -C $(KDIR) M=$(PWD) modules #I've changed makefile here
$(MAKE) INSTALL_MOD_DIR=kernel/drivers/input/touchscreen -C $(KDIR) M=$$PWD modules_install
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions sample Module.symvers
And make sure that you have permission to copy file to destination (/input/touchscreen)folder. If not then change it.
The below makefile is sufficient for you to build and install module
obj-m := dmcdus_dd.o
KDIR := /usr/src/linux-headers-3.13.0-24-generic/
all:
make -C $(KDIR) M=$$PWD modules
make -C $(KDIR) M=$$PWD modules_install
clean:
make -C $(KDIR) M=$$PWD clean
If you specify INSTALL_MOD_DIR then the modules is moved to that directory
make INSTALL_MOD_DIR=kernel/drivers/input/touchscreen -C $(KDIR) M=$$PWD modules_install
I'm trying to create a generic makefile to build static libraries that my project uses. I've used the expertise on this site, as well as the GNU Make manual to help write the following makefile. It is working well apart from one annoying problem.
# Generic makefile to build/install a static library (zlib example)
ARCH = linux
CFLAGS = -O3 -Wall
# List of source code directories
SOURCES = src test utils
# List of header files to install
INCLUDES = src/zlib.h src/zconf.h
# Library to create
LIBNAME = libz.a
############################################################
BUILD_DIR = build/$(ARCH)
# Full path to the built library
TARGET = $(BUILD_DIR)/$(LIBNAME)
prefix = ../..
exec_prefix = prefix
libdir = $(prefix)/lib/$(ARCH)
includedir = $(prefix)/include
INSTALL_PROGRAM = install -D
INSTALL_DATA = $(INSTALL_PROGRAM) -m 644
CFILES := $(foreach dir,$(SOURCES),$(wildcard $(dir)/*.c))
OBJECTS := $(addprefix $(BUILD_DIR)/,$(CFILES:.c=.o))
DEPENDS := $(OBJECTS:.o=.d)
.PHONY: all installdirs install uninstall clean
# Default
all: $(DEPENDS) $(TARGET)
# Build the dependency files
# (GNU Make Manual 4.14 Generating Prerequisites Automatically)
$(BUILD_DIR)/%.d: $(BUILD_DIR)
#echo "build dep for $*.c as $#"
#$(CC) -M $(CFLAGS) $*.c > $#.tmp
#sed s~.*:~"$(BUILD_DIR)/$*.o $#:"~ $#.tmp > $#
#rm $#.tmp
# Link all changed object files into static library
$(TARGET): $(OBJECTS)
$(AR) -rc $(TARGET) $?
# Compile C source to object code
$(BUILD_DIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
# Create the necessary directory tree for the build
$(BUILD_DIR):
#for p in $(SOURCES); do mkdir -p $(BUILD_DIR)/$$p; done
# Create the necessary directory tree for installation
installdirs:
#mkdir -p $(libdir)
#mkdir -p $(includedir)
# Install the library and headers
install: all installdirs
$(INSTALL_DATA) $(TARGET) $(libdir)
for p in $(INCLUDES); do $(INSTALL_DATA) $$p $(includedir); done
# Remove the library and headers
uninstall:
rm -f $(libdir)/$(LIBNAME)
for p in $(notdir $(INCLUDES)); do rm -f $(includedir)/$$p; done
# Remove all build files
clean:
rm -fr $(BUILD_DIR)
# Pull in the dependencies if they exist
# http://scottmcpeak.com/autodepend/autodepend.html
-include $(DEPENDS)
The problem is that the dependency files are built when they don't need to be. e.g. make install shown below rebuilds the .d files before installing.
$make --version
GNU Make 3.81
$make
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
...
{ continues on making the other .d files, then the .o files }
...
cc -O3 -Wall -c src/zutil.c -o build/linux/src/zutil.o
cc -O3 -Wall -c test/test.c -o build/linux/test/test.o
cc -O3 -Wall -c utils/utils.c -o build/linux/utils/utils.o
ar rc { ... .o files ... }
All good up to this point! But a 'make install' now will rebuild the .d files
$make install
build dep for utils/utils.c as build/linux/utils/utils.d
build dep for test/test.c as build/linux/test/test.d
build dep for src/zutil.c as build/linux/src/zutil.d
{ ... }
install -D -m 644 build/linux/libz.a ../../lib/linux
for p in src/zlib.h src/zconf.h; do install -D -m 644 $p ../../include; done
I tried to 'touch' the .d files when the objects are built, so the update time is newer than the .o files, but that had no effect. What's wrong with my makefile?
The problem is that you include the dependency files (whatever.d), and you also have a rule for building these files. So every time you use this makefile, no matter what target you specify, it will rebuild them, include them, and execute again.
Try this for an approach to dependency handling that solves this problem. Basically, you don't need a separate rule for foo.d, just make it a side effect of the foo.o rule (it takes some thought to realize that this will work).