Существует два подхода к отслеживанию таких вещей, как использование оптимизации или нет.
1) Использование оракулов
оракулы очень близко соответствуют тому, что вы просите.Чтобы отслеживать что-то вроде -O0
против -O2
, вам понадобится оракул, который отслеживает уровень оптимизации:
newtype OptLevel = OptLevel ()
deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
type instance RuleResult OptLevel = String
rules = do
addOracle $ \(OptLevel _) -> return $
if <whatever you use to decide> then "-O0" else "-O2"
"foo.o" %> \_ -> do
level <- askOracle $ OptLevel ()
cmd "gcc" level ...
Теперь уровень оптимизации - это отслеживаемая зависимость, которая будет обновляться, если что-то изменится.Этот пример основан на документации для addOracle
.
2) Использовать разные выходные файлы
Для флагов компилятора другой подход заключается в использовании разных каталогов сборки, т. Е.build/opt
(и build/opt/obj
и т. Д.) Содержит двоичные файлы и .o
файлы, созданные с -O
, build/debug
без, build/profile
с флагами профилирования и build/test
с флагами тестирования.Некоторые другие, такие как build/doc
и build/hsc
, генерируют файлы, которые не зависят от флагов компилятора.
Преимущество этого подхода состоит в том, что вы можете хранить все файлы в кэше одновременно и обновлятьотладка или тестовая сборка не разрушают опцию.Недостатком является то, что это просто набор жестко заданных флагов.Но также нетрудно добавить новый режим, вам просто нужна новая пара (directory, flags) для него.