# Need help debugging Kconfig recursive dependencies

**URL:** <https://forum.openwrt.org/t/need-help-debugging-kconfig-recursive-dependencies/240617>\
**Category:** For Developers\
**Created:** [September 14, 2025, 8:37pm UTC](https://forum.openwrt.org/t/need-help-debugging-kconfig-recursive-dependencies/240617 "2025-09-14T20:37:58Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alphix](https://forum.openwrt.org/user_avatar/forum.openwrt.org/alphix/32/90662_2.png) [@Alphix](https://forum.openwrt.org/u/Alphix)\
**Post date:** [September 14, 2025, 8:37pm UTC](https://forum.openwrt.org/t/need-help-debugging-kconfig-recursive-dependencies/240617/1 "2025-09-14T20:37:58Z")

</div>

So, I’m trying to update the `bind` package to support building with `gssapi` as a variant instead of it being a compile-time option.

A first stab at this is [here](https://github.com/Alphix/packages/commits/bind-gssapi-variant/), with the most important part being the [Makefile](https://github.com/Alphix/packages/blob/bind-gssapi-variant/net/bind/Makefile). To illustrate the problem I’m facing, consider the definition of `bind-tools`:

```plaintext
define Package/bind-tools
  $(Package/bind/Default)
  TITLE+= administration tools (all)
  DEPENDS:= \
	+bind-check \
	+bind-delv \
	+bind-dig \
	+bind-nslookup \
	+bind-dnssec \
	+bind-host \
	+bind-rndc \
	+bind-ddns-confgen
endef

```

Now, each package (like `bind-nslookup`) comes in two flavours with my patches: `bind-nslookup` and `bind-nslookup-gssapi`. This is modelled after e.g. [ethtool](https://github.com/openwrt/openwrt/blob/main/package/network/utils/ethtool/Makefile) which has a Makefile like this:

```plaintext
define Package/ethtool
  SECTION:=net
  CATEGORY:=Network
  TITLE:=Display or change ethernet card settings
  URL:=http://www.kernel.org/pub/software/network/ethtool/
  VARIANT:=tiny
  CONFLICTS:=ethtool-full
endef

define Package/ethtool-full
  $(Package/ethtool)
  TITLE += (full)
  VARIANT:=full
  PROVIDES:=ethtool
  DEPENDS:=+libmnl
  CONFLICTS:=
endef

```

This allows packages to depend on `ethtool` and it’ll be satisfied by `ethtool` or `ethtool-full`

So, returning to e.g. `bind-nslookup` from my branch, the relevant part of the `Makefile` looks like this:

```plaintext
define Package/bind-nslookup
  $(Package/bind/Default)
  TITLE+= tools (nslookup)
  ALTERNATIVES:= \
	  200:/usr/bin/nslookup:/usr/libexec/nslookup-bind
  CONFLICTS:=bind-nslookup-gssapi
endef

define Package/bind-nslookup-gssapi
  $(Package/bind-gssapi/Default)
  TITLE+= tools (nslookup) with GSSAPI
  ALTERNATIVES:= \
	  200:/usr/bin/nslookup:/usr/libexec/nslookup-bind
  PROVIDES:=bind-nslookup
endef

```

And that works as expected, the relevant parts of `tmp/.config-package.in` ends up looking like this:

```plaintext
        config PACKAGE_bind-tools
                tristate "bind-tools............................... bind administration tools (all)"
                default y if DEFAULT_bind-tools
                default m if ALL
                depends on !(BIND_JEMALLOC) || ((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64||loongarch64)||(USE_GLIBC&&(powerpc||i386)))
                depends on !arc
                select PACKAGE_bind-check 
                select PACKAGE_bind-ddns-confgen if PACKAGE_bind-ddns-confgen-gssapi<PACKAGE_bind-tools 
                select PACKAGE_bind-delv if PACKAGE_bind-delv-gssapi<PACKAGE_bind-tools 
                select PACKAGE_bind-dig 
                select PACKAGE_bind-dnssec if PACKAGE_bind-dnssec-gssapi<PACKAGE_bind-tools 
                select PACKAGE_bind-host if PACKAGE_bind-host-gssapi<PACKAGE_bind-tools 
                select PACKAGE_bind-nslookup if PACKAGE_bind-nslookup-gssapi<PACKAGE_bind-tools 
                select PACKAGE_bind-rndc if PACKAGE_bind-rndc-gssapi<PACKAGE_bind-tools
                select PACKAGE_libc
                help
                 bind administration tools (all)

```

The reference to `select PACKAGE_bind-nslookup if PACKAGE_bind-nslookup-gssapi<PACKAGE_bind-tools` basically means to select `bind-nslookup` if `bind-nslookup-gssapi` hasn’t already been selected, which is what’s intended.

Now, if I try to do the same thing to `bind-check` by uncommenting the `PROVIDES` line in the `Makefile`:

```plaintext
define Package/bind-check
  $(Package/bind/Default)
  TITLE+= tools (named-checkconf, named-checkzone)
  CONFLICTS:=bind-check-gssapi
endef

define Package/bind-check-gssapi
  $(Package/bind-gssapi/Default)
  TITLE+= tools (named-checkconf, named-checkzone) with GSSAPI
  #PROVIDES:=bind-check
endef

```

`make menuconfig` goes gaga and starts complaining:

```plaintext
tmp/.config-package.in:98795:error: recursive dependency detected!
tmp/.config-package.in:98795:	symbol PACKAGE_bind-tools depends on PACKAGE_bind-tools
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"

```

And the same section of `tmp/.config-package.in` suddenly turns into this:

```plaintext
        config PACKAGE_bind-tools
                tristate "bind-tools............................... bind administration tools (all)"
                default y if DEFAULT_bind-tools
                default m if ALL
                depends on !(BIND_JEMALLOC) || ((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64||loongarch64)||(USE_GLIBC&&(powerpc||i386)))
                depends on !(PACKAGE_bind-check-gssapi<PACKAGE_bind-tools && BIND_JEMALLOC) || ((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64||loongarch64)||(USE_GLIBC&&(powerpc||i386)))
                depends on !(PACKAGE_bind-check-gssapi<PACKAGE_bind-tools) || !arc
                depends on !(PACKAGE_bind-delv-gssapi<PACKAGE_bind-tools && BIND_JEMALLOC) || ((mips||mipsel||mips64||powerpc64||x86_64||arm||aarch64||loongarch64)||(USE_GLIBC&&(powerpc||i386)))
                depends on !(PACKAGE_bind-delv-gssapi<PACKAGE_bind-tools) || !arc
                depends on !arc
                select PACKAGE_bind-check if PACKAGE_bind-check-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-ddns-confgen if PACKAGE_bind-ddns-confgen-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-delv if PACKAGE_bind-delv-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-dig
                select PACKAGE_bind-dnssec if PACKAGE_bind-dnssec-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-host if PACKAGE_bind-host-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-nslookup if PACKAGE_bind-nslookup-gssapi<PACKAGE_bind-tools
                select PACKAGE_bind-rndc if PACKAGE_bind-rndc-gssapi<PACKAGE_bind-tools
                select PACKAGE_libc
                help
                 bind administration tools (all)

```

The `depends on !(PACKAGE_bind-check-gssapi<PACKAGE_bind-tools…` type of lines above are suddenly added (and seem bogus).

Any idea what I’m doing wrong and/or how I could further debug the whole dependency checking in `make menuconfig`?
