Haskell FFI中#include <xx.h>与"xx.h"的区别及Hackage编译问题
C头文件两种引入方式的区别与编译问题解析
一、两种#include引入方式的核心区别
- 用
<>包裹的头文件(比如<stdio.h>、<HsFFI.h>):编译器会直接去系统标准头文件目录查找,这些目录是编译器默认配置好的(比如系统的/usr/include、GHC自带的FFI头文件目录),不需要额外指定路径就能找到。这类头文件通常是系统标准库、编译器提供的工具类头文件。 - 用
""包裹的头文件(比如你的qhull_ra.h):编译器优先在当前编译的C源文件所在目录找,找不到才会去系统标准目录碰运气。这种写法本来就是给项目自己的本地头文件用的。
二、编译问题的具体原因
本地stack编译不稳定的问题
- 能找到的时候:要么是C源文件和
qhull_ra.h刚好在同一个目录,要么是stack的构建缓存里保留了之前配置的头文件搜索路径(比如cabal文件里的include-dirs配置生效了)。 - 找不到的时候:大概率是构建环境变化导致的——比如切换了stack resolver版本、清理了构建缓存,或者cabal/stack配置里的
include-dirs没写对,编译器搜索路径里没包含qhull_ra.h所在的目录。
Hackage编译失败的原因
Hackage的构建环境是完全干净的,不会有你本地的缓存或隐含路径。如果你的代码里用#include "qhull_ra.h",但没在cabal文件里明确指定头文件所在目录(include-dirs),也没把qhull_ra.h打包进发布的代码包,服务器上的编译器根本找不到这个文件,自然报错。
解决建议
- 如果
qhull_ra.h是项目自己的文件:- 把它放到项目的固定子目录(比如
cbits/),然后在cabal文件的library或executable段里加:include-dirs: cbits install-includes: qhull_ra.h
- 把它放到项目的固定子目录(比如
- 如果
qhull_ra.h是系统安装的第三方库头文件:- 改成
#include <qhull_ra.h>,同时在cabal文件里加系统库依赖:extra-libraries: qhull - 还要在项目README里说明,用户需要先安装qhull系统库才能编译。
- 改成
内容的提问来源于stack exchange,提问作者user855443
相关产品推荐
相关产品推荐

