Ticket #2458 (closed bug: fixed)

Opened 1 year ago

Last modified 10 months ago

GHC MacOS X Leopard build succeeds, but ghci complains about: unknown symbol `_environ'

Reported by: IgorBoehm Assigned to: igloo
Priority: normal Milestone: 6.10.1
Component: libraries/base Version: 6.9
Severity: major Keywords: environ
Cc: igor@bytelabs.org Difficulty: Unknown
Test Case: Operating System: MacOS X
Architecture: x86

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:

Change History

08/30/08 17:50:11 changed by igloo

  • owner set to igloo.
  • difficulty set to Unknown.
  • milestone set to 6.10.1.

08/31/08 04:35:37 changed by igloo

  • status changed from new to closed.
  • resolution set to fixed.

Hmm, this works for me; presumably fixed by Cabal's Distribution.Simple.GHC.stripExe doing:

    args = path : case buildOS of
       OSX -> ["-x"] -- By default, stripping the ghc binary on at least
                     -- some OS X installations causes:
                     --     HSbase-3.0.o: unknown symbol `_environ'"
                     -- The -x flag fixes that.
       _   -> []

so I'm closing this ticket. Please reopen it if you still think there's a problem.