请记住,几乎任何类型的原生二进制文件的编译都至少包含两个步骤:实际对象编译(.hs
-> .o
)和链接(.o
、、.a
- .lib
> 可执行文件.exe
///等.so
).dll
当你用这个编译时:
ghc -rtsopts -with-rtsopts=-K32M --make algo.hs -fforce-recomp
...幕后实际发生的事情基本上是:
# object compilation - creates algo.o
ghc -c algo.hs -fforce-recomp
# linking - links together algo.o and libHSsomepackage.a into the "algo" binary
# (we assume that `algo.hs` included some module from the package `somepackage`
# e.g. `Data.Package.Some`)
ghc -rtsopts -with-rtsopts=-K32M -o algo -package somepackage algo.o
即该--make
选项告诉 GHC 在链接结果之前自动编译目标文件,它会为您填补大量空白。请注意各个命令行标志的最终位置。
当您在文件顶部指定该编译指示时,会发生这种情况(使用ghc --make algo.hs
):
ghc -c algo.hs -rtsopts -with-rtsopts=-K32M
ghc -o algo -package somepackage algo.o
OPTIONS_GHC
pragma 告诉编译器在将该特定模块编译为目标文件时要添加的选项。因为-rtsopts
是一个链接器选项(它告诉 GHC 链接到一组不同的命令行处理内容),所以在编译目标文件时不能指定它。您必须在链接时指定它,并且不能在模块头中指定此类选项。
有两种解决方案:
- 使用Cabal为您构建东西并在您的
.cabal
文件中指定您想要的 GHC 选项
- 修复您的算法,以便您不需要太多的堆栈空间,例如通过使用尾递归和更严格的折叠。有关更多信息,请参阅wiki。