Как я могу определить, установлен ли GHC для генерации 32-битного или 64-битного кода по умолчанию?
у меня есть следующие биты в моем make-файл:
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 иногда 64bit. Я хотел бы обобщить это так, чтобы он автоматически определял, создает ли GHC 32-битный или 64-битный код, а затем передает правильный флаг GCC.
вопрос: как я могу спросить GHC, какой тип кода (32bit против 64bit) он будет строить?
PS: мой файл cabal вызывает этот файл makefile во время сборки для обхода ограничений в cabal. Я хотел бы просто перечислить их как c-источники в моем файле cabal.
3 ответов
обычный трюк, который я вижу, - это спросить размер в байтах или битах 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
благодаря Эдьке я теперь знаю правильный ответ.
в файле Makefile теперь есть такое правило:
GCCFLAGS := $(shell ghc --info | ghc -e "fmap read getContents >>= putStrLn . unwords . read . Data.Maybe.fromJust . lookup \"Gcc Linker flags\"")
это немного долго, но все, что он делает, это извлечь "флаги компоновщика Gcc" из вывода ghc. Примечание: это выход ghc --info
, а не ghc +RTS --info
.
Это лучше, чем другие предлагаемые способы, поскольку это дает мне все флаги, которые должны быть указаны, а не только флаг-m. Он также пуст, когда флаги не нужны.
спасибо всем!
согласно моему комментарию, должна быть возможность скомпилировать тестовую программу и прочитать полученный двоичный файл.
$ 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