Discussion:
environ on MacOS X
Bruno Haible
2008-02-24 14:30:41 UTC
Permalink
Hi,

I'm adding a bit of doc about 'environ' on MacOS X. References:
[1] http://wiki.finkproject.org/index.php/Fink:Porting_Notes
[2] http://lists.apple.com/archives/Unix-porting/2005/Sep/msg00062.html
[3] http://lists.apple.com/archives/Java-dev/2007/Dec/msg00096.html
[4] http://bob.pythonmac.org/archives/2004/01/02/accessing-environment-information-from-bundlesdylibs-os-x/
[5] http://article.gmane.org/gmane.os.apple.fink.cvs/72951


2008-02-24 Bruno Haible <***@clisp.org>

* doc/posix-functions/environ.texi: Document the MacOS X problem.

*** doc/posix-functions/environ.texi.orig 2008-02-24 15:26:50.000000000 +0100
--- doc/posix-functions/environ.texi 2008-02-24 15:25:16.000000000 +0100
***************
*** 16,21 ****
--- 16,33 ----
This variable is missing on some platforms:
MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, OSF/1 5.1, Cygwin.
@item
+ On MacOS X 10, this variable is not declared. Up to MacOS X 10.4, one can use
+ @smallexample
+ extern char **environ;
+ @end smallexample
+ to get the variable declared. This does not work any more, however, in
+ shared libraries on MacOS X 10.5. Here is a workaround: Instead, one can use
+ @smallexample
+ #include <crt_externs.h>
+ #define environ (*_NSGetEnviron())
+ @end smallexample
+ This works at least on MacOS X 10.3 and newer.
+ @item
The address of this variable is not a compile-time constant on some platforms:
mingw.
@end itemize
Eric Blake
2008-02-24 14:37:57 UTC
Permalink
According to Bruno Haible on 2/24/2008 7:30 AM:
| This variable is missing on some platforms:
| MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, OSF/1
5.1, Cygwin.

Actually, cygwin has environ.

- --
Don't work too hard, make some time for fun as well!

Eric Blake ***@byu.net
Bruno Haible
2008-02-24 15:39:45 UTC
Permalink
Actually, some modules in gnulib already use 'environ'. So this requires
handling in gnulib. I'm adding a new module 'environ'.
| MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, OSF/1 5.1, Cygwin.
Actually, cygwin has environ.
Probably all of them, except MacOS X 10.5, have 'environ'. The "nm" command
that I used to look for the 'environ' variable was not appropriate. I'm removing
this statement.


2008-02-24 Bruno Haible <***@clisp.org>

New module 'environ'.
* modules/environ: New file.
* lib/unistd.in.h (environ): New declaration.
* m4/environ.m4: New file.
(gt_CHECK_VAR_DECL): Moved here from m4/setenv.m4. Undefine gt_cv_var
after use.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Initialize GNULIB_ENVIRON and
HAVE_DECL_ENVIRON.
* modules/unistd (Makefile.am): Substitute also GNULIB_ENVIRON and
HAVE_DECL_ENVIRON.
* doc/posix-functions/environ.texi: Mention module 'environ'. Remove
wrong claim that 'environ' is missing on some systems.
* modules/execute (Depends-on): Add environ.
* lib/execute.c (environ): Remove fallback declaration.
* modules/pipe (Depends-on): Add environ.
* lib/pipe.c (environ): Remove fallback declaration.
* modules/setenv (Depends-on): Add environ.
* lib/setenv.c (environ): Remove fallback declaration.
* modules/unsetenv (Depends-on): Add environ.
* lib/unsetenv.c (environ): Remove fallback declaration.
* m4/setenv.m4 (gt_CHECK_VAR_DECL): Remove macro. Moved to
m4/environ.m4.
(gl_PREREQ_SETENV): Require gl_ENVIRON instead of testing for environ.
(gl_PREREQ_UNSETENV): Likewise.

============================== modules/environ ===============================
Description:
environ variable: storage of environment variables.

Files:
m4/environ.m4

Depends-on:
unistd

configure.ac:
gl_ENVIRON
gl_UNISTD_MODULE_INDICATOR([environ])

Makefile.am:

Include:
#include <unistd.h>

License:
LGPLv2+

Maintainer:
Bruno Haible

=============================== m4/environ.m4 ================================
# environ.m4 serial 1
dnl Copyright (C) 2001-2004, 2006-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_ENVIRON],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
dnl Persuade glibc <unistd.h> to declare environ.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
gt_CHECK_VAR_DECL([#include <unistd.h>], environ)
if test $gt_cv_var_environ_declaration != yes; then
HAVE_DECL_ENVIRON=0
fi
])

# Check if a variable is properly declared.
# gt_CHECK_VAR_DECL(includes,variable)
AC_DEFUN([gt_CHECK_VAR_DECL],
[
define([gt_cv_var], [gt_cv_var_]$2[_declaration])
AC_MSG_CHECKING([if $2 is properly declared])
AC_CACHE_VAL(gt_cv_var, [
AC_TRY_COMPILE([$1
extern struct { int foo; } $2;],
[$2.foo = 1;],
gt_cv_var=no,
gt_cv_var=yes)])
AC_MSG_RESULT($gt_cv_var)
if test $gt_cv_var = yes; then
AC_DEFINE([HAVE_]translit($2, [a-z], [A-Z])[_DECL], 1,
[Define if you have the declaration of $2.])
fi
undefine([gt_cv_var])
])
*** doc/posix-functions/environ.texi.orig 2008-02-24 16:38:57.000000000 +0100
--- doc/posix-functions/environ.texi 2008-02-24 16:21:51.000000000 +0100
***************
*** 4,20 ****

POSIX specification: @url{http://www.opengroup.org/susv3xsh/environ.html}

! Gnulib module: ---

Portability problems fixed by Gnulib:
@itemize
- @end itemize
-
- Portability problems not fixed by Gnulib:
- @itemize
@item
! This variable is missing on some platforms:
! MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, OSF/1 5.1, Cygwin.
@item
On MacOS X 10, this variable is not declared. Up to MacOS X 10.4, one can use
@smallexample
--- 4,17 ----

POSIX specification: @url{http://www.opengroup.org/susv3xsh/environ.html}

! Gnulib module: environ

Portability problems fixed by Gnulib:
@itemize
@item
! POSIX does not require this variable to be declared, and it is indeed not
! declared on some platforms:
! MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, Solaris 10.
@item
On MacOS X 10, this variable is not declared. Up to MacOS X 10.4, one can use
@smallexample
***************
*** 27,32 ****
--- 24,33 ----
#define environ (*_NSGetEnviron())
@end smallexample
This works at least on MacOS X 10.3 and newer.
+ @end itemize
+
+ Portability problems not fixed by Gnulib:
+ @itemize
@item
The address of this variable is not a compile-time constant on some platforms:
mingw.
*** lib/execute.c.orig 2008-02-24 16:38:57.000000000 +0100
--- lib/execute.c 2008-02-24 15:56:21.000000000 +0100
***************
*** 1,5 ****
/* Creation of autonomous subprocesses.
! Copyright (C) 2001-2004, 2006-2007 Free Software Foundation, Inc.
Written by Bruno Haible <***@clisp.cons.org>, 2001.

This program is free software: you can redistribute it and/or modify
--- 1,5 ----
/* Creation of autonomous subprocesses.
! Copyright (C) 2001-2004, 2006-2008 Free Software Foundation, Inc.
Written by Bruno Haible <***@clisp.cons.org>, 2001.

This program is free software: you can redistribute it and/or modify
***************
*** 54,63 ****

#endif

- #if ! HAVE_ENVIRON_DECL
- extern char **environ;
- #endif
-
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
--- 54,59 ----
*** lib/pipe.c.orig 2008-02-24 16:38:57.000000000 +0100
--- lib/pipe.c 2008-02-24 15:56:33.000000000 +0100
***************
*** 1,5 ****
/* Creation of subprocesses, communicating via pipes.
! Copyright (C) 2001-2004, 2006-2007 Free Software Foundation, Inc.
Written by Bruno Haible <***@clisp.cons.org>, 2001.

This program is free software: you can redistribute it and/or modify
--- 1,5 ----
/* Creation of subprocesses, communicating via pipes.
! Copyright (C) 2001-2004, 2006-2008 Free Software Foundation, Inc.
Written by Bruno Haible <***@clisp.cons.org>, 2001.

This program is free software: you can redistribute it and/or modify
***************
*** 53,62 ****

#endif

- #if ! HAVE_ENVIRON_DECL
- extern char **environ;
- #endif
-
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
--- 53,58 ----
*** lib/setenv.c.orig 2008-02-24 16:38:57.000000000 +0100
--- lib/setenv.c 2008-02-24 15:58:00.000000000 +0100
***************
*** 1,4 ****
! /* Copyright (C) 1992,1995-1999,2000-2003,2005-2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.

This program is free software: you can redistribute it and/or modify
--- 1,4 ----
! /* Copyright (C) 1992,1995-1999,2000-2003,2005-2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.

This program is free software: you can redistribute it and/or modify
***************
*** 40,48 ****

#if !_LIBC
# define __environ environ
- # ifndef HAVE_ENVIRON_DECL
- extern char **environ;
- # endif
#endif

#if _LIBC
--- 40,45 ----
*** lib/unistd.in.h.orig 2008-02-24 16:38:57.000000000 +0100
--- lib/unistd.in.h 2008-02-24 16:28:02.000000000 +0100
***************
*** 1,5 ****
/* Substitute for and wrapper around <unistd.h>.
! Copyright (C) 2004-2007 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
--- 1,5 ----
/* Substitute for and wrapper around <unistd.h>.
! Copyright (C) 2004-2008 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
***************
*** 86,91 ****
--- 86,111 ----
#endif


+ #if @GNULIB_ENVIRON@
+ # if !@HAVE_DECL_ENVIRON@
+ /* Set of environment variables and values. An array of strings of the form
+ "VARIABLE=VALUE", terminated with a NULL. */
+ # if defined __APPLE__ && defined __MACH__
+ # include <crt_externs.h>
+ # define environ (*_NSGetEnviron ())
+ # else
+ extern char **environ;
+ # endif
+ # endif
+ #elif defined GNULIB_POSIXCHECK
+ # undef environ
+ # define environ \
+ (GL_LINK_WARNING ("environ is unportable - " \
+ "use gnulib module environ for portability"), \
+ environ)
+ #endif
+
+
#if @GNULIB_FCHDIR@
# if @REPLACE_FCHDIR@

*** lib/unsetenv.c.orig 2008-02-24 16:38:57.000000000 +0100
--- lib/unsetenv.c 2008-02-24 15:58:17.000000000 +0100
***************
*** 1,4 ****
! /* Copyright (C) 1992,1995-1999,2000-2002,2005-2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.

This program is free software: you can redistribute it and/or modify
--- 1,4 ----
! /* Copyright (C) 1992,1995-1999,2000-2002,2005-2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.

This program is free software: you can redistribute it and/or modify
***************
*** 29,37 ****

#if !_LIBC
# define __environ environ
- # ifndef HAVE_ENVIRON_DECL
- extern char **environ;
- # endif
#endif

#if _LIBC
--- 29,34 ----
*** m4/setenv.m4.orig 2008-02-24 16:38:57.000000000 +0100
--- m4/setenv.m4 2008-02-24 16:30:00.000000000 +0100
***************
*** 1,5 ****
! # setenv.m4 serial 9
! dnl Copyright (C) 2001-2004, 2006-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
--- 1,5 ----
! # setenv.m4 serial 10
! dnl Copyright (C) 2001-2004, 2006-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
***************
*** 53,90 ****
fi
])

- # Check if a variable is properly declared.
- # gt_CHECK_VAR_DECL(includes,variable)
- AC_DEFUN([gt_CHECK_VAR_DECL],
- [
- define([gt_cv_var], [gt_cv_var_]$2[_declaration])
- AC_MSG_CHECKING([if $2 is properly declared])
- AC_CACHE_VAL(gt_cv_var, [
- AC_TRY_COMPILE([$1
- extern struct { int foo; } $2;],
- [$2.foo = 1;],
- gt_cv_var=no,
- gt_cv_var=yes)])
- AC_MSG_RESULT($gt_cv_var)
- if test $gt_cv_var = yes; then
- AC_DEFINE([HAVE_]translit($2, [a-z], [A-Z])[_DECL], 1,
- [Define if you have the declaration of $2.])
- fi
- ])
-
# Prerequisites of lib/setenv.c.
AC_DEFUN([gl_PREREQ_SETENV],
[
AC_REQUIRE([AC_FUNC_ALLOCA])
AC_CHECK_HEADERS_ONCE(unistd.h)
AC_CHECK_HEADERS(search.h)
AC_CHECK_FUNCS(tsearch)
- gt_CHECK_VAR_DECL([#include <unistd.h>], environ)
])

# Prerequisites of lib/unsetenv.c.
AC_DEFUN([gl_PREREQ_UNSETENV],
[
AC_CHECK_HEADERS_ONCE(unistd.h)
- gt_CHECK_VAR_DECL([#include <unistd.h>], environ)
])
--- 53,71 ----
fi
])

# Prerequisites of lib/setenv.c.
AC_DEFUN([gl_PREREQ_SETENV],
[
AC_REQUIRE([AC_FUNC_ALLOCA])
+ AC_REQUIRE([gl_ENVIRON])
AC_CHECK_HEADERS_ONCE(unistd.h)
AC_CHECK_HEADERS(search.h)
AC_CHECK_FUNCS(tsearch)
])

# Prerequisites of lib/unsetenv.c.
AC_DEFUN([gl_PREREQ_UNSETENV],
[
+ AC_REQUIRE([gl_ENVIRON])
AC_CHECK_HEADERS_ONCE(unistd.h)
])
*** m4/unistd_h.m4.orig 2008-02-24 16:38:57.000000000 +0100
--- m4/unistd_h.m4 2008-02-24 16:31:48.000000000 +0100
***************
*** 1,5 ****
! # unistd_h.m4 serial 10
! dnl Copyright (C) 2006-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
--- 1,5 ----
! # unistd_h.m4 serial 11
! dnl Copyright (C) 2006-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
***************
*** 34,39 ****
--- 34,40 ----
[
GNULIB_CHOWN=0; AC_SUBST([GNULIB_CHOWN])
GNULIB_DUP2=0; AC_SUBST([GNULIB_DUP2])
+ GNULIB_ENVIRON=0; AC_SUBST([GNULIB_ENVIRON])
GNULIB_FCHDIR=0; AC_SUBST([GNULIB_FCHDIR])
GNULIB_FTRUNCATE=0; AC_SUBST([GNULIB_FTRUNCATE])
GNULIB_GETCWD=0; AC_SUBST([GNULIB_GETCWD])
***************
*** 49,54 ****
--- 50,56 ----
HAVE_GETPAGESIZE=1; AC_SUBST([HAVE_GETPAGESIZE])
HAVE_READLINK=1; AC_SUBST([HAVE_READLINK])
HAVE_SLEEP=1; AC_SUBST([HAVE_SLEEP])
+ HAVE_DECL_ENVIRON=1; AC_SUBST([HAVE_DECL_ENVIRON])
HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
HAVE_OS_H=0; AC_SUBST([HAVE_OS_H])
HAVE_SYS_PARAM_H=0; AC_SUBST([HAVE_SYS_PARAM_H])
*** modules/execute.orig 2008-02-24 16:38:57.000000000 +0100
--- modules/execute 2008-02-24 15:42:34.000000000 +0100
***************
*** 16,21 ****
--- 16,22 ----
stdbool
strpbrk
unistd
+ environ

configure.ac:
gl_EXECUTE
*** modules/pipe.orig 2008-02-24 16:38:57.000000000 +0100
--- modules/pipe 2008-02-24 15:42:25.000000000 +0100
***************
*** 16,21 ****
--- 16,22 ----
stdbool
strpbrk
unistd
+ environ

configure.ac:
gl_PIPE
*** modules/setenv.orig 2008-02-24 16:38:57.000000000 +0100
--- modules/setenv 2008-02-24 15:55:42.000000000 +0100
***************
*** 10,15 ****
--- 10,16 ----
malloca
alloca-opt
unistd
+ environ

configure.ac:
gl_FUNC_SETENV
*** modules/unistd.orig 2008-02-24 16:38:57.000000000 +0100
--- modules/unistd 2008-02-24 16:33:40.000000000 +0100
***************
*** 25,30 ****
--- 25,31 ----
-e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
-e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \
-e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \
+ -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \
-e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
-e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
-e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
***************
*** 39,44 ****
--- 40,46 ----
-e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
-e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
-e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
+ -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \
-e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
-e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
-e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
*** modules/unsetenv.orig 2008-02-24 16:38:57.000000000 +0100
--- modules/unsetenv 2008-02-24 15:55:50.000000000 +0100
***************
*** 8,13 ****
--- 8,14 ----
Depends-on:
stdlib
unistd
+ environ

configure.ac:
gl_FUNC_UNSETENV
Peter O'Gorman
2008-02-24 15:44:15 UTC
Permalink
Post by Bruno Haible
* doc/posix-functions/environ.texi: Document the MacOS X problem.
*** doc/posix-functions/environ.texi.orig 2008-02-24 15:26:50.000000000 +0100
--- doc/posix-functions/environ.texi 2008-02-24 15:25:16.000000000 +0100
***************
*** 16,21 ****
--- 16,33 ----
MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, IRIX 6.5, OSF/1 5.1, Cygwin.
@item
+ On MacOS X 10, this variable is not declared. Up to MacOS X 10.4, one can use
+ extern char **environ;
+ to get the variable declared. This does not work any more, however, in
+ shared libraries on MacOS X 10.5. Here is a workaround: Instead, one can use
+ #include <crt_externs.h>
+ #define environ (*_NSGetEnviron())
+ This works at least on MacOS X 10.3 and newer.
Hi Bruno,

crt_externs.h and _NSGetEnviron works on all released versions of Mac OS X.

The environ symbol is available to every application, it is in the c
startup object crt1.o (on 10.5 crt1.10.5.o), but the static linker, when
set to not allow any undefined symbols (the default) does not know about
it when creating a shared library (because crt1.0 is only added when
creating an executable), so linking will fail with undefined references
to _environ in that case.

A library which allows undefined symbols (the GNU libtool default) will
not see this problem.

Thanks for writing this up, it is good to have the crt_externs.h
solution in the docs.

Peter
--
Peter O'Gorman
http://pogma.com
Bruno Haible
2008-02-24 16:20:40 UTC
Permalink
Post by Peter O'Gorman
crt_externs.h and _NSGetEnviron works on all released versions of Mac OS X.
Thanks for this info. I'm updating the doc (see below).
Post by Peter O'Gorman
The environ symbol is available to every application, it is in the c
startup object crt1.o (on 10.5 crt1.10.5.o), but the static linker, when
set to not allow any undefined symbols (the default) does not know about
it when creating a shared library (because crt1.0 is only added when
creating an executable), so linking will fail with undefined references
to _environ in that case.
A library which allows undefined symbols (the GNU libtool default) will
not see this problem.
Well, there must be something different between MacOS X 10.[34] and 10.5.
The cited references mention a problem that cropped up with 10.5, not
earlier.

Attached you find the test script that I used to verify that both declarations
work on 10.3. (I cannot test 10.4 or 10.5.)

Bruno


--- doc/posix-functions/environ.texi.orig 2008-02-24 17:13:56.000000000 +0100
+++ doc/posix-functions/environ.texi 2008-02-24 17:13:47.000000000 +0100
@@ -23,7 +23,7 @@
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
@end smallexample
-This works at least on MacOS X 10.3 and newer.
+This works at all versions of MacOS X.
@end itemize

Portability problems not fixed by Gnulib:


================================ fooshared.c ==================
#if 0
extern char **environ;
#else
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#endif
char *** environ_addr (void) { return &environ; }
===============================================================
================================= foo.c =======================
#include <stdio.h>
#include <unistd.h>
extern char ***environ_addr (void);
int main ()
{
printf ("%p\n", environ_addr());
{
char **env = *environ_addr();
if (env == NULL)
printf("env = NULL\n");
else {
char *s;
for (; (s = *env) && *s; env++)
printf ("%s\n", s);
}
}
return 0;
}
================================================================
$ libtool --mode=compile gcc -c fooshared.c
$ libtool --mode=link gcc -o libfoo.la fooshared.lo
$ gcc -c foo.c
$ libtool --mode=link gcc -o a.out foo.o libfoo.la
$ ./a.out
Peter O'Gorman
2008-02-24 16:43:50 UTC
Permalink
Post by Bruno Haible
Post by Peter O'Gorman
crt_externs.h and _NSGetEnviron works on all released versions of Mac OS X.
Thanks for this info. I'm updating the doc (see below).
Post by Peter O'Gorman
The environ symbol is available to every application, it is in the c
startup object crt1.o (on 10.5 crt1.10.5.o), but the static linker, when
set to not allow any undefined symbols (the default) does not know about
it when creating a shared library (because crt1.0 is only added when
creating an executable), so linking will fail with undefined references
to _environ in that case.
A library which allows undefined symbols (the GNU libtool default) will
not see this problem.
Well, there must be something different between MacOS X 10.[34] and 10.5.
The cited references mention a problem that cropped up with 10.5, not
earlier.
Attached you find the test script that I used to verify that both declarations
work on 10.3. (I cannot test 10.4 or 10.5.)
It is an old problem, e.g.
http://lists.apple.com/archives/Darwin-development/2003/Apr/msg00177.html

Here is me compiling your test on Mac OS X 10.5 (using the systems GNU
libtool 1.5.22):

mb:environs peter$ cat fooshared.c
#if 1
extern char **environ;
#else
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#endif
char *** environ_addr (void) { return &environ; }
mb:environs peter$ glibtool --mode=compile gcc -c fooshared.c
gcc -c fooshared.c -fno-common -DPIC -o .libs/fooshared.o
gcc -c fooshared.c -o fooshared.o >/dev/null 2>&1
mb:environs peter$ glibtool --mode=link gcc -o libfoo.la fooshared.lo
-rpath /no
texist
rm -fr .libs/libfoo.0.0.0.dylib .libs/libfoo.0.dylib .libs/libfoo.a
.libs/libfo
o.dylib .libs/libfoo.la .libs/libfoo.lai
gcc -dynamiclib ${wl}-undefined ${wl}dynamic_lookup -o
.libs/libfoo.0.0.0.dylib
.libs/fooshared.o -install_name /notexist/libfoo.0.dylib
-Wl,-compatibility_
version -Wl,1 -Wl,-current_version -Wl,1.0
(cd .libs && rm -f libfoo.0.dylib && ln -s libfoo.0.0.0.dylib
libfoo.0.dylib)
(cd .libs && rm -f libfoo.dylib && ln -s libfoo.0.0.0.dylib libfoo.dylib)
ar cru .libs/libfoo.a fooshared.o
ranlib .libs/libfoo.a
creating libfoo.la
(cd .libs && rm -f libfoo.la && ln -s ../libfoo.la libfoo.la)
mb:environs peter$ glibtool --mode=link gcc -o libfoo.la fooshared.lo
-rpath /no
texist -no-undefined
rm -fr .libs/libfoo.0.0.0.dylib .libs/libfoo.0.dylib .libs/libfoo.a
.libs/libfo
o.dylib .libs/libfoo.la .libs/libfoo.lai
gcc -dynamiclib -o .libs/libfoo.0.0.0.dylib .libs/fooshared.o
-install_name
/notexist/libfoo.0.dylib -Wl,-compatibility_version -Wl,1
-Wl,-current_version
-Wl,1.0
Undefined symbols:
"_environ", referenced from:
_environ$non_lazy_ptr in fooshared.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Peter
--
Peter O'Gorman
http://pogma.com
Bruno Haible
2008-02-24 17:59:08 UTC
Permalink
Post by Peter O'Gorman
glibtool --mode=link gcc -o libfoo.la fooshared.lo
And does the executable that you create by linking against this library
work on MacOS X 10.5? It works on 10.3.

Bruno
Peter O'Gorman
2008-02-24 18:20:58 UTC
Permalink
Post by Bruno Haible
Post by Peter O'Gorman
glibtool --mode=link gcc -o libfoo.la fooshared.lo
And does the executable that you create by linking against this library
work on MacOS X 10.5? It works on 10.3.
Yes, it works.

Thank you,
Peter
--
Peter O'Gorman
http://pogma.com
Loading...