Генерация правил встряхивания из действий
Я хотел бы найти все "Makefiles" в моем проекте, а затем сгенерировать правила на их основе. Тем не менее, похоже, что (намеренно) ничто не может избежать действия. Поэтому вместо этого я поднял свой сканер Makefile до операции ввода-вывода перед функцией встряхивания.
main = do
makefiles <- findMakefiles
shake skakeOptions $ generate_rules makefiles
Есть ли способ лучше?
1 ответ
Во-первых, я не думаю, что с текущим подходом что-то не так. Сам пакет Shake использует аналогичный подход для встроенных интерпретаторов Ninja и Makefile, см. Подробности о интерпретаторе Makefile или интерпретаторе Sake. Пока обработка Makefile достаточно быстра, чтобы это не имело значения (как это обычно и бывает), тогда вы в основном пишете интерпретатор для своего пользовательского синтаксиса сборки, используя Shake, который работает хорошо.
Есть несколько причин, чтобы избежать такого подхода, например, если обработка Makefile стоит дорого, или если сам Makefile имеет другие зависимости. В этой ситуации вы можете использовать комбинацию newCache
проанализировать Makefile один раз и addOracle
поэтому правила могут зависеть от подмножества Makefile, которое им требуется. Тем не менее, такой подход обмануть правильно, так как он в основном вызывает слой косвенности, и вы должны сделать некоторые предположения о том, как generate_rules
работает. Пакет ghc-make использует эту технику (см. Правило "makefile" и вызов newCache
) и usingConfigFile
функция из пакета Shake использует тот же newCache
/addOracle
шаблон.
Придерживаясь оригинального подхода, есть где-то немного другое, вы можете поставить свой findMakefiles
шаг. Ты можешь сделать:
main = shakeArgsWith shakeOptions [] $ \_ -> xs -> do
makefiles <- findMakefiles
let rules = generate_rules makefiles
if null xs then rules else withoutActions rules >> want xs
Преимущество этого заключается в том, что вы можете легко добавлять флаги командной строки, чтобы выяснить, где найти Makefile или варианты его обработки. И системы Ninja, и Makefile в Shake поддерживают это, используя --makefile=FILE
переопределить значение по умолчанию. Даже если вы не хотите двигаться generate_rules
вы можете заменить shake
с shakeArgs
в вашем исходном примере, который предоставит вам обработку командной строки.