id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
2458,Unknown symbol `_environ' on MacOS X,IgorBoehm,,"Shared libraries and bundles on MacOS X Leopard don't have direct access to environ (i.e. extern char **environ), which is only available to the loader ld when a complete program is being linked. If direct access to environ is needed, the _NSGetEnviron() routine, defined in <crt_externs.h> can be used to retrieve the address of environ at runtime ([http://developer.apple.com/documentation/Darwin/Reference/ManPages/man7/environ.7.html man environ(7)] see last paragraph in section PROGRAMMING).

Two Libraries are affected by this - namely [http://darcs.haskell.org/packages/base/ base] and [http://darcs.haskell.org/packages/unix/ unix]. Both of these Libraries implement (duplicate code) access to  environ:
 * [http://darcs.haskell.org/packages/base/include/HsBase.h base/include/HsBase.h]:
{{{
* ToDo: write a feature test that doesn't assume 'environ' to
*    be in scope at link-time. */
extern char** environ;
INLINE char **__hscore_environ() { return environ; }
}}}
 * [http://darcs.haskell.org/packages/unix/include/HsUnix.h unix/include/HsUnix.h]
{{{
extern char **environ;
}}}

Unfortunately this does not work on MaxOS X Leopard with XCode 3.0. My temporary workaround was to comment out the current definition of environ in the header files and add the following instead:
 * Hack for [http://darcs.haskell.org/packages/base/include/HsBase.h base/include/HsBase.h]:
{{{
/* ToDo: write a feature test that doesn't assume 'environ' to
 *    be in scope at link-time. */
//extern char **environ;
//INLINE char **__hscore_environ() { return environ; }
#include <crt_externs.h>
INLINE char **__hscore_environ(void) { return (*_NSGetEnviron()); }
}}}

 * Hack for [http://darcs.haskell.org/packages/unix/include/HsUnix.h unix/include/HsUnix.h]:
{{{
//extern char **environ;
#include <crt_externs.h>
INLINE char **__hsunix_environ (void) { return (*_NSGetEnviron()); }
}}}

 * Hack for [http://darcs.haskell.org/packages/unix/System/Posix/Env.hsc unix/System/Posix/Env.hsc]:
{{{
--getEnvironmentPrim :: IO [String]
--getEnvironmentPrim = do
--  c_environ <- peek c_environ_p
--  arr <- peekArray0 nullPtr c_environ
--  mapM peekCString arr
--
--foreign import ccall unsafe ""&environ""
--    c_environ_p :: Ptr (Ptr CString)
getEnvironmentPrim :: IO [String]
getEnvironmentPrim = do
  c_environ <- c_environ_p
  arr <- peekArray0 nullPtr c_environ
  mapM peekCString arr

foreign import ccall unsafe ""__hsunix_environ""
  c_environ_p :: IO (Ptr CString)
}}}

Unfortunately I do not know GHC well enough to propose a clean patch. With these 'hacks' ghc compiled from source on MacOS X Leopard with XCode 3.0 works well. It would also probably be good to get rid of the code duplication in the base and unix libraries.

Shall I open another Ticket for libraries/unix?

References:
 * [http://developer.apple.com/documentation/Darwin/Reference/ManPages/man7/environ.7.html environ man page]
 * [http://lists.apple.com/archives/Java-dev/2007/Dec/msg00096.html response to similar problem on Apple Mailing List]",bug,closed,high,7.2.1,libraries/base,6.10.1,fixed,environ,igor@… fontaine@… pho@…,MacOS X,x86,GHC rejects valid program,Unknown,,,,
