2014-01-05 2 views
2

У меня есть проект Haskell, в котором несколько исполняемых файлов создаются в основном из тех же модулей. Я использую Makefile, чтобы включить параллельные сборки, и он почти работает так, как я хочу. Вот усеченная версия моей текущей Makefile, идеи взяты из http://www.haskell.org/ghc/docs/latest/html/users_guide/separate-compilation.html#using-make:Создание правильных зависимостей ссылок для построений стиля GHC и Makefile

HFLAGS=-O3 -Wall -v0 -fno-ignore-asserts 
HASKELLS=bin1 bin2 bin3 bin4 bin5 bin6 bin7 bin8 bin9 

all: $(HASKELLS) 

%.hi: %.o 
    @: 

%.hi %.o: %.hs 
    ghc -c $(HFLAGS) $< 

$(HASKELLS): %: %.o 
    ghc --make $(HFLAGS) [email protected] 

.hsdepend: *.hs 
    ghc -M -dep-makefile .hsdepend *.hs 
    rm -f .hsdepend.bak 

include .hsdepend 

Как вы можете видеть, я до сих пор использую ghc --make для соединения (только); таким образом отдельные модули могут быть скомпилированы параллельно, а ghc --make вызывает только компоновщик.

К сожалению, это не является надежным: а RELINK срабатывает только, скажем, BIN1 только если bin1.o новее, чем исполняемый файл, но если только один из других объектных файлов был обновлен. Это может произойти, когда в модуле происходит изменение, так что он приводит к обновлению файла .o, но интерфейс модуля не изменяется, то есть файл .hi не затрагивается.

Одним из альтернативных решений является запуск нулевого ghc --make для каждый двоичный каждый раз, когда вызывается make; к сожалению, это медленно и загромождает выход (я хотел бы видеть, когда что-то было связано, а когда нет).

ghc -M только создает линию зависимостей для каждого .o файл, но для связанных исполняемых файлов нет. Информация о которых .o файлов для ссылки, в которых исполняемый файл (с указанием имени основного модуля binN.hs), очевидно, есть, но мне не совсем понятно, если можно добраться до него с помощью любой магии Makefile ,

Я могу только думать о том, как это сделать, написав постпроцессор для .hsdepend, но это кажется чрезмерным.

Может ли кто-нибудь предложить лучшее решение?

ответ

0

Мой совет был бы, не утруждайте себя попыткой сделать эту работу. Он должен работать, и было бы неплохо, если бы это сработало, но поддержка ghc -M в настоящее время нарушена (как в, она не генерирует правильные правила зависимостей и не указывает правила для некоторых файлов, отличных от Haskell). На самом деле заставить это работать надежно приложить много усилий, и в конце концов вызовет больше перестроек, чем это необходимо.

Кроме того, поддержка параллельных сборок была объединена с GHC, поэтому, когда ghc-7.8 выпущен, вы сможете использовать простой ghc --make для получения параллельных сборок. Или теперь вы можете использовать HEAD HEAD.

+0

Будет ли также возможно создание нескольких исполняемых файлов с использованием одного 'ghc -make'? Поскольку я предполагаю, что небезопасно запускать несколько из них параллельно при создании нескольких двоичных файлов из одних и тех же модулей. –

+0

Один вызов 'ghc --make' не будет создавать несколько двоичных файлов, но есть несколько способов обойти это без особых проблем. Вероятно, наиболее полезным является создание конфигурации cabal, которая определяет весь ваш общий код как библиотеку. Или последовательно создавайте свои исполняемые файлы, но поскольку большинство объектных файлов будет построено с помощью первой исполняемой сборки, остаток будет в основном связан. –

Смежные вопросы