code

.cabal 파일의 빌드 종속 필드에서 중복을 줄이는 방법은 무엇입니까?

codestyles 2020. 12. 13. 09:34
반응형

.cabal 파일의 빌드 종속 필드에서 중복을 줄이는 방법은 무엇입니까?


다음은 .cabal 파일입니다.

Name:                myprogram
Version:             0.1
-- blah blah blah
Cabal-version:       >=1.9.2

Executable myprogram
  HS-source-dirs:       src
  Main-is:              Main.hs
  Build-depends:        attoparsec == 0.10.*,
                        base == 4.3.*,
                        -- long long list of packages

Test-Suite test
  HS-source-dirs:       test, src
  Type:                 exitcode-stdio-1.0
  Main-is:              Main.hs
  Build-depends:        attoparsec == 0.10.*,
                        base == 4.3.*,
                        -- long long list of packages
                        QuickCheck == 2.4.*

테스트 스위트에 대한 빌드 종속 패키지의 긴 목록을 "실행 파일과 동일하고 QuickCheck 추가"로 대체 할 수있는 방법이 있습니까?

편집 : 버전 정보.

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • 기갑 단 도서관 1.10.2.0
  • GHC 7.0.4
  • Haskell 플랫폼 2011.4.0.0

버전 2.2 Cabal은 공통 스탠자를 지원하므로 빌드 정보 필드 중복 제거 : https://cabal.readthedocs.io/en/latest/developing-packages.html#common-stanzas

cabal-version:       2.2
name:                myprogram
version:             0.1
-- blah blah blah

common deps
  build-depends: base ^>= 4.11,
                 -- long long list of packages
  ghc-options: -Wall

library
  import: deps
  exposed-modules: Foo

test-suite tests
  import: deps
  type: exitcode-stdio-1.0
  main-is: Tests.hs
  build-depends: foo

테스트 스위트에 대한 빌드 종속 패키지의 긴 목록을 "실행 파일과 동일하고 QuickCheck 추가"로 대체 할 수있는 방법이 있습니까?

내가 알기로는 아니야. 그러나 build-depends프로젝트를 세 가지 대상으로 구성하여 패키지 목록을 한 번만 언급하는 방법이 있습니다.

  1. 모든 코드를 포함하고 긴 빌드 종속 목록이 필요한 라이브러리.
  2. 하나의 파일로만 구성되고 위의 기본 및 라이브러리에 의존하는 실행 파일.
  3. 위의 라이브러리와 사용중인 테스트 패키지에 의존하는 테스트 스위트.

이 접근 방식은 인디 젬마의 답변이 제안하는 것일 수 있지만 Norman Ramsey가 의견에서 지적했듯이 거기에 제안 된 Cabal 파일은 그것을 달성하지 못할 것입니다. Cabal 파일에 필요한 항목의 요점은 다음과 같습니다. 저에게 적합한 전체 예제를 보려면 이 Cabal 파일을 참조하십시오 .

name: my-program
version: ...

library
  hs-source-dirs: src-lib
  build-depends: base, containers, ...
  exposed-modules: My.Program.Main, ...

executable my-program
  hs-source-dirs: src-exec
  main-is: my-program.hs
  Build-depends: base, my-program

test-suite tests
  type: exitcode-stdio-1.0
  hs-source-dirs: src-test
  main-is: tests.hs
  other-modules: ...
  build-depends: base, my-program, test-framework, ...

중요 사항 :

  • 세 개의 대상에 대해 세 개의 개별 소스 디렉토리가 있습니다. 이는 다른 타겟을 빌드 할 때 GHC가 라이브러리 파일을 재 컴파일하는 것을 중지하는 데 필요합니다.

  • 모든 애플리케이션 코드는 라이브러리에 있습니다. 실행 파일은 다음과 같이 래퍼 일뿐입니다.

    import My.Program.Main (realMain)
    main = realMain
    
  • 라이브러리는 테스트에 필요한 모든 모듈을 노출합니다.

The last point highlights the drawback of this approach: You end up having to expose internal modules. The main benefit of this approach is that you have less duplication in the Cabal file, and maybe more importantly, less duplication in the build process: The library code will be built only once, and then linked into both the executable and the test-suite.


You could also consider using hpack instead of writing the .cabal file by hand:

In hpack's package.yaml format, you can specify a common dependencies field whose entries are added to every components' build-depends field when generating the .cabal file.

For example, see hpack's own package.yaml and the generated hpack.cabal.

To start using hpack with an existing package, you can use hpack-convert which will generate the package.yaml from an existing .cabal file.

To create a new package that uses hpack, you can use stack's simple-hpack template like so: stack new mypkg simple-hpack.

If you use stack for development, you don't have to call hpack manually to regenerate the .cabal file from an updated package.yaml – stack will do that automatically.


No easy way:

  • you can use m4 and specify your dependencies once, but then you will need to reprocess your Cabal file through m4 whenever you change it.

  • you can move the code you are testing out to a library, and then specify the library in your Build-depends for the test. That requires you to install a library even just to run the test.

  • You can just not put the test in the cabal file at all. Build it with ghc --make, which will pull in dependencies. But then you lose cabal integration.


There is an optional library section for .cabal files, which solves your problem.

name:              myprogram
version:           0.1
-- blah blah blah
cabal-version:     >=1.9.2

library
    build-depends: attoparsec == 0.10.*
                 , base == 4.3.*
                 -- long long list of packages

executable myprogram
    hs-source-dirs: src
    main-is:        Main.hs

test-suite test
    hs-source-dirs: test, src
    type:           exitcode-stdio-1.0
    main-is:        Main.hs
    build-depends:  QuickCheck == 2.4.*

참고URL : https://stackoverflow.com/questions/10163604/how-to-reduce-duplication-in-the-build-depends-fields-of-a-cabal-file

반응형