cabal install重编译二进制且忽略include-dirs,如何指定输出目录?
Cabal项目二进制文件指定目录及编译问题解决
问题背景
项目基于Cabal构建,相关配置如下:
- cabal文件片段:
... include-dirs: include ...
- 目录结构:
... ├── include/ │ ├── one.h │ ├── two.h │ └── three.h ... myproject.cabal cabal.project
- cabal.project配置片段:
... program-options -- 此配置在cabal build时生效,移除则构建失败 ghc-options: -Lclib/mylib -lmylib
执行cabal build --with-compiler=...可正常构建所有二进制文件,但执行cabal install --with-compiler=...时,出现找不到.h头文件的错误,即使添加--cabal-file=myproject.cabal --project-file=cabal.project参数也无效。需求是实现类似Stack的--copy-bins --local-bin-path ...功能,同时理解为何cabal install会重编译且忽略配置。
解决方案
方法1:使用cabal copy(推荐)
cabal copy专门用于将已构建的产物复制到指定目录,无需重新编译,步骤如下:
- 先完成正常构建:
cabal build --with-compiler=your-compiler - 执行拷贝命令,指定二进制文件目标目录:
若构建时用了特殊编译器,拷贝时也可追加cabal copy --bindir=/path/to/your/target/directory--with-compiler参数,不过通常无需重复指定。
方法2:调整cabal install的执行方式
如果坚持使用cabal install,需修正配置并调整执行参数:
- 修改
cabal.project的配置写法,确保ghc-options作用域正确:# 全局生效(所有包) ghc-options: -Lclib/mylib -lmylib # 或仅针对当前项目包生效 package myproject ghc-options: -Lclib/mylib -lmylib - 执行install时,指定安装方式为
copy并绑定目标目录:cabal install --install-method=copy --bindir=/path/to/target --with-compiler=your-compiler
问题原因解释
- 为何cabal install会重编译:
cabal build是将产物构建在项目本地的dist-newstyle目录,属于项目级临时构建;而cabal install默认行为是将包安装到用户全局的Cabal仓库路径(如~/.cabal),它会重新执行完整构建流程(依赖检查、编译等),即使本地已build过,因为二者的构建上下文、目标路径完全不同。 - 为何忽略配置并找不到头文件:
你在cabal.project中使用的program-options作用域存在问题,该配置是针对Cabal自身的调用选项,而非传递给GHC的编译选项,导致cabal install时没有正确继承-Lclib/mylib -lmylib链接参数;同时,install流程的构建根与build不同,可能未正确读取cabal文件中的include-dirs配置,进而引发头文件找不到的错误。
内容的提问来源于stack exchange,提问作者RandomB
相关产品推荐
相关产品推荐

