如何在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
相关产品推荐
相关产品推荐

