Bug 16075

Summary: Cannot use linux kernel extensions from external tree (building zfs into kernel)
Product: buildroot Reporter: mscdex <mscdex>
Component: OtherAssignee: unassigned
Status: RESOLVED INVALID    
Severity: normal CC: buildroot, yann.morin.1998
Priority: P5    
Version: 2024.02.1   
Target Milestone: ---   
Hardware: All   
OS: Linux   
Host: Target:
Build:

Description mscdex 2024-05-15 06:22:12 UTC
I'm wanting to build zfs into the kernel, so after reading through the documentation it seemed like the best way to go about it would be through Buildroot's Linux kernel extension mechanism.

I already have an existing, working external tree, so according to the documentation I added a `linux/Config.ext.in` and `linux/linux-ext-zfs-inkernel.mk` to my external tree.

Re-running `make menuconfig` and navigating to the Linux Extensions section shows both the built-in Buildroot extensions and my new extension. However, after I select my extension and save the Buildroot configuration, just about every make target except `menuconfig` fails with:

linux/linux.mk:646: *** Package 'linux' defined a second time in 'linux/'; previous definition was in '/home/foo/buildroot-external/linux/'.  Stop.
make: *** [Makefile:23: _all] Error 2

I tried explicitly adding a reference to the Config.ext.in in my external tree's Config.in and adding a reference to the linux-ext-zfs-inkernel.mk in my external tree's external.mk, but that did not make any difference.

For what it's worth here are the contents of the two files (there may be issues with them as I obviously haven't been able to test them yet):

linux/Config.ext.in:
  config BR2_LINUX_KERNEL_EXT_ZFS_INKERNEL
      bool "In-kernel ZFS"
      help
        In-kernel ZFS module

linux/linux-ext-zfs-inkernel.mk:
  ZFS_INKERNEL_VERSION = 2.2.2
  ZFS_INKERNEL_SOURCE = https://github.com/openzfs/zfs/releases/download/zfs-$(ZFS_INKERNEL_VERSION)
  ZFS_INKERNEL_INSTALL_STAGING = NO
  ZFS_INKERNEL_INSTALL_TARGET = NO
  define ZFS_INKERNEL_COPY_BUILTIN
    cd $(ZFS_INKERNEL_BUILDDIR) && ./copy-builtin $(LINUX_DIR)
  endef
  ZFS_INKERNEL_POST_CONFIGURE_HOOKS += ZFS_INKERNEL_COPY_BUILTIN
  LINUX_EXTENSIONS += zfs-inkernel
  ZFS_INKERNEL_CONF_OPTS = \
      --with-linux=$(LINUX_DIR) \
      --enable-linux-builtin
  ZFS_INKERNEL_MAKE = true
  $(eval $(autotools-package))
Comment 1 Arnout Vandecappelle 2024-05-15 16:45:30 UTC
Is it possible that you have `include */*.mk` in your external.mk? This will include your `linux/linux-ext-zfs-inkernel.mk` in the "main" buildroot include, but it should only be included in the linux-extensions-specific section in buildroot linux/linux.mk:

include $(sort $(wildcard $(foreach ext,$(BR2_EXTERNAL_DIRS), \
        $(ext)/linux/linux-ext-*.mk)))
Comment 2 Yann E. MORIN 2024-05-15 19:12:21 UTC
mscdex, All,

You are calling the autotools-package macro in your linux externsion; that
is going to create an actual package, which is what is actually causing you
trouble.

The linux-ext file should be limited exactly to defining the linux extension.

Downloading the sources for the extension should be done in a separate
package.

See for example the fbtft linux extension, which is simple enough to be
a good example.

Regards,
Yann E. MORIN.