Как я могу определить, установлен ли GHC для генерации 32-битного или 64-битного кода по умолчанию? - PullRequest
7 голосов
/ 02 июня 2011

В моем 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 вызывает этот make-файл во время сборки, чтобы обойти ограничения в cabal. Хотел бы я просто перечислить их в качестве c-источников в моем файле клики.

Ответы [ 3 ]

6 голосов
/ 03 июня 2011

Обычный трюк, который я вижу, это запрашивать размер в байтах или битах Int или Word, поскольку в 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 голосов
/ 03 июня 2011

Спасибо Эдьке, теперь я знаю правильный ответ.

У Makefile теперь есть такое правило:

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

Это немного долго, но все, что он делает - это извлечение"Gcc Linker flags" из вывода ghc. Примечание: Это вывод ghc --info, а не ghc +RTS --info.

Это лучше, чем другие предложенные способы, поскольку дает мне все флаги, которые необходимо указать, а не только флаг -m.Это также пусто, когда никакие флаги не нужны.

Спасибо всем!

1 голос
/ 02 июня 2011

Согласно моему комментарию, должна быть возможность скомпилировать тестовую программу и прочитать полученный бинарный файл.

$ 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
...