vectorgraphics / asymptote

2D & 3D TeX-Aware Vector Graphics Language
https://asymptote.sourceforge.io/
GNU General Public License v3.0
533 stars 89 forks source link

configure fails to enable readline if ncurses is built with separate tinfo lib and "--as-needed" linker flag is used #461

Closed tifv closed 2 weeks ago

tifv commented 1 month ago

Steps to reproduce:

  1. Have a Linux system with readline and ncurses; ncurses is built with separate tinfo library.
  2. Run LDFLAGS="-Wl,--as-needed" ./configure --enable-readline
  3. Compile.
  4. Observe that ./asy --version tells you that readline is disabled.

Notably, I can see in the output of ./configure:

checking for setupterm in -lncurses... no
checking for setupterm in -lcurses... no

and in config.log:

configure:8050: checking for setupterm in -lncurses
configure:8072: g++ -o conftest -std=c++14  -I. -I/usr/local/include/gc -I/usr/include/gc -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -Wl,--as-needed   -lreadline     -ltinfo     -lncurses -ltinfo   conftest.cpp -lncurses  -lrt -lz -L/usr/local/lib -lgc  >&5
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /tmp/ccCjnqXD.o: in function `main':
conftest.cpp:(.text+0x9): undefined reference to `setupterm'
collect2: error: ld returned 1 exit status
configure:8072: $? = 1
configure: failed program was:

Apparently, setupterm symbol in fact belongs to libtinfo.so and not to libncurses.so (at least on my Gentoo system):

$ nm -gD /usr/lib64/libncurses.so | grep setupterm
                 U _nc_setupterm
$ nm -gD /usr/lib64/libtinfo.so | grep setupterm
000000000000e7c0 T _nc_setupterm
000000000000edc0 T setupterm

As far as I understand, the linker with --as-needed option will only link a library if one of its symbols is required by an item that goes before that library in the command line. Since setupterm symbol is used in conftest.cpp, and it goes after -ltinfo in the g++ args, the -ltinfo does not get linked. However, I have no idea how to fix the order of link arguments from configure.ac

(Today was the day I have learned about the tinfo library and --as-needed option, so I'm not sure I got all of that right. Gentoo uses --as-needed by default when building packages. Asymptote 2.86 does not have this bug, and 2.89 does.)

johncbowman commented 2 weeks ago

Can you try out the latest git development source, which fixes some pkg-config issues?

tifv commented 2 weeks ago

Yes, I have tried. It doesn't work.

It seems that for the ncurses check to succeed, -ltinfo should already be in $LIBS. But the tinfo check done with CHECK_LIB_STATIC autoconf macro, even successfull, doesn't append -ltinfo to $LIBS.

For example, replacing the line CHECK_LIB_STATIC(tinfo,tinfo,tgetent,HAVE_LIBTINFO,AC_MSG_NOTICE([perhaps tgetent is in -lncurses])) with AC_CHECK_LIB(tinfo, tgetent) on my system correctly prepends -ltinfo to $LIBS after the check and allows subsequent ncurses check to succeed.

As for pkg-config, it seems to work fine on my system:

$ pkg-config --libs tinfo
-ltinfo
$ pkg-config --libs ncurses
-lncurses -ltinfo

However, the CHECK_LIB_STATIC autoconf macro appends pkg-config output to $LDFLAGS during the check, but not to $LIBS. In linker arguments, $LDFLAGS goes before the conftest.cpp and $LIBS goes after it. Because --as-needed linker flag makes the order of linked libraries important, this results in a failed check.

tifv commented 2 weeks ago

This is somewhat unfamiliar territory for me, but it seems that according to AC_CHECK_LIB documentation, any extra libraries required for correct linkage, such as produced by pkg-config --libs, should go in its fifth argument? Like this:

--- a/configure.ac
+++ b/configure.ac
@@ -344,7 +344,7 @@
 [
 LDFLAGS=$LDFLAGS_SAVE
 $5
-])
+],$PKG_FLAGS)
 ]
 else
 [
@@ -352,7 +352,7 @@
 $5
 ]
 fi
-)]
+,$PKG_FLAGS)]
 )

 if test "x$enable_readline" != "xno"; then
johncbowman commented 2 weeks ago

Yes, that seems like a good solution. I think it is better than the one I came up:

--- a/configure.ac
+++ b/configure.ac
@@ -333,14 +333,24 @@ PKG_FLAGS=-l"$2"
 echo will try linking with $PKG_FLAGS
 fi
 LDFLAGS_SAVE=$LDFLAGS
-LDFLAGS="$LDFLAGS ""$STATIC ""$PKG_FLAGS ""$DYNAMIC "
-AC_CHECK_LIB($2,$3,AC_DEFINE($4,1,DEFINE_LIB($2)),
+LDFLAGS="$LDFLAGS "$STATIC"$PKG_FLAGS "$DYNAMIC
+AC_CHECK_LIB($2,$3,
+[
+LIBS=$LIBS$STATIC"$PKG_FLAGS "$DYNAMIC
+LDFLAGS=$LDFLAGS_SAVE
+AC_DEFINE($4,1,DEFINE_LIB($2))
+],
 if test "x$enable_static" = "xyes"; then
 [
 echo "Static library not found; will check for dynamic version"
 LDFLAGS="$LDFLAGS_SAVE ""$PKG_FLAGS "
 AS_UNSET([ac_cv_lib_$2_$3])
-AC_CHECK_LIB($2,$3,AC_DEFINE($4,1,DEFINE_LIB($2)),
+AC_CHECK_LIB($2,$3,
+[
+LIBS=$LIBS"$PKG_FLAGS "
+LDFLAGS=$LDFLAGS_SAVE
+AC_DEFINE($4,1,DEFINE_LIB($2))
+],
 [
 LDFLAGS=$LDFLAGS_SAVE
 $5
johncbowman commented 2 weeks ago

Fixed in commit 99bd09380ddd649d3d6060dda12320e2dc8ed10b.