[SOLVED] Compiling nftables with cli support

Hi all,

I'm trying to build nftables with cli support and I think I could really use some help. So, I have enabled --with-cli option in Makefile of nftables, added dependency for libreadline, selected libreadline, run make and got this error:

checking for readline in -lreadline... no
configure: error: No suitable version of libreadline found
Makefile:43: recipe for target '/home/user/openwrt/build_dir/target-x86_64_musl/nftables-0.8.2/.configured_68b329da9893e34099c7d8ad5cb9c940' failed
make[2]: *** [/home/user/openwrt/build_dir/target-x86_64_musl/nftables-0.8.2/.configured_68b329da9893e34099c7d8ad5cb9c940] Error 1
make[2]: Leaving directory '/home/user/openwrt/package/network/utils/nftables'
package/Makefile:106: recipe for target 'package/network/utils/nftables/compile' failed
make[1]: *** [package/network/utils/nftables/compile] Error 2
make[1]: Leaving directory '/home/user/openwrt'
/home/user/openwrt/include/toplevel.mk:216: recipe for target 'package/network/utils/nftables/compile' failed
make: *** [package/network/utils/nftables/compile] Error 2

After some investigation I've found out that failing code is in openwrt/build_dir/target-x86_64_musl/nftables-0.8.2/configure:

if test "x$with_cli" != xno; then :

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5
$as_echo_n "checking for readline in -lreadline... " >&6; }
if ${ac_cv_lib_readline_readline+:} false; then :
  $as_echo_n "(cached) " >&6
else
  ac_check_lib_save_LIBS=$LIBS
LIBS="-lreadline  $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */

/* Override any GCC internal prototype to avoid an error.
   Use char because int might match the return type of a GCC
   builtin and then its argument prototype would still apply.  */
#ifdef __cplusplus
extern "C"
#endif
char readline ();
int
main ()
{
return readline ();
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
  ac_cv_lib_readline_readline=yes
else
  ac_cv_lib_readline_readline=no
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5
$as_echo "$ac_cv_lib_readline_readline" >&6; }
if test "x$ac_cv_lib_readline_readline" = xyes; then :
  cat >>confdefs.h <<_ACEOF
#define HAVE_LIBREADLINE 1
_ACEOF

  LIBS="-lreadline $LIBS"

else
  as_fn_error $? "No suitable version of libreadline found" "$LINENO" 5
fi

$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h

Now I don't really understand where is a problem, because libreadline seems to be compiled correctly. Does anyone has suggestions?

EDIT. config.log of nftables says following:

configure:12695: checking for readline in -lreadline
configure:12720: x86_64-openwrt-linux-musl-gcc -o conftest -Os -pipe -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -iremap/home/user/openwrt/build_dir/target-x86_64_musl/nftables-0.8.2:nftables-0.8.2 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro  -I/home/user/openwrt/staging_dir/target-x86_64_musl/usr/include -I/home/user/openwrt/staging_dir/target-x86_64_musl/include -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/usr/include -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/include/fortify -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/include  -L/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib -L/home/user/openwrt/staging_dir/target-x86_64_musl/lib -L/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/usr/lib -L/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/lib -znow -zrelro  conftest.c -lreadline   >&5
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `PC'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `UP'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tgetent'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tgetstr'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tgetflag'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tputs'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tgetnum'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `BC'
/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib/libreadline.so: undefined reference to `tgoto'
collect2: error: ld returned 1 exit status
configure:12720: $? = 1
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "nftables"
| #define PACKAGE_TARNAME "nftables"
| #define PACKAGE_VERSION "0.8.2"
| #define PACKAGE_STRING "nftables 0.8.2"
| #define PACKAGE_BUGREPORT "netfilter-devel@vger.kernel.org"
| #define PACKAGE_URL ""
| #define RELEASE_NAME "Joe Btfsplk"
| #define PACKAGE "nftables"
| #define VERSION "0.8.2"
| #define _GNU_SOURCE /**/
| #define _STDC_FORMAT_MACROS /**/
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define HAVE_DLFCN_H 1
| #define LT_OBJDIR ".libs/"
| /* end confdefs.h.  */
| 
| /* Override any GCC internal prototype to avoid an error.
|    Use char because int might match the return type of a GCC
|    builtin and then its argument prototype would still apply.  */
| #ifdef __cplusplus
| extern "C"
| #endif
| char readline ();
| int
| main ()
| {
| return readline ();
|   ;
|   return 0;
| }
configure:12729: result: no
configure:12739: error: No suitable version of libreadline found

What if you also add +libncurses to your dependency list ?
libreadline has some dependencies on libncurses

Apparently by default nftables are linked only against -lreadline as it is visible in config.log:

configure:12720: x86_64-openwrt-linux-musl-gcc -o conftest -Os -pipe -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -iremap/home/user/openwrt/build_dir/target-x86_64_musl/nftables-0.8.2:nftables-0.8.2 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -I/home/user/openwrt/staging_dir/target-x86_64_musl/usr/include -I/home/user/openwrt/staging_dir/target-x86_64_musl/include -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/usr/include -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/include/fortify -I/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/include -L/home/user/openwrt/staging_dir/target-x86_64_musl/usr/lib -L/home/user/openwrt/staging_dir/target-x86_64_musl/lib -L/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/usr/lib -L/home/user/openwrt/staging_dir/toolchain-x86_64_gcc-5.5.0_musl/lib -znow -zrelro conftest.c -lreadline >&5

According to some forums, if nftables is compiled with cli option, then it must be also linked against -lncurses as well. In order to do so, following must have been added to nftables Makefile:

CONFIGURE_VARS += \
	LIBS="-lncurses"

That option alone does not do the job completely, because for some reason libncursesw.o.6 can't be found, therefore dependency +libncurses (as mentioned by commodo) must be added as well. After adding that, building is successful and interactive mode nft -i is working without any problems. I have done all these tests on x86_64 target running on virtual machine. Later on I will build image for WRT1900ACS based on these findings.