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

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打包进发布的代码包,服务器上的编译器根本找不到这个文件,自然报错。

解决建议

  1. 如果qhull_ra.h是项目自己的文件:
    • 把它放到项目的固定子目录(比如cbits/),然后在cabal文件的library或executable段里加:
      include-dirs: cbits
      install-includes: qhull_ra.h
      
    这样不管是本地stack还是Hackage编译,编译器都会去指定目录找,而且发布时会自动把这个头文件包含进去。
  2. 如果qhull_ra.h是系统安装的第三方库头文件:
    • 改成#include <qhull_ra.h>,同时在cabal文件里加系统库依赖:
      extra-libraries: qhull
      
    • 还要在项目README里说明,用户需要先安装qhull系统库才能编译。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 01:06:27