Search code examples
cmakefilelinux-kernelkernel-modulekbuild

disable a KBUILD_CFLAGS option when making a driver


I'm attempting to compile this UART -> USB driver from silicon labs. It has only been tested on Ubuntu version 18.04 (Bionic) and my machine is running on 21.10 (Impish). Apparently one of the differences is that the newest version enables strict pointer conversion checking when building kernel modules:

/lib/modules/$(uname -r)/build/Makefile

# enforce correct pointer usage
KBUILD_CFLAGS   += $(call cc-option,-Werror=incompatible-pointer-types)

I am wondering if there is a way to disable that particular flag as it prevents me from compiling the driver. I get the error:

.../vcp_driver_source/Linux_3.x.x_4.x.x_VCP_Driver_Source/cp210x.c:290:35: error: initialization of ‘void (*)(struct usb_serial_port *)’ from incompatible pointer type ‘int (*)(struct usb_serial_port *)’ [-Werror=incompatible-pointer-types]
  290 |         .port_remove            = cp210x_port_remove,
      |                                   ^~~~~~~~~~~~~~~~~~
.../vcp_driver_source/Linux_3.x.x_4.x.x_VCP_Driver_Source/cp210x.c:290:35: note: (near initialization for ‘cp210x_device.port_remove’)
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:277: .../vcp_driver_source/Linux_3.x.x_4.x.x_VCP_Driver_Source/cp210x.o] Error 1
make[1]: *** [Makefile:1874: .../vcp_driver_source/Linux_3.x.x_4.x.x_VCP_Driver_Source] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.15.23-76051523-generic'
make: *** [Makefile:7: all] Error 2

The Makefile is very simple and I can change it as needed

Makefile

obj-m = cp210x.o
KDIR = /lib/modules/`uname -r`/build
SRCDIR = $(PWD)
# try this instead if you don't have PWD defined
# SRCDIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
all:
    $(MAKE) -C $(KDIR) M=$(SRCDIR) modules
clean:
    $(MAKE) -C $(KDIR) M=$(SRCDIR) clean

Solution

  • Adding the following to the top of the makefile fixed the problem

    ccflags-y := -Wno-error=incompatible-pointer-types
    

    From the linux kernel documentation I was able to find

    --- 3.7 Compilation flags

    ccflags-y, asflags-y and ldflags-y These three flags apply only to the kbuild makefile in which they are assigned. They are used for all the normal cc, as and ld invocations happening during a recursive build. Note: Flags with the same behaviour were previously named: EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS. They are still supported but their usage is deprecated.

    ccflags-y specifies options for compiling with $(CC).

    Example:

    ccflags-y            := -Os -D_LINUX -DBUILDING_ACPICA
    ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
    

    This variable is necessary because the top Makefile owns the variable $(KBUILD_CFLAGS) and uses it for compilation flags for the entire tree.

    After that is was just a matter of finding the correct gcc flag. Thankfully gcc provides a way to unset the -Werror flag with -Wno-error. Setting that overrides the default behavior and allows the compilation to work without issue.