libgpg-error 1.50 build issue (spawn-posix.c:345:5: error: use of undeclared identifier 'environ')
Closed, ResolvedPublic

Assigned To
Authored By
Marius_Schamschula
Jun 19 2024, 11:28 PM

Description

While updating the MacPorts Portfile to libgpg-error 1.50, I ran into the following error:

:info:build /bin/sh ../libtool  --tag=CC   --mode=compile /usr/bin/clang -DHAVE_CONFIG_H -I. -I..  -DLOCALEDIR=\"/opt/local/share/locale\" -I/opt/local/include -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk  -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk -arch arm64 -Wall -Wpointer-arith -MT libgpg_error_la-spawn-posix.lo -MD -MP -MF .deps/libgpg_error_la-spawn-posix.Tpo -c -o libgpg_error_la-spawn-posix.lo `test -f 'spawn-posix.c' || echo './'`spawn-posix.c
:info:build spawn-posix.c:345:5: error: use of undeclared identifier 'environ'
:info:build     environ = act->environ;
:info:build     ^

macOS 14.5 23F79 arm64
Xcode 15.4 15F31d
Apple clang version 15.0.0 (clang-1500.3.9.4)

Full log attached

P.S. Sorry Werner! After more closely examining the diff between 1.49 and 1.50, it looks like spawn-posix.c got a major rewrite, rather than a small change in variable names. Context!

Event Timeline

I encountered this also on macOS. Apparently, Apple does not provide an declaration for environ, in contradiction to the manual page for execv.

• werner changed the task status from Open to Testing.Jun 20 2024, 12:05 PM
• werner added a subscriber: • werner.

Frankly, having environ declared in unistd.h is a glibc convenience and other systems likey don't have it. easy to fix, though.

• werner claimed this task.
• werner triaged this task as Normal priority.
• werner added a project: MacOS.
• werner added a project: gpgrt.

It looks like various flavors of BSD (including macOS just declare environ when needed): environ -- user environment Note: this is a very old MacOS X man page, however the current version is from 2003, and has the same Synopsis.

Quick workaround (should wrap it in the proper #if clauses):

--- src/spawn-posix.c.orig	2024-06-19 02:33:41
+++ src/spawn-posix.c	2024-06-20 10:01:26
@@ -57,6 +57,7 @@
 
 #include "gpgrt-int.h"
 
+extern char **environ;
 
 /* Definition for the gpgrt_spawn_actions_t.  Note that there is a
  * different one for Windows.  */

While the above patch worked for MacOS 10.8 and above, MacPorts CI shows a second error for older MacOS versions:

libtool: link: /usr/bin/clang -dynamiclib  -o .libs/libgpg-error.0.dylib  .libs/libgpg_error_la-posix-lock.o .libs/libgpg_error_la-posix-thread.o .libs/libgpg_error_la-spawn-posix.o .libs/libgpg_error_la-init.o .libs/libgpg_error_la-version.o .libs/libgpg_error_la-estream.o .libs/libgpg_error_la-estream-printf.o .libs/libgpg_error_la-strsource.o .libs/libgpg_error_la-strerror.o .libs/libgpg_error_la-code-to-errno.o .libs/libgpg_error_la-code-from-errno.o .libs/libgpg_error_la-visibility.o .libs/libgpg_error_la-sysutils.o .libs/libgpg_error_la-stringutils.o .libs/libgpg_error_la-syscall-clamp.o .libs/libgpg_error_la-logging.o .libs/libgpg_error_la-b64dec.o .libs/libgpg_error_la-b64enc.o .libs/libgpg_error_la-argparse.o   -L/opt/local/lib -lintl  -Os -arch x86_64 -Wl,-headerpad_max_install_names -arch x86_64 -Wl,-framework -Wl,CoreFoundation   -install_name  /opt/local/lib/libgpg-error.0.dylib -compatibility_version 38 -current_version 38.0 -Wl,-single_module
Undefined symbols for architecture x86_64:
  "_environ", referenced from:
      _my_exec in libgpg_error_la-spawn-posix.o
     (maybe you meant: _gpgrt_spawn_actions_set_environ, __gpgrt_spawn_actions_set_environ )
ld: symbol(s) not found for architecture x86_64
• gniibe added a subscriber: • gniibe.

Use of execve is better (avoiding use of environ).

diff --git a/src/spawn-posix.c b/src/spawn-posix.c
index 96f1536..8a14724 100644
--- a/src/spawn-posix.c
+++ b/src/spawn-posix.c
@@ -57,9 +57,6 @@
 
 #include "gpgrt-int.h"
 
-/* (Only glibc's unistd.h declares this iff _GNU_SOURCE is used.)  */
-extern char **environ;
-
 
 /* Definition for the gpgrt_spawn_actions_t.  Note that there is a
  * different one for Windows.  */
@@ -344,9 +341,6 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
   /* Close all other files.  */
   _gpgrt_close_all_fds (3, act->except_fds);
 
-  if (act->environ)
-    environ = act->environ;
-
   if (act->atfork)
     act->atfork (act->atfork_arg);
 
@@ -354,7 +348,11 @@ my_exec (const char *pgmname, const char *argv[], gpgrt_spawn_actions_t act)
   if (pgmname == NULL)
     return 0;
 
-  execv (pgmname, (char *const *)argv);
+  if (act->environ)
+    execve (pgmname, (char *const *)argv, act->environ);
+  else
+    execv (pgmname, (char *const *)argv);
+    
   /* No way to print anything, as we have may have closed all streams. */
   _exit (127);
   return -1;

This problem has gone in libgpg-error 1.51, since the implementation doesn't use environ any more.