Re: environ on MacOS X
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 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 [EMAIL PROTECTED] -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.5 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHwYFF84KuGfSFAYARAr5tAJ9lGgO0YB64GQkMYpOEOgmCmcWAEACfXA+z 8pSus4zDUooCpc9Nhci5GB4= =e8Ao -END PGP SIGNATURE-
Re: environ on MacOS X
Bruno Haible wrote: 2008-02-24 Bruno Haible [EMAIL PROTECTED] * doc/posix-functions/environ.texi: Document the MacOS X problem. *** doc/posix-functions/environ.texi.orig 2008-02-24 15:26:50.0 +0100 --- doc/posix-functions/environ.texi 2008-02-24 15:25:16.0 +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. 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
Re: environ on MacOS X
Peter O'Gorman wrote: 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). 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.0 +0100 +++ doc/posix-functions/environ.texi2008-02-24 17:13:47.0 +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
Re: environ on MacOS X
Bruno Haible wrote: Peter O'Gorman wrote: 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). 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 21 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
Re: environ on MacOS X
Peter O'Gorman wrote: 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
Re: environ on MacOS X
Bruno Haible wrote: Peter O'Gorman wrote: 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