编译器开关打开/关闭调试信息?

问题描述 投票:10回答:3

好的,所以这是一个简单的问题。我写了一个函数debug :: String -> IO ()。我想设置一下,这样当我以一种方式编译我的程序时,这个函数会写入标准错误,如果我以另一种方式编译我的程序,这个函数就变成了无操作。是否有一些简单的编译时间切换来做到这一点?或者我必须自己实施一些东西?

haskell ghc
3个回答
11
投票

我不认为涉及trace是解决这个问题的正确方法。

相反,您可以使用预处理器来禁用/启用调试消息。将以下内容放在一个单独的文件中:

{-# LANGUAGE CPP #-}
import System.IO

debug :: String -> IO ()
debug message =
#ifdef DEBUG
  hPutStrLn stderr message
#else
  return ()
#endif

{-# LANGUAGE CPP #-}行为当前文件启用C预处理器。然后,您可以使用ghc -DDEBUGghc编译文件,无需调试。


9
投票

您可以使用CPP预处理器和#ifdef执行此操作。

  1. 首先,使用#ifdef在函数的两个版本之间进行选择。 {-# LANGUAGE CPP #-} module Logging (debug) where debug :: String -> IO () #ifdef DEBUG debug = putStrLn #else debug _ = return () #endif
  2. 然后,在.cabal文件中添加一个标志来控制它。 ... flag debug description: Enable debug logging default: False executable foo -- or library if flag(debug) cpp-options: -DDEBUG ...
  3. 最后,要启用调试,请在配置时使用-f启用该标志: $ cabal configure -f debug

1
投票

为了补充这里给出的优秀答案,我想提一下这种方法,以防人们(像我一样)使用最新版本的stackhpack

package.yaml文件中,我添加了以下内容:

  flags:
    debug: # Or whatever name you want to give to the flag
      description: Enable debug
       manual: True
       default: False

   when:
     - condition: flag(debug)
       cpp-options:  -DDEBUG

然后我建议使用来自traceIODebug.TraceNoTrace,以便在没有traceIO标志的情况下编译代码时debug将无效:

{-# LANGUAGE CPP #-}

-- ...

#ifdef DEBUG
import Debug.Trace
#else
import Debug.NoTrace
#endif              

-- ...
someFunc :: IO ()
someFunc = do
    -- ...
    traceIO "Whatever..."

使用堆栈时,可以使用debug选项启用--flag标志:

stack build --flag "your-package:debug"

或者,如果您正在测试您的包裹:

stack build --flag "your-package:debug"

如果未使用hpack,则可以按照hammar的说明配置cabal文件。

© www.soinside.com 2019 - 2024. All rights reserved.