2013-07-22 1 views
16

나는 이것에 대한 질문이 이미있을 것이라고 생각했지만 찾을 수는 없다.GHC : 컴파일 일 삽입

내 프로그램이 컴파일 된 날짜를 인쇄하고 싶습니다. 이를 설정하는 가장 쉬운 방법은 무엇입니까?

나는 여러 가지 가능성을 생각할 수 있지만 그 중 '쉬운'이라고 부르는 것은 없습니다. 이상적으로는 ghc --make Foo을 수행하고 실행할 때마다 Foo 출력을 인쇄 할 수있게하고 싶습니다. 마음에 봄

다양한 비 쉬운 가능성 :

  • 이 템플릿 하스켈을 알아보세요. Data.Time을 사용하여 오늘의 날짜를 가져 오는 방법을 파악하십시오. 이를 문자열로 변환하는 방법을 찾아보십시오. (이제는 내 프로그램이 작동하려면 TH가 필요하며, 매번 모듈을 다시 컴파일하도록 설득해야합니다. 그렇지 않으면 전체 프로그램이 아닌 해당 모듈의 컴파일 날짜가됩니다.

  • 시스템 날짜를 포함하는 작은 Haskell 모듈을 생성하는 쉘 스크립트를 작성하십시오. (지금은! 또한, Windows에서 쉘 스크립트는 많은 원하는 수 나뭇잎. 그 쉘 스크립트를 사용하기보다는 직접 내 프로그램을 컴파일해야한다)

  • 앉아 아래로 포함하는 작은 하스켈 모듈을 생성하는 일부 하스켈 코드를 작성 날짜. 이전 아이디어보다 더 이식성이 뛰어나지 만 추가 빌드 단계가 필요하거나 인쇄 된 날짜가 올바르지 않습니다.)

  • Cabal을 통해이 작업을 수행 할 수있는 방법이있을 수 있지만 실제로이 작은 프로그램을 패키지로 만들어야합니까? 데이트 시설을 얻으려고?

아무도 간단한 제안 사항이 있습니까?

+1

별칭 ghc는 "ghc -DNOW ="\ "'date' \" "''(Windows 셸을 찾는 방법은 모르겠다.) 모듈에'{- # LANGUAGE CPP # -}'와'now = NOW'를 사용합니다. 추악한 해킹은 더 많은 작업을 필요로하는보다 깨끗한 대안으로 당신을 밀어 넣을 정도로 추한 것일 수도 있습니다. –

+0

@DanielFischer 분명히 Windows 셸에는 명령 출력에서 ​​변수를 설정할 수있는 기능이 없습니다. 대신 stdin에서 텍스트를 읽는'SET/P VAR ='과 관련된 해킹을 사용해야합니다. 명령 출력을 파일로 파이프 한 다음 파이프로 다시 파이프하면 원하는 효과를 얻을 수 있지만 ... 예수! > _ < – MathematicalOrchid

+0

오, 와우. PowerShell에도 이러한 기능이 있습니까? –

답변

26

템플릿 Haskell을 사용하는 것은 비교적 간단합니다. 당신은 할 필요가 :

    템플릿 하스켈 모나드 내
  1. 실행 IO 작업 :

    stringE :: String -> ExpQ 
    
  2. 가 내 전체 표현식을 넣어 :

    runIO :: IO a -> Exp a 
    
  3. 그런 다음에 문자열 리터럴을 만들 준 쿼츠. 당신은 그것을 다시 컴파일되어 있는지 확인하기 위해 다른 모든 모듈을 가져 오는 모듈에 관련 조각을 넣을 수

    {-# LANGUAGE TemplateHaskell #-} 
    import Language.Haskell.TH 
    import Data.Time 
    
    main = print $(stringE =<< runIO (show `fmap` Data.Time.getCurrentTime)) 
    

    :

    $(...) 
    

이 프로그램은 컴파일 시간을 인쇄합니다.

또는 현재 버전 정보를 사용하십시오.TemplateHaskell and IO

+1

위대한 첫 번째 대답! 스택 오버플로에 오신 것을 환영합니다! – AndrewC

+0

이것은 가장 깨끗한 해결책 인 것 같습니다. 버전 문자열은 여러 곳에서 사용되므로이 코드를 별도의 모듈에 넣을 수 있습니다. 내가 예상하는 유일한 문제는 매번 버전 모듈을 다시 컴파일하는 것이다. 아마도 나는 TH를 사용하여 매번 소스 파일을 "만지기"를 할 수 있을까요? – MathematicalOrchid

+0

MathematicalOrchid : 그래서이 모듈이 다른 모든 최상위 모듈을 가져올 것을 제안했습니다. 아니면이 코드를'main' 모듈에 넣을 수도 있습니다. 그런 다음 항상 다시 컴파일됩니다. 다른 솔루션도 같은 문제를 가지고 있으며 소스 파일을 "만지려고"하는 것은 일부 사용자에게는 더러운 해결책으로 보일 수 있습니다. –

7

전처리가 유용하게 (단지 C처럼) __DATE____TIME__ 매크로를 정의하고, 그래서 이것은 작동 : 참조

{-# LANGUAGE CPP #-} 
main = putStrLn (__DATE__ ++ " " ++ __TIME__) 

이 템플릿 하스켈의 마이클의 제안보다는 아마 간단하지만 당신을 허용하지 않습니다 날짜 형식을 선택하십시오.

+0

물론, 프로그램에서 리터럴로 날짜를 얻으면 원하는대로 편집 할 수 있습니다. – muhmuhten

+0

나는 이것이 사실일지도 모르지 만 문서에 언급 된 내용을 찾을 수는 없었다. 또한''__DATE __ "'을 쓰는 것이 왜 효과가 없지만'__DATE__' 자체가 그렇게할만한 이유가 있습니까? – MathematicalOrchid

+0

GHC는 C 사전 처리기를 호출하기 때문에 거기에 설명되어있는 미리 정의 된 매크로를 찾을 수 있습니다. __DATE__, __TIME__, __FILE__ (소스 파일 이름)과'__LINE__ (소스 파일 줄 번호)만이 유용합니다. 마지막 두 개는 소스 위치를 포함하는 오류 매크로를 정의하는 데 유용합니다. ''__DATE __ "'가 작동하지 않는 이유는 전 처리기가 문자열 리터럴 내부의 매크로를 확장하지 않기 때문입니다. 게다가'__DATE__' 자체는 이미 문자열 리터럴로 확장됩니다. –