
On Fri, Feb 15, 2013 at 9:05 AM, Andrew Cowie < andrew@operationaldynamics.com> wrote:
I've got a piece of code that looks like this:
baselineContextSSL :: IO SSLContext baselineContextSSL = do ctx <- SSL.context SSL.contextSetDefaultCiphers ctx #if defined __MACOSX__ SSL.contextSetVerificationMode ctx SSL.VerifyNone #elif defined __WIN32__ SSL.contextSetVerificationMode ctx SSL.VerifyNone #else SSL.contextSetCADirectory ctx "/etc/ssl/certs" SSL.contextSetVerificationMode ctx $ SSL.VerifyPeer True True Nothing #endif return ctx
all very nice (this being necessary because apparently the non-free operating systems don't store their certs in a reliably discoverable place; bummer).
That, however, is not the problem. After all, this sort of thing is what #ifdefs are for. The problem is needing to get an appropriate symbol based on what OS you're using defined.
I naively assumed there would be __LINUX__ and __MACOSX__ and __WIN32__ defined by GHC because, well, that's just the sort of wishful thinking that powers the universe.
So my question is: what's an appropriate Haskell mechanism for building code that is OS / arch / distro specific? It's not like I have autoconf running generating me a config.h I could #include, right?
This feels simple and an appropriate use of CPP; even the symbol names look just about like what I would have expected; stackoverflow said so, must be true. Just need to get the right symbol defined at build time.
Any suggestions?
Things like this have been the bane of Unix programmers for decades; the C pre-processor has always been kind of a hack, mostly because of things like #ifdef and the huge messes they create. For more on why this is so bad from the Unix side of the house, see: http://static.usenix.org/publications/library/proceedings/sa92/spencer.pdf A better solution is to define a standard interface called by your code and a per-system module that implements that interface and does the things you need, then simply include one for the appropriate system at compile time. E.g., a Darwin and Win32 modules that provide a function that calls 'SSL.contextSetVerificationMode ctx SSL.VerifyNone', and some kind of Generic module that provides a function that does the rest. - Dan C.