Ticket #42114

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

Eröffnet am: 2021-04-30 05:19 Letztes Update: 2021-05-15 13:34

Auswertung:
Verantwortlicher:
Typ:
Status:
Geschlossen
Komponente:
Meilenstein:
Priorität:
5 - Mittel
Schweregrad:
5 - Mittel
Lösung:
Gefixt
Datei:
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-Verlauf (3/17 Historien)

2021-04-30 05:19 Aktualisiert von: jdlh
  • New Ticket "macOS compile error "use of undeclared identifier 'NSIG'"" created
2021-04-30 05:38 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: jdlh)
2021-04-30 10:10 Aktualisiert von: cazfi
  • Meilenstein Update from (Keine) to 2.6.5 (closed)
  • Komponente Update from (Keine) to Bootstrap
Kommentar

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 Aktualisiert von: cazfi
Kommentar

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 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: jdlh)
2021-04-30 11:37 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: cazfi
  • Lösung Update from Keine to Accepted
Kommentar

Oh sorry, my tree has #42040 applied.

2021-04-30 13:32 Aktualisiert von: jdlh
  • Lösung Update from Accepted to Keine
Kommentar

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 Aktualisiert von: cazfi
Kommentar

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

2021-05-08 15:20 Aktualisiert von: cazfi
Kommentar

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 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: jdlh
Kommentar

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 Aktualisiert von: cazfi
Kommentar

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 Aktualisiert von: cazfi
  • Status Update from Offen to Geschlossen
  • Verantwortlicher Update from (Keine) to cazfi
  • Lösung Update from Keine to Gefixt

Bearbeiten

Please login to add comment to this ticket » Anmelden