包拆分后Cabal依赖配置咨询:支持旧单包或双新包并规避无效组合
包拆分后的Cabal依赖约束方案
当一个软件包拆分为两个新包后,要让Cabal只允许依赖旧单包或同时依赖两个新包这两种有效组合,排除无效的依赖情况(比如仅依赖新核心包、旧包+新base包),可以通过以下几种方式实现:
1. 用Cabal 3.4+的any条件(推荐,最接近base的自动选择逻辑)
Cabal 3.4及以上版本支持any条件语法,可以直接声明允许的依赖组合,让 resolver 自动选择最优的有效选项:
cabal-version: >=3.4 name: your-package version: 0.1.0.0 library build-depends: base >=4.14 && <5, any ( -- 有效组合1:依赖旧版单包 (singletons >=2.7 && <3), -- 有效组合2:同时依赖两个新版包 (singletons >=3 && <4, singletons-base >=3 && <4) ) -- 其他配置(exposed-modules等)...
这种方式直接告诉Cabal只能从这两组依赖中选一种,自动排除所有无效组合,完全交由Cabal resolver处理,和base的版本限制逻辑一致。
2. 结合dependency-version条件(Cabal 3.0+)
如果需要兼容Cabal 3.0到3.3的版本,可以用dependency-version条件来添加约束:
cabal-version: >=3.0 name: your-package version: 0.1.0.0 library build-depends: base >=4.14 && <5, -- 先声明宽泛的版本范围,再通过条件约束 singletons >=2.7 && <4, singletons-base >=3 && <4 || singletons-base <3 -- 约束:如果用singletons 3.x,必须搭配singletons-base 3.x if dependency-version(singletons >=3) build-depends: singletons-base >=3 constraints: singletons-base >=3 -- 约束:如果用singletons 2.x,禁止依赖singletons-base if dependency-version(singletons <3) constraints: singletons-base <0 -- 用不可能的版本范围彻底排除该依赖
3. 自定义Flag(兼容旧版Cabal)
如果需要支持Cabal 3.0以下的旧版本,可以通过自定义Flag来切换依赖模式,同时通过constraints排除无效组合:
cabal-version: >=2.0 name: your-package version: 0.1.0.0 flag use-singletons-3 description: 使用新版singletons 3.x + singletons-base组合 default: False manual: False -- 让Cabal自动判断,也可手动指定 library build-depends: base >=4.14 && <5 -- 新版依赖组合 if flag(use-singletons-3) build-depends: singletons >=3 && <4, singletons-base >=3 && <4 -- 旧版依赖组合,同时禁止依赖singletons-base else build-depends: singletons >=2.7 && <3 constraints: singletons-base <0
你还可以在cabal.project中根据编译器版本自动设置flag,实现类似自动选择的效果:
# 针对支持singletons 3.x的GHC版本自动启用flag if impl(ghc >=8.10) flags: use-singletons-3=True
额外提示
- 代码层面需要做好兼容性适配,比如用CPP条件编译:
#if MIN_VERSION_singletons(3,0,0) -- 适配singletons 3.x的代码(导入singletons-base的模块) #else -- 适配singletons 2.x的代码 #endif - 选择方案时,优先用
any条件,它最简洁且符合现代Cabal的设计逻辑;如果需要兼容旧环境,再选择其他方案。
内容的提问来源于stack exchange,提问作者leftaroundabout
相关产品推荐
相关产品推荐

