如何检测 GHC 是否默认生成32位或64位代码?

7

我在我的makefile中有以下的代码:

GLFW_FLAG := -m32 -O2 -Iglfw/include -Iglfw/lib -Iglfw/lib/cocoa $(CFLAGS)
...
$(BUILD_DIR)/%.o : %.c
    $(CC) -c $(GLFW_FLAG) $< -o $@
$(BUILD_DIR)/%.o : %.m
    $(CC) -c $(GLFW_FLAG) $< -o $@
-m32指示GCC生成32位代码。它存在的原因是因为在某些配置中,GHC被设置为构建32位代码,但是GCC的默认设置有时是64位。我希望将其泛化,以便自动检测GHC正在构建32位还是64位代码,然后将正确的标志传递给GCC。
问题:如何询问GHC将构建哪种类型的代码(32位还是64位)?
PS:我的cabal文件在构建过程中调用此makefile以解决cabal中的限制。我希望我可以在我的cabal文件中将这些列为c源。

1
我可以使用这个来从 GHC 获取字长,但我不知道是否使用了正确的值:WORDSIZE := $(shell ghc +RTS --info | ghc -e "do c <- getContents; let { r = read c :: [(String,String)]; wsize = Data.Maybe.fromJust (lookup "Word size" r) }; putStrLn wsize") - Jason Dagit
你可以尝试使用 ghc -e 'print (maxBound :: Int)' 命令的结果,这个结果会根据你使用的是32位还是64位的 GHC 而有所不同... - hvr
你能直接调用ghc而不是gcc吗?这样它就会自动添加正确的标志。 - John L
@Ed'ka,哦,看起来真不错。 - Jason Dagit
@John L,请看“PS”评论。我希望我能做到,但问题的一部分是有些文件是Objective-C的,而唯一可以正确处理它们的GHC尚未发布。 - Jason Dagit
显示剩余2条评论
3个回答

6

我通常看到的技巧是询问 IntWord 的大小(以字节或位为单位),因为这取决于机器的字长,在 GHC 中会有所不同。

Prelude> :m + Foreign
Prelude Foreign> sizeOf (undefined :: Int)
8
Prelude Foreign> bitSize (undefined :: Int)
64

或者使用系统工具:

$ cat A.hs
main = print ()

$ ghc --make A.hs
[1 of 1] Compiling Main             ( A.hs, A.o )
Linking A ...

$ file A
A: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
     dynamically linked (uses shared libs), for GNU/Linux 2.6.27, not stripped

2

感谢Ed'ka,现在我知道正确的答案了。

现在Makefile有一个像这样的规则:

GCCFLAGS  := $(shell ghc --info | ghc -e "fmap read getContents >>= putStrLn . unwords . read . Data.Maybe.fromJust . lookup \"Gcc Linker flags\"")

这段内容有点长,但它只是从ghc的输出中提取“Gcc链接器标志”。注意: 这是ghc --info的输出而不是ghc +RTS --info

与其他建议的方法相比,这种方法更好,因为它给我提供了需要指定的所有标志,而不仅仅是-m标志。当不需要任何标志时,它也是空的。

谢谢大家!


看起来你需要类似于 getContents >>= putStrLn . Data.Maybe.fromJust . lookup "C compiler link flags" . read 这样的东西。 - Steven Shaw

1
根据我的评论,编译一个测试程序并读取生成的二进制文件应该是可行的。
$ cabal install elf

而代码只是这样的

readElf testFile'sPath >>= \e -> if elfClass e == ELFCLASS64 then print 64 else print 32

或者在 GHCi 中我们可以看到:

> e <- readElf "/bin/ls"
> elfClass e
ELFCLASS64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接