从单个项目生成多个可执行文件

Nik*_*kov 21 haskell cabal

具有以下项目结构:

src/FirstExecutable.hs
src/SecondExecutable.hs
my-amazing-project.cabal
Run Code Online (Sandbox Code Playgroud)

和以下cabal设置:

name:               my-amazing-project
version:            0.1.0.0
build-type:         Simple
cabal-version:      >=1.8

executable first-executable
  hs-source-dirs:   src
  main-is:          FirstExecutable.hs
  ghc-options:      -O2 -threaded -with-rtsopts=-N
  build-depends:    base == 4.5.*

executable second-executable
  hs-source-dirs:   src
  main-is:          SecondExecutable.hs
  ghc-options:      -O2 -threaded -with-rtsopts=-N
  build-depends:    base == 4.5.*
Run Code Online (Sandbox Code Playgroud)

cabal install使用以下输出运行失败:

Installing executable(s) in
/Users/mojojojo/Library/Haskell/ghc-7.4.2/lib/my-amazing-project-0.1.0.0/bin
cabal: dist/build/second-executable/second-executable: does not exist
Failed to install my-amazing-project-0.1.0.0
cabal: Error: some packages failed to install:
my-amazing-project-0.1.0.0 failed during the final install step. The exception
was:
ExitFailure 1
Run Code Online (Sandbox Code Playgroud)

我做错了什么或者这是一个Cabal bug?


可执行模块的内容如下:

module FirstExecutable where

main = putStrLn "Running FirstExecutable"
Run Code Online (Sandbox Code Playgroud)

module SecondExecutable where

main = putStrLn "Running SecondExecutable"
Run Code Online (Sandbox Code Playgroud)

Sat*_*vik 25

cabal期望可执行文件的模块Main.您应该跳过模块行或使用module Main where.

好的,这是可能的原因.当模块不是Main您实际编译程序时,不会生成haskell程序的可执行文件.运行可执行文件时使用模块的main功能Main.ghc的可能解决方法是-main-isflag.所以你可以有类似的东西

name:               my-amazing-project
version:            0.1.0.0
build-type:         Simple
cabal-version:      >=1.8

executable first-executable
  hs-source-dirs:   src
  main-is:          FirstExecutable.hs
  ghc-options:      -O2 -threaded -with-rtsopts=-N -main-is FirstExecutable
  build-depends:    base == 4.5.*

executable second-executable
  hs-source-dirs:   src
  main-is:          SecondExecutable.hs
  ghc-options:      -O2 -threaded -with-rtsopts=-N -main-is SecondExecutable
  build-depends:    base == 4.5.*
Run Code Online (Sandbox Code Playgroud)

  • @NikitaVolkov这种行为是由[语言标准](http://www.haskell.org/onlinereport/modules.html)强制执行的 - "Haskell程序是模块的集合,按照惯例,其中一个必须被调用主要并且必须输出值main." (4认同)
  • @MikhailGlushenkov谢谢.因此,Cabal家伙违反了标准,允许用户声明不同命名的"Main"模块.类似的事情应该在文档中大胆地注明,但[没有关于这个问题,也没有关于它的实际问题](http://www.haskell.org/cabal/users-guide/developing-packages.html#executables ).*(如果有权访问它的人正在阅读此评论,请注意).* (3认同)
  • Cabal的'main-is`和GHC的`-main-is`做了不同的事情.Cabal的`main-is`只是让你定义主模块所在的*filename*,但*模块名*仍然必须是'Main`(即文件中的模块声明).GHC的`-main-is`允许模块名称或`main`函数名称为其他名称. (3认同)