ibara/mg

NetBSD 8.1: fparseln() not detected by ./configure

Closed this issue · 9 comments

Thanks! My alpine build is happy. :)

For portability I think we need the same #include <stdio.h> fix for fparselncheck on NetBSD 8.1 (build run on sdf.org) (ref #30):

In file included from fstatat.c:9:
./config.h:16:23: error: unknown type name 'FILE'
extern char *fparseln(FILE *, size_t *, size_t *, const char[3], int);
                      ^
1 error generated.
*** Error code 1

Stop.
make: stopped in /sdf/arpa/af/d/dgoerger/build/mg

On NetBSD 8.1 (probably also earlier, not sure), fparseln() seems to be in stdio.h:

$ grep -rIn fparseln /usr/include
/usr/include/stdio.h:417:char   *fparseln(FILE *, size_t *, size_t *, const char[3], int);

If I change config.h to include #define HAVE_FPARSELN instead, the build proceeds. The build does still ultimately fail, but I'm not convinced that's a NetBSD problem so much as a consequence of SDF carrying forward decades of old libraries on the /usr/pkg NAS (/usr/bin/ld: cannot find -lncursesw - the dynamic/non-static build works if I link against NetBSD's libcurses from base [-lcurses] instead of GNU ncurses[w] from pkgsrc, and does not work if I try to include /usr/pkg headers explicitly [but I've had the same problem linking other software against libncursesw on sdf.org]).

ibara commented

Should be fixed now, thanks.

Thanks! But this isn't enough -- now it fails with the same error in futimens.c.

My thought had been that the header should (probably) be added to configure just like in this commit for detecting futimens() on Alpine Linux: e5962fa

At least, all I needed to do for it to build was add #define HAVE_FPARSELN to config.h. Adding stdio.h in more files shouldn't hurt, though, I'm not sure it's strictly necessary.

Current behaviour on master:

otaku$ uname -sr
NetBSD 8.1
otaku$ git clone https://github.com/ibara/mg.git
Cloning into 'mg'...
remote: Enumerating objects: 58, done.
remote: Counting objects: 100% (58/58), done.
remote: Compressing objects: 100% (50/50), done.
remote: Total 571 (delta 14), reused 27 (delta 8), pack-reused 513
Receiving objects: 100% (571/571), 375.56 KiB | 562.00 KiB/s, done.
Resolving deltas: 100% (325/325), done.
otaku$ cd mg
otaku$ ./configure
checking for C compiler... clang
checking for -w compiler flag... yes
checking for OS... NetBSD
checking for fparseln... no
checking for fstatat... yes
checking for futimens... yes
checking for getline... yes
checking for pledge... no
checking for reallocarray... yes
checking for strlcat... yes
checking for strlcpy... yes
checking for strndup... yes
checking for strtonum... yes
creating Makefile... done
otaku$ make
clang -DREGEX -w -D_OPENBSD_SOURCE  -c autoexec.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c basic.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c bell.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c buffer.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cinfo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c dir.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c display.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c echo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c extend.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c file.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fileio.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c funmap.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c help.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c kbd.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c keymap.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c line.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c macro.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c main.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c match.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c modes.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c paragraph.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c re_search.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c region.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c search.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c spawn.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c tty.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c ttyio.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c ttykbd.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c undo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c util.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c version.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c window.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c word.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c yank.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cmode.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cscope.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c dired.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c grep.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c tags.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fparseln.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fstatat.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c futimens.c
In file included from futimens.c:5:
./config.h:16:23: error: unknown type name 'FILE'
extern char *fparseln(FILE *, size_t *, size_t *, const char[3], int);
                      ^
1 error generated.
*** Error code 1

Stop.
make: stopped in /sdf/arpa/af/d/dgoerger/tmp/mg

further output

otaku$ cp -p config.h{,.orig}
otaku$ vi config.h
otaku$ diff -u config.h.orig config.h
--- config.h.orig 2019-10-14 17:33:14.983834458 -0400
+++ config.h      2019-10-14 17:41:14.392518994 -0400
@@ -13,7 +13,7 @@
 #include "dragonfly.h"
 #endif

-extern char *fparseln(FILE *, size_t *, size_t *, const char[3], int);
+#define HAVE_FPARSELN
 #define HAVE_FSTATAT
 #define HAVE_FUTIMENS
 #define HAVE_GETLINE
otaku$ make
clang -DREGEX -w -D_OPENBSD_SOURCE  -c futimens.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c getline.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c reallocarray.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strlcat.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strlcpy.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strndup.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strtonum.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c interpreter.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c extensions.c
clang  -o mg autoexec.o basic.o bell.o buffer.o cinfo.o dir.o display.o  echo.o extend.o file.o fileio.o funmap.o help.o kbd.o keymap.o  line.o macro.o main.o match.o modes.o paragraph.o re_search.o  region.o search.o spawn.o tty.o ttyio.o ttykbd.o undo.o util.o  version.o window.o word.o yank.o cmode.o cscope.o dired.o  grep.o tags.o fparseln.o fstatat.o futimens.o getline.o  reallocarray.o strlcat.o strlcpy.o strndup.o strtonum.o  interpreter.o extensions.o -lncursesw -lutil
/usr/bin/ld: cannot find -lncursesw
clang: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

Stop.
make: stopped in /sdf/arpa/af/d/dgoerger/tmp/mg

(at this point I need to link against -lcurses instead of -lncursesw, but again I'm not sure this is a NetBSD problem per se - although curses is in base, whereas ncursesw is not, so curses may be a better option regardless similar to macOS being picky)

ibara commented

So this problem is because fparseln isn't being picked up on your system. That doesn't make much sense, since fparseln has been in NetBSD since 1.4.

Unrelatedly, the commit I just made fixes the compat fparseln compilation.

But we should figure out why the fparseln check isn't working on NetBSD.

Can you compile this program on your machine and tell me what the output is:

#include <stdio.h>
#include <util.h>
int main(void){fparseln(NULL,NULL,NULL,NULL,0);return 0;}

Compile that with the following invocation:

cc -DREGEX -D_OPENBSD_SOURCE -o a.out file.c -lncursesw -lutil

As that will replicate the configure test.

Ahhhh, I'm very sorry -- I hadn't expanded $libs -- it is related to -lcurses vs -lncursesw:

otaku$ mkdir 20191014_fparseln_test
otaku$ cd 20191014_fparseln_test/
otaku$ vi test.c
otaku$ cat test.c
#include <stdio.h>
#include <util.h>
int main(void){fparseln(NULL,NULL,NULL,NULL,0);return 0;}
otaku$ cc -DREGEX -D_OPENBSD_SOURCE -o a.out test.c -lncursesw -lutil
/usr/bin/ld: cannot find -lncursesw
cc: error: linker command failed with exit code 1 (use -v to see invocation)
otaku$ cc -DREGEX -D_OPENBSD_SOURCE -o a.out test.c -lcurses -lutil
otaku$ ./a.out
Segmentation fault (core dumped)

I might then suggest changing

  "xNetBSD")
    cflags="$cflags -D_OPENBSD_SOURCE"
    libs="$libs -lutil"
    ;;

to

  "xNetBSD")
    cflags="$cflags -D_OPENBSD_SOURCE"
    libs="-lcurses -lutil"
    ;;

log verifying this patch (otaku.sdf.org, part of the freeshell.org public access unix system):

otaku$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
otaku$ cp -p configure{,.orig}
otaku$ vi configure
otaku$ diff -u configure.orig configure
--- configure.orig        2019-10-14 17:33:03.511044262 -0400
+++ configure     2019-10-14 18:58:03.789471508 -0400
@@ -344,7 +344,7 @@
     ;;
   "xNetBSD")
     cflags="$cflags -D_OPENBSD_SOURCE"
-    libs="$libs -lutil"
+    libs="-lcurses -lutil"
     ;;
   "xDragonFly")
     cflags="$cflags -D__dead=__dead2 -DLOGIN_NAME_MAX=MAXLOGNAME"
otaku$ ./configure
checking for C compiler... clang
checking for -w compiler flag... yes
checking for OS... NetBSD
checking for fparseln... yes
checking for fstatat... yes
checking for futimens... yes
checking for getline... yes
checking for pledge... no
checking for reallocarray... yes
checking for strlcat... yes
checking for strlcpy... yes
checking for strndup... yes
checking for strtonum... yes
creating Makefile... done
otaku$ make
clang -DREGEX -w -D_OPENBSD_SOURCE  -c autoexec.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c basic.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c bell.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c buffer.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cinfo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c dir.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c display.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c echo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c extend.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c file.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fileio.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c funmap.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c help.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c kbd.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c keymap.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c line.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c macro.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c main.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c match.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c modes.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c paragraph.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c re_search.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c region.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c search.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c spawn.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c tty.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c ttyio.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c ttykbd.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c undo.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c util.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c version.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c window.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c word.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c yank.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cmode.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c cscope.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c dired.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c grep.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c tags.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fparseln.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c fstatat.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c futimens.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c getline.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c reallocarray.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strlcat.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strlcpy.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strndup.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c strtonum.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c interpreter.c
clang -DREGEX -w -D_OPENBSD_SOURCE  -c extensions.c
clang  -o mg autoexec.o basic.o bell.o buffer.o cinfo.o dir.o display.o  echo.o extend.o file.o fileio.o funmap.o help.o kbd.o keymap.o  line.o macro.o main.o match.o modes.o paragraph.o re_search.o  region.o search.o spawn.o tty.o ttyio.o ttykbd.o undo.o util.o  version.o window.o word.o yank.o cmode.o cscope.o dired.o  grep.o tags.o fparseln.o fstatat.o futimens.o getline.o  reallocarray.o strlcat.o strlcpy.o strndup.o strtonum.o  interpreter.o extensions.o -lcurses -lutil
otaku$ ./mg ~/.mg
otaku$ # hurrah!
ibara commented

OK. One last question then. Because I don't know NetBSD so well.

  1. Does NetBSD have a /usr/include/term.h header? and
  2. Is that header part of NetBSD curses?

If so, then yes we can default to NetBSD curses for NetBSD.

ibara commented

By the way, you might want to run configure as something like
$ CFLAGS='-O2 -pipe' ./configure
so you can have some optimization in there.

No worries, I'm no expert of NetBSD, either. I have a free shell account on SDF.org, which runs an open access NetBSD array. It's been useful for poking around and learning about subtle (or not so subtle) differences between different unix-like operating systems, and for helping me write better / more portable code (not a lot of C).

  1. I can confirm that file exists and (using a quick and dirty check via file atime) can verify that that file is being used during the build.
  2. I'm not sure I fully understand the question. It doesn't look like one header #includes the other, but commit messages for lib/libterminfo/term.h and lib/libcurses/curses.h do suggest they're developed in tandem, despite being developed in different source directories -- if that's the question.

Regarding the optimization tip.. thanks! :)

ibara commented

Yeah, I just wanted to make sure NetBSD had its own term.h header (as that's what mg uses). So yes, we can switch NetBSD over to NetBSD curses.