(I'm new and this issue is nonobvious, so I'm posting to the list instead of opening an issue, hoping sr-dev is the right call.)
I am packaging kamailio for pkgsrc, a multi-OS multi-CPU portable packaging system, with NetBSD and SmartOS being perhaps the biggest targets. Mostly this is going well, and I'm probably doing a few things wrong (but am not asking for help on those yet).
During the build (NetBSD 8 amd64), I got a failure in src/lib/srdb1/db_ut.c:
CC (gcc) [L libsrdb1.so.1.0] db_ut.o In file included from db_ut.c:63:0: /usr/include/stdlib.h:273:28: error: unknown type name 'u_char' void arc4random_addrandom(u_char *, int); ^ /usr/include/stdlib.h:306:1: error: unknown type name 'devmajor_t' devmajor_t getdevmajor(const char *, mode_t); ^ gmake[3]: *** [../../Makefile.rules:100: db_ut.o] Error 1
This may be a NetBSD bug and I am investigating that in parallel.
In db_ut.c, several visibility defines are set. These have the effect of ensuring that definitions mandated by a certain standard are visible, but they also restrict visibility of definitions not mandated by that standard.
The code is:
/** * make strptime available * use 600 for 'Single UNIX Specification, Version 3' * _XOPEN_SOURCE creates conflict in swab definition in Solaris */ #ifndef __OS_solaris #define _XOPEN_SOURCE 600 /* glibc2 on linux, bsd */ #define _BSD_SOURCE 1 /* needed on linux to "fix" the effect * of the above define on * features.h/unistd.h syscall() */ #define _DEFAULT_SOURCE 1 /* _BSD_SOURCE is deprecated */ #else #define _XOPEN_SOURCE_EXTENDED 1 /* solaris */ #endif
#include <time.h>
#ifndef __OS_solaris #undef _XOPEN_SOURCE #undef _XOPEN_SOURCE_EXTENDED #else /* solaris */ #undef _XOPEN_SOURCE_EXTENDED #endif
strptime seems to have originally been XPG4, and now seems to be in base POSIX:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html
_XOPEN_SOURCE being 600 seems to be "X/Open 6, incorporating POSIX 2004": https://pubs.opengroup.org/onlinepubs/009695399/
I am not following the comment "_BSD_SOURCE is deprecated"; that is perhaps referring to the situation on Linux. But that define is not used on recent NetBSD.
Overall, feature tests macros are complicated, and while I'm sure there were good reasons they was added over time, I suspect that today they are not needed at all, or in a far more limited manner. (I'm unclear on how far back on various systems kamailio intends to support.)
On NetBSD 8, removing all the visibility defines that I quoted results in a clean build, and I have a patch in pkgsrc that does that.
I would advance the hypothesis that it would be preferable to remove the visibility defines, and if there are systems on which they are needed, to #ifdef system and perhaps #ifdef version <= OK_VERSION and then define things. This would avoid setting visibility defines on systemss where they haven't been tested and probably aren't needed.
I am therefore curious what happens on various systems if the above-quoted text from db_ut is removed.
There are also POSIX and other XOPEN defines in other files, and I'm not sure if they are ok or if I'm just not building those modules.
Alternatively I could prepare a PR to not set any defines on NetBSD, or to define _NETBSD_SOURCE, which should be more or less equivalent.
Thanks, Greg
Greg Troxel gdt@lexort.com writes:
This may be a NetBSD bug and I am investigating that in parallel.
The problem on NetBSD is including time.h with one set of visibility defines, and then stdlib with another. This seems likely to include some other headers (e.g. sys/types.h) with restricted visbility, and then because sys/types.h include guard is set, stdlib doesn't re-include it and thus doesn't get the definitions with the changed visibility macros.
While I can see the intent, it seems that code should define visibilty macros before including any headers and then not change them, so this doesn't feel like a NetBSD bug. But perhaps I am wrong on that.
My minimized reproduction for this:
#define _XOPEN_SOURCE 600
#include <time.h>
#undef _XOPEN_SOURCE
#include <stdlib.h>
int main(int argc, char **argv) { return 0; }
which fails exactly as unpatched db_ut.c.