Ticket #2458 (closed bug: fixed)
Unknown symbol `_environ' on MacOS X
| Reported by: | IgorBoehm | Owned by: | |
|---|---|---|---|
| Priority: | high | Milestone: | 7.2.1 |
| Component: | libraries/base | Version: | 6.10.1 |
| Keywords: | environ | Cc: | igor@…, fontaine@…, pho@… |
| Operating System: | MacOS X | Architecture: | x86 |
| Type of failure: | GHC rejects valid program | Difficulty: | Unknown |
| Test Case: | Blocked By: | ||
| Blocking: | Related Tickets: |
Description
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 ( man environ(7) see last paragraph in section PROGRAMMING).
Two Libraries are affected by this - namely base and unix. Both of these Libraries implement (duplicate code) access to environ:
- 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; } - 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 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 unix/include/HsUnix.h:
//extern char **environ; #include <crt_externs.h> INLINE char **__hsunix_environ (void) { return (*_NSGetEnviron()); }
- Hack for 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:

