Stack中导入sub-packages的操作疑问及cabal配置报错求助
解决Stack中导入子包/子模块的配置问题
先跟你澄清下术语:你说的“sub-packages”其实分两种常见场景——一种是同一个项目下的独立本地包(每个包都有自己的.cabal文件,比如项目根目录下的packageA、packageB),另一种是同一个包内的层级子模块(比如MyProject.Utils这种属于主包的子模块)。我分别给你讲这两种场景的正确配置方式,以及executable部分的写法:
场景1:项目包含多个独立本地子包
假设你的项目结构是这样的:
my-project/ ├── stack.yaml ├── core/ │ └── core.cabal # 子包1,name字段是core └── app/ └── app.cabal # 子包2,里面有我们要编译的可执行文件
关键配置步骤:
- 在stack.yaml中声明所有子包:
打开根目录的stack.yaml,确保packages字段包含所有子包的路径:packages: - core/ - app/ - 在executable所在的cabal文件中添加依赖:
如果app里的可执行文件需要依赖core包,打开app.cabal,在executable块的build-depends里加上子包的名字(要和core.cabal里的name字段完全一致):executable my-app main-is: Main.hs build-depends: base >=4.14 && <5, core # 这里填子包的包名 hs-source-dirs: src default-language: Haskell2010
场景2:同一个包内的子模块
如果是主包内有层级模块(比如MyProject.Utils),项目结构类似:
my-project/ ├── myproject.cabal # 主包,name字段是myproject ├── stack.yaml └── src/ ├── Main.hs └── MyProject/ └── Utils.hs # 子模块,模块名是MyProject.Utils
两种配置方式:
方式1:通过library模块共享子模块
推荐这种方式,方便后续复用:
- 在
myproject.cabal中添加library块,声明要暴露的子模块:library exposed-modules: MyProject.Utils build-depends: base >=4.14 && <5 hs-source-dirs: src default-language: Haskell2010 - 在
executable块的build-depends里加上主包自己的名字,这样就能导入子模块了:executable myproject-exe main-is: Main.hs build-depends: base >=4.14 && <5, myproject # 主包的名字,对应cabal里的name字段 hs-source-dirs: src default-language: Haskell2010
方式2:直接在executable中声明子模块
如果不需要library,也可以直接在executable块里列出用到的子模块:
executable myproject-exe main-is: Main.hs other-modules: MyProject.Utils # 明确列出用到的子模块 build-depends: base >=4.14 && <5 hs-source-dirs: src default-language: Haskell2010
常见错误排查点
- 确认
stack.yaml的packages路径正确,子包路径写错会导致Stack找不到依赖 - 检查
build-depends里的包名和对应cabal文件的name字段完全一致(大小写、拼写都不能错) - 模块路径要和
hs-source-dirs对应:比如hs-source-dirs: src,那MyProject.Utils必须对应src/MyProject/Utils.hs - 遇到奇怪的错误可以先执行
stack clean清除缓存,再重新stack build -v
内容的提问来源于stack exchange,提问作者Mark Karavan
相关产品推荐
相关产品推荐

