On OS X 10.5 (Leopard), compile/link HelloWorld: class HelloWorld { static public void main( String args[] ) { System.out.println( "Hello World!" ); } } as follows: gcj --main=HelloWorld HelloWorld.java Then strip and run a.out: strip a.out ./a.out dyld: Symbol not found: _environ Referenced from: /public/sw/gcc-4.3.2/Darwin-i386-buildhost2/lib/libgcj.9.dylib Expected in: flat namespace Trace/BPT trap Applying the following patch and rebuilding libgcj.9.dylib fixes the problem: --- libjava/java/lang/natPosixProcess.cc.orig 2009-01-08 17:06:14.000000000 +0000 +++ libjava/java/lang/natPosixProcess.cc 2009-01-09 21:13:34.000000000 +0000 @@ -54,7 +54,6 @@ using gnu::java::nio::channels::FileChannelImpl; using namespace java::lang; -extern char **environ; static char * new_string (jstring string) @@ -371,8 +370,16 @@ if (pid_tmp == 0) { // Child process, so remap descriptors, chdir and exec. - if (envp) - environ = env; + if (envp) { + for ( char *p, *e = *env; *e; e++ ) { + p=index(e, '='); + if ( p ) { + *p = '\0'; + setenv (e, p+1, 1); + *p = '='; + } + } + } // We ignore errors from dup2 because they should never occur. dup2 (outp[0], 0); More information: the OS X man page for environ(7) says: Shared libraries and bundles don't have direct access to environ, which is only available to the loader ld(1) when a complete program is being linked.
Created attachment 17075 [details] Output from gcj -v
Created attachment 17076 [details] Preprocessor output
Confirmed, though your patch is not portable really.
Thanks for confirming the problem. I know that what I did isn't particularly portable (although it would be fine on the systems that I work with). I vaguely remember something about setenv not being available on Solaris, but I haven't worked with Solaris for several years now. I'm hoping that someone with more experience than me of libgcj development and the range of supported OS's can use my information to submit a more robust fix. I'll keep an eye on this bug and help out if I can.
On Mac OS X (all versions), the correct fix is to use _NSGetEnviron() instead of extern variable environ, and to include <crt_externs.h>. Example of use: #include <stdlib.h> #include <string.h> #include <crt_externs.h> int main (void) { // Instead of: extern char **environ; #define environ (*_NSGetEnviron()) char **env = malloc (3 * sizeof(char *)); env[0] = strdup ("VAR1=this is variable one"); env[1] = strdup ("PATH=/dev/null"); env[2] = NULL; environ = env; system ("/usr/bin/env"); return 0; } (see http://www.gnu.org/software/gnulib/manual/html_node/environ.html) So, a possible patch (protecting target-specific code with #idef's; I don't know if that's the style libjava maintainers would like best) is: Index: java/lang/natPosixProcess.cc =================================================================== --- java/lang/natPosixProcess.cc (revision 159481) +++ java/lang/natPosixProcess.cc (working copy) @@ -54,7 +54,12 @@ using gnu::java::nio::channels::FileChannelImpl; using namespace java::lang; +#ifdef __APPLE__ +#include <crt_externs.h> +#define environ (*_NSGetEnviron()) +#else extern char **environ; +#endif static char * new_string (jstring string)
There's also some places where environ is used as an extern variable in libiberty that would need similar fixes; specifically in pex-unix.c and xmalloc.c.
(In reply to Eric Gallager from comment #6) > There's also some places where environ is used as an extern variable in > libiberty that would need similar fixes; specifically in pex-unix.c and > xmalloc.c. ...and it turns out that that is bug 63758, for reference... (sorry for the digression; I hadn't seen the other one previously...)
(In reply to Eric Gallager from comment #7) > (In reply to Eric Gallager from comment #6) > > There's also some places where environ is used as an extern variable in > > libiberty that would need similar fixes; specifically in pex-unix.c and > > xmalloc.c. > > ...and it turns out that that is bug 63758, for reference... (sorry for the > digression; I hadn't seen the other one previously...) ... which was marked as RESOLVED/FIXED on 2015-12-07. It would be great if someone committed a fix for this bug, using the same method.
Closing as won't fix as libgcj (and the java front-end) has been removed from the trunk.