Ticket #42114

macOS compile error "use of undeclared identifier 'NSIG'"

Open Date: 2021-04-30 05:19 Last Update: 2021-05-15 13:34

Reporter:
Owner:
Type:
Status:
Closed
Component:
MileStone:
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
Fixed
File:
2

Details

When compiling freeciv 'master' branch on macOS, using MacPorts libraries, compilation fails in dependencies/lua-5.4/src/lcode.c with this error:

libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../../../gen_headers -I/opt/local/include -DLOCALEDIR=\"/usr/local/share/locale\" -DBINDIR=\"/usr/local/bin\" -DFC_CONF_PATH=\"/usr/local/etc/freeciv\" "-DDEFAULT_DATA_PATH=\".:data:~/.freeciv/dev:/usr/local/share/freeciv\"" "-DDEFAULT_SAVE_PATH=\".:~/.freeciv/saves\"" "-DDEFAULT_SCENARIO_PATH=\".:data/scenarios:~/.freeciv/dev/scenarios:~/.freeciv/scenarios:/usr/local/share/freeciv/scenarios\"" -Wall -Wpointer-arith -Wcast-align -Wno-tautological-compare -g -O2 -MT lcode.lo -MD -MP -MF .deps/lcode.Tpo -c lcode.c -o lcode.o
In file included from lcode.c:20:
In file included from ./ldebug.h:11:
In file included from ./lstate.h:125:
/usr/include/signal.h:69:42: error: use of undeclared identifier 'NSIG'
extern __const char *__const sys_signame[NSIG];
                                         ^
/usr/include/signal.h:70:42: error: use of undeclared identifier 'NSIG'
extern __const char *__const sys_siglist[NSIG];
                                         ^
2 errors generated.
make[3]: *** [lcode.lo] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all-recursive] Error 1

I believe that the immediate cause of the error is that the configuration defines a macro _DARWIN_C_SOURCE in gen_headers/fc_config.h. Source file dependencies/lua-5.4/src/lcode.c indirectly includes <sys/signal.h> before gen_headers/fc_config.h, then includes <signal.h> after. Thus, when the preprocessor reads <sys/signal.h>, _DARWIN_C_SOURCE is not defined, so the preprocessor omits the macOS-specific name NSIG. Then the preprocessor reads gen_headers/fc_config.h, which defines _DARWIN_C_SOURCE. Later, the preprocessor later reads <signal.h>, and includes some macOS-specific code which requires the name NSIG.

I believe that the root cause of the error is that configure.ac line 16 calls the macro AC_USE_SYSTEM_EXTENSIONS. This macro somehow causes gen_headers/fc_config.h to include a definition of _DARWIN_C_SOURCE. I'm not sure of the complete chain of events.

A workaround is to comment out configure.ac line 16, so that it reads:

dnl @@@ we don't want _DARWIN_C_SOURCE. AC_USE_SYSTEM_EXTENSIONS
With this workaround, the entire freeciv source code compiles correctly, and appears to run. There are some bugs, but it's hard to assess which of those are due to the workaround and which are underlying bugs in the freeciv 3 codebase.

Compilation environment:
host OS: macOS 10.13.6 High Sierra
environment:

LDFLAGS=-L/opt/local/lib
CFLAGS=-pipe -Os -arch x86_64
Supply required libraries via MacPorts.
Branch: master
configuration command: ./autogen.sh --disable-silent-rules --enable-fcdb=sqlite3 --with-readline --enable-sdl-mixer --enable-fcmp=cli --enable-client=all

Ticket History (3/17 Histories)

2021-04-30 05:19 Updated by: jdlh
  • New Ticket "macOS compile error "use of undeclared identifier 'NSIG'"" created
2021-04-30 05:38 Updated by: jdlh
Comment

Here is a little more information on the include file structure which cause the problem. ./dependencies/lua-5.4/src/lcode.c:15-20 contains the following include statements:

#include <stdlib.h>

#include "lua.h"

#include "lcode.h"
#include "ldebug.h"

Adding -H to the compilation command for lcode.c gives this include file listing (irrelevant lines replaced by '…'):

. /usr/include/stdlib.h …
.. /usr/include/sys/wait.h …
... /usr/include/sys/signal.h …
…
. ./lua.h …
.. ./luaconf.h …
... ./localluaconf.h
.... ../../../gen_headers/fc_config.h
…
. ./ldebug.h
.. ./lstate.h
... /usr/include/signal.h
…

/usr/include/sys/signal.h:76-80 includes code which defines macro NSIG if macro _DARWIN_C_SOURCE is defined:

#define __DARWIN_NSIG	32	/* counting 0; could be 33 (mask is 1-32) */

#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
#define NSIG	__DARWIN_NSIG
#endif

./gen_headers/fc_config.h:722-725 contains code to define _DARWIN_C_SOURCE:

/* Enable general extensions on macOS.  */
#ifndef _DARWIN_C_SOURCE
# define _DARWIN_C_SOURCE 1
#endif

Finally /usr/include/signal.h:68-71 contains code which requires macro NSIG if macro _DARWIN_C_SOURCE is defined:

#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
extern __const char *__const sys_signame[NSIG];
extern __const char *__const sys_siglist[NSIG];
#endif

So the problem is that freeciv includes <sys/signal.h> (via <stdlib.h>) before <fc_config.h> (via lua.h). But _DARWIN_C_SOURCE doesn't get defined until <fc_config.h>, after <sys/signal.h> has missed the chance to define NSIG.

Of course, ./dependencies/lua-5.4/src/lcode.c is a slight adaptation of code received from the Lua project. Does that code require _DARWIN_C_SOURCE to be defined in order to compile correctly on macOS? How does that code expect the containing code base to supply the _DARWIN_C_SOURCE definition? I don't know, at this point.

I suspect, but have not tested, that if freeciv were to include -D_DARWIN_C_SOURCE in the compiler invocation for each file within the the Lua-5.4/ source, or perhaps for every file in the whole freeciv source, then this bug would be resolved. The problem with supplying _DARWIN_C_SOURCE via include file <fc_config.h> is that this file gets included in the midst of other includes, not as the first entry.

2021-04-30 08:08 Updated by: jdlh
Comment

I see a variable LUA_CFLAGS, described in ./configure --help as:

LUA_CFLAGS  C compiler flags for LUA, overriding pkg-config

I tried using it to set -D_DARWIN_C_SOURCE just for the ./dependencies/lua-5.4/ build, by means of:

% ./autogen.sh LUA_CFLAGS=-D_DARWIN_C_SOURCE LDFLAGS=-L/opt/local/lib --enable-client=all --enable-fcmp=all --enable-sys-lua=no
However, this failed with the same compilation error on lcode.o.

Looking at the contents of Makefile, there is a LUA_CFLAGS definition which does not include the -D_DARWIN_C_SOURCE from the autogen. I would expect it to be there.

(Edited, 2021-04-30 08:19 Updated by: jdlh)
2021-04-30 10:10 Updated by: cazfi
  • Milestone Update from (None) to 2.6.5 (closed)
  • Component Update from (None) to Bootstrap
Comment

Assuming all branches to be affected, when one does build for in-tree liblua.

The proper solution, fixing any incompatibilities between fc_config,h definitions and liblua compilaton, not just this one, is to generate separate config header containing just the macros that liblua configuration requires, and use that instead of full fc_config.h in liblua build.

2021-04-30 10:48 Updated by: cazfi
Comment

Reply To cazfi

The proper solution, fixing any incompatibilities between fc_config,h definitions and liblua compilaton, not just this one, is to generate separate config header containing just the macros that liblua configuration requires, and use that instead of full fc_config.h in liblua build.

Patches to do that attached. Do they help?

2021-04-30 11:25 Updated by: jdlh
Comment

Thank you for the prompt response!

I applied patch 0045 to my copy of freeciv, master branch. It failed on meson.build.

% patch -p1 <0045-Generate-separate-configuration-header-to-be-used-fo.patch 
patching file configure.ac
patching file dependencies/lua-5.4/src/localluaconf.h
patching file gen_headers/.gitignore
patching file gen_headers/Makefile.am
patching file gen_headers/liblua_config.h.in
patching file gen_headers/meson_liblua_config.h.in
patching file meson.build
Hunk #2 succeeded at 131 (offset -7 lines).
Hunk #3 succeeded at 150 (offset -7 lines).
Hunk #4 FAILED at 163.
Hunk #5 succeeded at 316 (offset -14 lines).
1 out of 5 hunks FAILED -- saving rejects to file meson.build.rej

My meson.build is from commit d2c28c6d254dba3c9a909216b31513a3ac1f19f3. I think that's the most recent one I can get from the freeciv repo. It has no lines containing BCryptGenRandom.

This is the content of meson.build.rej (869 bytes):

***************
*** 168,173 ****
    endif
  endforeach
  
  if c_compiler.has_function('BCryptGenRandom', args: '-lbcrypt')
    bcrypt_lib_dep = c_compiler.find_library('bcrypt')
    priv_conf_data.set('HAVE_BCRYPTGENRANDOM', 1)
--- 163,189 ----
    endif
  endforeach
  
+ liblua_functions = [
+   'mkstemp',
+   'popen',
+   'pclose',
+   '_longjmp',
+   '_setjmp',
+   'gmtime_r',
+   'localtime_r',
+   'fseeko'
+   ]
+ 
+ foreach func : liblua_functions
+   if c_compiler.has_function(func)
+     liblua_conf_data.set('HAVE_' + func.underscorify().to_upper(), 1)
+   endif
+ endforeach
+ 
+ if c_compiler.has_header('unistd.h')
+   liblua_conf_data.set('FREECIV_HAVE_UNISTD_H', 1)
+ endif
+ 
  if c_compiler.has_function('BCryptGenRandom', args: '-lbcrypt')
    bcrypt_lib_dep = c_compiler.find_library('bcrypt')
    priv_conf_data.set('HAVE_BCRYPTGENRANDOM', 1)
(Edited, 2021-04-30 12:13 Updated by: jdlh)
2021-04-30 11:37 Updated by: jdlh
Comment

But, when I manually add the liblua_functions and unistd.h lines to the meson.build file which I have, then yes, it seems to compile without the "undefined NSIG" error.

2021-04-30 12:05 Updated by: cazfi
  • Resolution Update from None to Accepted
Comment

Oh sorry, my tree has #42040 applied.

2021-04-30 13:32 Updated by: jdlh
  • Resolution Update from Accepted to None
Comment

Interestingly, I just compiled S2_6 head (commit 43bc253d6faa68d04667c73be3b5503a7c7f5aaf) without encountering the "undefined NSIG" error. I did not need to apply patch 0023 from the attachments here.

However, I thought I did try to build with tag R2_6_4 (commit 9b2b1d7b0698fbb5220257f161b00a7e952efac9) and it failed.

I don't know what would have changed between commit 9b2b1d7 and commit 43bc253 to fix the problem. I'll see if I can figure out a fancy git diff which might tell me.

2021-05-08 11:05 Updated by: cazfi
Comment

Pushed to master & S3_1. Waiting until after 3.0.0-beta2 before pushing to S3_0 & S2_6.

2021-05-08 15:20 Updated by: cazfi
Comment

Reply To jdlh

Interestingly, I just compiled S2_6 head (commit 43bc253d6faa68d04667c73be3b5503a7c7f5aaf) without encountering the "undefined NSIG" error. I did not need to apply patch 0023 from the attachments here.

Maybe you have lua-5.3, used by S2_6 and S3_0, installed? When already available in system, no in-tree liblua build gets made (unless you configure with --disable-sys-lua).

2021-05-08 15:25 Updated by: jdlh
Comment

Maybe you have lua-5.3, used by S2_6 and S3_0, installed?

Yes, in fact, I have lua 5.3.5 installed courtesy of MacPorts. The next experiments for me will be to try redoing configure with --disable-sys-lua, and to disable lua at the MacPorts level. I might then see the NSIG errors.

2021-05-13 16:57 Updated by: jdlh
Comment

Reply To cazfi

Pushed to master & S3_1. Waiting until after 3.0.0-beta2 before pushing to S3_0 & S2_6.

I think I see something missing from both patch files. They do not add an entry /stamp-h3 to gen_headers/.gitignore. Thus when AC_CONFIG_HEADERS() generates gen_headers/stamp-h3, git flags that as an untracked file.

This should be a trivial change to make. That part of gen_headers/.gitignore will look like:

/stamp-h1
/stamp-h2
/stamp-h3

(Or maybe /stamp-h* ?)

Would it be helpful for me to generate a patch for this? Or is it easier for you to just do it?

2021-05-14 14:42 Updated by: cazfi
Comment

Reply To jdlh

They do not add an entry /stamp-h3 to gen_headers/.gitignore. Would it be helpful for me to generate a patch for this? Or is it easier for you to just do it?

I can push such a change without a ticket. Thanks for reporting.

2021-05-15 13:34 Updated by: cazfi
  • Status Update from Open to Closed
  • Owner Update from (None) to cazfi
  • Resolution Update from None to Fixed

Edit

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Login