这是一个.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.*
有没有什么方法可以替换测试套件的长依赖的build-depends包列表“与可执行文件相同,加上QuickCheck”?
修改版本信息。
答案 0 :(得分:33)
有没有什么方法可以替换测试套件的长依赖的build-depends包列表“与可执行文件相同,加上QuickCheck”?
不是我知道的。但是,通过将项目结构化为三个目标,有一种方法只能提及build-depends
个包列表:
也许这种方法是indygemma的答案所提出的,但正如诺曼拉姆齐在评论中指出的那样,提出的Cabal文件将无法实现。以下是Cabal文件中所需内容的要点。有关适用于我的完整示例,您可以查看this Cabal file。
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
该库公开了测试所需的所有模块。
最后一点强调了这种方法的缺点:您最终不得不公开内部模块。这种方法的主要好处是Cabal文件中的重复较少,更重要的是,构建过程中的重复较少:库代码只构建一次,然后链接到可执行文件和测试套件中
答案 1 :(得分:7)
从2.2版本开始,Cabal支持常见的节,以重复构建 build info 字段: 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
答案 2 :(得分:3)
您还可以考虑使用hpack而不是手动编写.cabal文件:
在hpack的package.yaml格式中,您可以指定一个公共dependencies
字段,在生成.cabal文件时,其条目会添加到每个组件的build-depends
字段中。
例如,请参阅hpack自己的package.yaml和生成的hpack.cabal。
要开始在现有包中使用hpack,可以使用hpack-convert从现有的.cabal文件生成package.yaml。
要创建一个使用hpack的新包,您可以使用堆栈的simple-hpack
模板,如下所示:stack new mypkg simple-hpack
。
如果您使用stack进行开发,则无需手动调用hpack
以从更新的package.yaml重新生成.cabal文件 - 堆栈将自动执行此操作。
答案 3 :(得分:-1)
没有简单的方法:
您可以使用m4并指定一次依赖项,但是每当您更改它时,您都需要通过m4重新处理您的Cabal文件。
您可以将正在测试的代码移动到库中,然后在Build-depends中指定库以进行测试。这要求您安装库甚至只是为了运行测试。
您根本不能将测试放在cabal文件中。使用ghc --make构建它,它将引入依赖关系。但是你失去了集合。
答案 4 :(得分:-5)
.cabal文件有一个可选的库部分,可以解决您的问题。
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.*