diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,7 @@
+### 1.5.2
+
+- Foreign calls were extracted in a separate module.
+
 ### 1.5.1
 
 - Fixed dynamic linker errors when building haddocks.
diff --git a/NgxExport/Log.hs b/NgxExport/Log.hs
--- a/NgxExport/Log.hs
+++ b/NgxExport/Log.hs
@@ -14,9 +14,7 @@
 --
 -----------------------------------------------------------------------------
 
-module NgxExport.Log (module NgxExport.Log.Base
-                     ,module Gen
-                     ) where
+module NgxExport.Log (module NgxExport.Log.Base, module Gen) where
 
 import           NgxExport
 
diff --git a/NgxExport/Log/Base.hs b/NgxExport/Log/Base.hs
--- a/NgxExport/Log/Base.hs
+++ b/NgxExport/Log/Base.hs
@@ -1,45 +1,19 @@
-{-# LANGUAGE CPP, ForeignFunctionInterface, OverloadedStrings #-}
+{-# LANGUAGE OverloadedStrings #-}
 
-module NgxExport.Log.Base (LogLevel (..)
-                          ,logG
-                          ,logM
-                          ,logR
-                          ) where
+module NgxExport.Log.Base (LogLevel (..), logG, logM, logR) where
 
 import           NgxExport
 import           NgxExport.Tools
 
+import           NgxExport.Log.CLog
+
 import           Data.ByteString (ByteString)
 import qualified Data.ByteString.Char8 as C8
 import qualified Data.ByteString.Unsafe as B
-import           Foreign.C.Types
-import           Foreign.C.String
 import           Foreign.Ptr
 import           Control.Arrow
 import           Data.Char
 
--- 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 :: Ptr () -> CUIntPtr -> CString -> CSize -> IO (); \
-f _ _ _ _ = return ()
-#endif
-
 -- | Log severity levels.
 --
 -- Being applied to a certain constructor, function 'fromEnum' returns the value
@@ -54,13 +28,6 @@
               | LogInfo
               | LogDebug deriving Enum
 
-#if defined(__GHCIDE__) || defined(__HADDOCK_VERSION__)
-C_LOG_STUB(c_log)
-#else
-foreign import ccall unsafe "plugin_ngx_http_haskell_log"
-    c_log :: Ptr () -> CUIntPtr -> CString -> CSize -> IO ()
-#endif
-
 -- | Logs a message to the global Nginx log.
 logG :: LogLevel        -- ^ Log severity level
      -> ByteString      -- ^ Log message
@@ -70,13 +37,6 @@
     c <- ngxCyclePtr
     B.unsafeUseAsCStringLen msg $
         \(x, i) -> c_log c (fromIntegral $ fromEnum l) x $ fromIntegral i
-
-#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 :: Ptr () -> CUIntPtr -> CString -> CSize -> IO ()
-#endif
 
 -- | Logs a message to the request's Nginx log.
 --
diff --git a/NgxExport/Log/CLog.hs b/NgxExport/Log/CLog.hs
new file mode 100644
--- /dev/null
+++ b/NgxExport/Log/CLog.hs
@@ -0,0 +1,42 @@
+{-# 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
+
diff --git a/ngx-export-log.cabal b/ngx-export-log.cabal
--- a/ngx-export-log.cabal
+++ b/ngx-export-log.cabal
@@ -1,5 +1,5 @@
 name:                  ngx-export-log
-version:               1.5.1
+version:               1.5.2
 synopsis:    Native Nginx logging from configuration files and Haskell handlers
 description: Native Nginx logging from configuration files and Haskell handlers.
         .
@@ -27,6 +27,7 @@
 
   exposed-modules:     NgxExport.Log
   other-modules:       NgxExport.Log.Base
+                     , NgxExport.Log.CLog
                      , NgxExport.Log.Gen
 
   ghc-options:        -Wall
