{-# LANGUAGE CPP, ForeignFunctionInterface #-} module NgxExport.Log.CLog where import Foreign.C.Types import Foreign.C.String import Foreign.Ptr type CLogType = Ptr () -> CUIntPtr -> CString -> CSize -> IO () -- Some tools such as hls, haddock, and ghci run interactive linking against C -- functions plugin_ngx_http_haskell_log() and plugin_ngx_http_haskell_log_r() -- when loading Log.hs. In Log.hs, TH declarations from Log/Gen.hs which make -- calls to those C functions, get instantiated. Obviously, linking fails as -- soon as we don't have a library to expose the functions because such a -- library is built by Nginx and we don't want to use Nginx at this step. -- -- In this workaround, the C functions get replaced by stubs when running by -- hls or haddock. This prevents interactive linking in Log.hs. It's easy to -- detect that the code is being run by hls or haddock: the tools define their -- own C macro declarations __GHCIDE__ and __HADDOCK_VERSION__ respectively. To -- prevent interactive linking in ghci, pass one of the two macro declarations -- in an appropriate option, e.g. -- -- cabal repl --ghc-options=-D__GHCIDE__ --repl-options=-fobject-code #if defined(__GHCIDE__) || defined(__HADDOCK_VERSION__) #define C_LOG_STUB(f) f :: CLogType; f _ _ _ _ = return () #endif #if defined(__GHCIDE__) || defined(__HADDOCK_VERSION__) C_LOG_STUB(c_log) #else foreign import ccall unsafe "plugin_ngx_http_haskell_log" c_log :: CLogType #endif #if defined(__GHCIDE__) || defined(__HADDOCK_VERSION__) C_LOG_STUB(c_log_r) #else foreign import ccall unsafe "plugin_ngx_http_haskell_log_r" c_log_r :: CLogType #endif