为何仅在Cabal文件library段添加gloss依赖无法正常工作?
为什么只在library段添加gloss依赖无法正常工作?
这个问题的核心原因是你在executable ray-tracer段中声明了other-modules: MyLib,这会让Cabal把MyLib当作executable的一部分重新编译,而不是复用library中已经编译好的版本。
具体原因拆解:
- 当你在library段声明
exposed-modules: MyLib并添加gloss依赖时,library本身可以正常编译,因为它的依赖是完整的。 - 但一旦你在executable段加上
other-modules: MyLib,就相当于告诉Cabal:“这个executable需要单独编译MyLib模块,作为自身的一部分”。此时,编译executable中的MyLib时,需要找到Graphics.Gloss的定义,但executable的build-depends里没有声明gloss依赖,自然会编译失败。 - 当你同时在executable段也添加gloss依赖时,executable编译自己的MyLib副本时就能找到所需依赖,所以可以正常运行。
解决方案:
去掉executable段中的other-modules: MyLib,因为MyLib已经是library暴露的模块,executable只需要通过import语句引用它即可复用library的编译结果。修改后的executable段应该是这样:
executable ray-tracer main-is: Main.hs build-depends: base ^>=4.13.0.0, ray-tracer, haskell-say ^>=1.0.0.0 default-language: Haskell2010
这样调整后,executable通过ray-tracer依赖你的library,而library已经包含了gloss的依赖,Cabal会自动处理间接依赖的传递,你不需要在executable段重复声明gloss。
补充:Cabal的Target隔离逻辑
Cabal中的每个构建目标(library、executable、test-suite等)都是独立的单元,它们的依赖不会自动共享。只有当一个target显式依赖另一个target时,才会继承对方的依赖。如果错误地把library的模块放到executable的other-modules中,就等于把该模块从library“复制”到executable中,此时模块的依赖必须在executable的build-depends中单独声明。
内容的提问来源于stack exchange,提问作者Sevan Golnazarian
相关产品推荐
相关产品推荐

