3

我希望 GHCI 为一个模块加载已编译的目标代码,该模块在编译时比未编译版本快得多。当所有文件都在同一个目录中(没有模块层次结构)时,这工作得很好。但是,当文件位于模块层次结构中时,它们不起作用。

工作版本 MyFile.hs:

import Basic
import Histogram

其中 Basic.o 和 Histogram.o 与 MyFile.hs 位于同一目录中

不工作版本 MyFile.hs:

import Util.Basic
import Util.Histogram

其中 Basic.o 和 Histogram.o 位于子目录 Util 中。使用这个版本,我在加载 MyFile.hs 时得到以下信息:

[1 of 2] Compiling Util.Basic ( Util/Basic.hs, interpreted )
[2 of 2] Compiling Util.Histogram ( Util/Histogram.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram.

我希望能够在模块中组织我的代码,但仍然可以从使用编译的 o 文件中获得好处。

另外,应该注意的是,自从 o 文件被编译后,源文件并没有改变。

编辑:以下是每个文件的内容:

我的文件.hs

import Util.Basic
import Util.Histogram

实用程序/基本.hs

module Util.Basic () where

实用程序/直方图.hs

module Util.Histogram () where

文件/编译:

$:~/programming/haskell/example-error$ ls
MyFile.hs  MyFile.hs~  Util
$:~/programming/haskell/example-error$ cd Util
$:~/programming/haskell/example-error/Util$ ls
Basic.hs  Basic.hs~  Histogram.hs  Histogram.hs~
$:~/programming/haskell/example-error/Util$ ghc *.hs
[1 of 2] Compiling Util.Histogram   ( Histogram.hs, Histogram.o )
[2 of 2] Compiling Util.Basic       ( Basic.hs, Basic.o )
$:~/programming/haskell/example-error/Util$ ls
Basic.hi  Basic.hs~  Histogram.hi  Histogram.hs~
Basic.hs  Basic.o    Histogram.hs  Histogram.o
$:~/programming/haskell/example-error/Util$  cd ../
$:~/programming/haskell/example-error$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 3] Compiling Util.Histogram   ( Util/Histogram.hs, interpreted )
[2 of 3] Compiling Util.Basic       ( Util/Basic.hs, interpreted )
[3 of 3] Compiling Main             ( MyFile.hs, interpreted )
Ok, modules loaded: Util.Basic, Util.Histogram, Main.
*Main> 

丹尼尔建议的解决方案:

The fix is to compile the importing file, and the files in the 
subdirectory only as a consequence of that, not directly. 
4

1 回答 1

5

问题与下面讨论的相同,标志发生了变化:

~/.../Util> ghc Other.hs
[1 of 1] Compiling Util.Other       ( Other.hs, Other.o )
~/.../Util> cd ..
~/.../src> ghc MyFile.hs
[1 of 2] Compiling Util.Other       ( Util/Other.hs, Util/Other.o ) [flags changed]
[2 of 2] Compiling MyFile           ( MyFile.hs, MyFile.o )

我还没有发现特别是哪些标志,或者为什么在单独编译期间传递的标志与编译为从导入模块追逐的模块时传递的标志不同,但它们确实发生了变化,因此重新编译是必要的(具体来说,文件中的标志哈希值会.hi发生变化)。

因此,解决方法是不单独编译模块,而是将它们编译为顶级导入器的依赖项。


原始几乎正确的猜测:

我只能部分重现。编译后touching MyFile.hs

$ ghci-7.4.2 MyFile.hs
-- snip
[1 of 2] Compiling Util.Other       ( Util/Other.hs, interpreted )
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

它看起来和你一样,但是在 7.6.1 中,我们得到了一个提示(编译和touching):

$ ghci MyFile.hs
-- snip
[1 of 2] Compiling Util.Other       ( Util/Other.hs, interpreted ) [flags changed]
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

旗帜变了。我:set -XNoMonomorphismRestriction.ghci文件中有,标志的更改会导致重新编译。

$ ghci -ignore-dot-ghci MyFile.hs
GHCi, version 7.6.1: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[2 of 2] Compiling MyFile           ( MyFile.hs, interpreted )
Ok, modules loaded: MyFile, Util.Other.

.ghci忽略没有为编译提供的标志的违规行为,Util.Other不解释未更改的,使用编译后的代码。.ghci(使用 GHC < 7.4,甚至不需要忽略该文件。)

如果您有一个.ghci文件在其中设置了语言选项 ( NoMonomorphismRestriction, , ...) 并且 ghc >= 7.4,则在加载模块时TypeFamilies需要忽略该文件。.ghci

如果不是这种情况,则重新编译不是预期的行为。然后需要更多信息来诊断问题并找到解决方法。

然后,半解决方法将成为-fobject-codeghci 的标志。

于 2012-11-28T03:54:04.963 回答