You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Haskell项目的文件级递归依赖关系图?

如何用Stack或Cabal提取Haskell文件级递归依赖?

我的Haskell项目包含多个可执行目标,目录结构如下:

...
app/
other_app/
src/
package.yaml
stack.yaml
...

app/、other_app/和src/目录下有不同的.hs文件。用Stack构建时,若src/中的.hs文件变更,相关可执行文件会重新构建,说明Stack能识别类似GNU make的依赖关系图。我希望像C语言的makedepend工具那样,递归提取Haskell文件的文件级依赖(而非Stack dot提供的包级依赖),比如获取app2的Main.hs对应的文件依赖列表:

  • src/Component1/Types.hs
  • src/Component1/Utils.hs
  • src/CoolLibrary/CoolUtility.hs
    ...

项目的package.yaml配置片段如下:

.............
executables:
  app1-exe:
    main:                Main.hs
    source-dirs:         app1
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - app1

  app2-exe:
    main:                Main.hs
    source-dirs:         app2
    ghc-options:
    - -threaded
    - -rtsopts
    - -with-rtsopts=-N
    dependencies:
    - app1
............

请问能否通过Stack或Cabal工具实现该需求?此前尝试Cabal的v2-freeze命令,发现与需求无关。


可以通过Stack或Cabal结合GHC原生功能实现

方法一:通过Stack调用GHC生成依赖信息

Stack本身没有直接输出文件级依赖的命令,但可以借助GHC的-M参数(生成Makefile风格的依赖规则)来实现:

  1. 针对目标可执行文件,执行以下命令生成依赖文件:
    stack ghc -- --make app2/Main.hs -M -dep-makefile app2.deps
    
    执行后会生成app2.deps文件,里面包含app2/Main.hs递归依赖的所有本地.hs文件路径,格式符合Makefile的依赖规则。
  2. 如果只需要保留项目内的文件(过滤系统库/外部包依赖),可通过文本工具提取:
    grep -E 'src/|app2/' app2.deps | cut -d: -f1 | sort | uniq
    

方法二:通过Cabal调用GHC生成依赖

Cabal同样可以借助GHC的-M参数实现,步骤类似:

  1. 执行以下命令生成依赖文件:
    cabal exec -- ghc --make app2/Main.hs -M -dep-makefile app2.deps
    
    同样会生成包含所有递归依赖的app2.deps文件。
  2. 提取项目内依赖文件的命令与Stack方案一致:
    grep -E 'src/|app2/' app2.deps | cut -d: -f1 | sort | uniq
    

补充说明

  • GHC的-M参数会递归解析所有导入模块对应的.hs文件,完全匹配你需要的makedepend类功能。
  • 执行命令前确保Stack/Cabal已正确加载项目依赖环境,这样GHC才能找到所有模块的路径。
  • 如果需要结构化输出(如JSON格式),可以使用第三方工具ghc-deps,但仅需基础文件列表的话,上述方法足够满足需求。

内容的提问来源于stack exchange,提问作者RandomB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:57:30