GHC:插入编译日期

Mat*_*hid 17 haskell ghc

我以为会有这个问题,但我找不到一个.

我希望我的程序打印出它编译的日期.设置它的最简单方法是什么?

我可以想到几种可能性,但它们都不是你所谓的"简单".理想情况下,我希望每次运行时ghc --make Foo都可以Foo打印出编译日期.

想到的各种不容易的可能性:

  • 学习模板Haskell.弄清楚如何使用Data.Time来获取今天的日期.找到一种如何将其转换为字符串的方法.(现在我的程序需要TH才能工作.我还需要说服它每次重新编译该模块,否则我得到该模块的编译日期[永不改变]而不是整个程序.)

  • 编写一个shell脚本,生成一个包含系统日期的小Haskell模块.(现在我必须使用那个shell脚本而不是直接编译我的程序.而且,Windows上的shell脚本还有很多不足之处!)

  • 坐下来写一些Haskell代码,生成一个包含日期的小Haskell模块.(比以前的想法更便携 - 但仍需要额外的构建步骤或打印日期不正确.)

  • 可能有一些方法可以通过Cabal来做到这一点 - 但我真的想要打包这个小程序只是为了获得日期工具吗?

有没有人有更简单的建议?

小智 27

使用模板Haskell相对简单.你只需要:

  1. 在Template Haskell monad中运行IO操作:

    runIO :: IO a -> Exp a
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后创建一个字符串文字:

    stringE :: String -> ExpQ
    
    Run Code Online (Sandbox Code Playgroud)
  3. 把整个表达式放在一个quasiquote中.

    $( ... )
    
    Run Code Online (Sandbox Code Playgroud)

该程序将打印其编译时间:

{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.TH
import Data.Time

main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime))
Run Code Online (Sandbox Code Playgroud)

您可以将相关片段放入导入所有其他模块的模块中,以确保重新编译它.

或者从您的版本控制系统中获取当前版本信息.请参阅:TemplateHaskell和IO


小智 9

预处理器有助于定义__DATE____TIME__宏(就像在C中一样),所以这适用:

{-# LANGUAGE CPP #-}
main = putStrLn (__DATE__ ++ " " ++ __TIME__)
Run Code Online (Sandbox Code Playgroud)

这可能比Michal对Template Haskell的建议更简单,但不允许您选择日期的格式.