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

如何在GHC API的runGhc中添加C/C++目标文件参与编译

如何在runGhc中添加外部目标文件(.o)?

问题背景

原始GHC编译命令如下:

ghc -ibuild/foreign/somelib \
  -lstdc++ \
  -outputdir "$buildDir" \
  foreign/somelib/somelib.o \
  src/Main.hs -o "$buildDir/Main"

对应的等价runGhc代码初稿如下,但未包含foreign/somelib/somelib.o目标文件,尝试将其设为target不生效:

runGhc (Just libdir) $ do
  (setOutputFile (Just "build/Main") -> dflags) <- getSessionDynFlags

  setSessionDynFlags $ dflags
    { importPaths      = [".", "build/foreign/somelib"]
    , ldInputs         = [Option "-lstdc++"]
    , libraryPaths     = ["build/foreign/somelib"]
    , objectDir        = Just "build"
    , hiDir            = Just "build"
    }

  target <- guessTarget "src/Main.hs" Nothing Nothing

  setTargets [target]
  load LoadAllTargets
  return ()

解决方案

外部.o文件不能通过guessTarget作为普通Haskell目标添加,正确的做法是将其加入链接器输入列表ldInputs,具体修改如下:

修改dynFlags的ldInputs字段

将somelib.o以FileOption的形式添加到ldInputs中,调整后的代码:

runGhc (Just libdir) $ do
  (setOutputFile (Just "build/Main") -> dflags) <- getSessionDynFlags

  setSessionDynFlags $ dflags
    { importPaths      = [".", "build/foreign/somelib"]
    , ldInputs         = [FileOption "" "foreign/somelib/somelib.o", Option "-lstdc++"]
    , libraryPaths     = ["build/foreign/somelib"]
    , objectDir        = Just "build"
    , hiDir            = Just "build"
    }

  target <- guessTarget "src/Main.hs" Nothing Nothing

  setTargets [target]
  load LoadAllTargets
  return ()

关键说明

  • FileOption的第一个参数为前缀(通常留空,直接指定文件路径即可),第二个参数是目标文件的相对路径,需和原始GHC命令中的路径一致。
  • 链接器会在链接阶段自动将该.o文件纳入输入,和原始GHC命令的行为完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:05:01