Генерация правил встряхивания из действий

Я хотел бы найти все "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 в вашем исходном примере, который предоставит вам обработку командной строки.

Другие вопросы по тегам