Как вы объявляете цели PHONY действиями по умолчанию с помощью Shake?

Я нахожусь в процессе преобразования Makefile в Shakefile, и я не уверен, как обращаться с целевыми объектами PHONY (clean, install, так далее.). Я попробовал что-то вроде:

main = shake shakeOptions $ do
  want ["install"]
  "install" *> \_ -> do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

Он успешно создает символические ссылки, но сообщает об ошибке "Ошибка, правило" установить "не удалось создать файл: установить".

Итак, если не с действием "хочу", как я могу объявить, что цель по умолчанию, которую я хочу запустить, является фиктивной?

2 ответа

Решение

В Shake-0.10.1 и выше вы можете использовать phony функция для записи:

main = shake shakeOptions $ do
  want ["install"]
  phony "install" $ do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

Это должно делать именно то, что вы хотите, и не требует создания поддельного файла. Кроме того, вы можете использовать shakeArgs скорее, чем shake так что пользователь может выбрать install из командной строки, или выбрал другую цель, такую ​​как очистить.

В Shake-0,9 и ниже фальшивые цели - слабое место в Shake - вы можете сделать это, но они более многословны и ручны, чем должны быть. Вот несколько вариантов:

Пусть правило установки создаст файл

Как очень простое решение, просто добавьте writeFile' "install" "" в нижней части install править. Это создает фиктивный файл, но он будет запускаться каждый раз mytarget изменения. Если вы хотите, чтобы он запускался каждый раз install запрашивается (как фальшивка в make), просто добавьте alwaysRerun, Если вы можете игнорировать избыточный файл, это самое простое решение, пока не будет обеспечена первоклассная ложная поддержка.

использованиеaction

Ты можешь написать:

main = shake shakeOptions $ do
  action $ do
    need ["mytarget"]
    system' "ln" ["-s", "mytarget", "linkname"]

Это объявляет действие, которое выполняется на каждой сборке. В действительности вы, вероятно, хотите, чтобы это запускалось, только если install находится в командной строке, так что вы можете сделать:

main = do
  args <- getArgs
  shake shakeOptions $ do
    when ("install" `elem` args) $ action $ do
      ... install code ...

использованиеshakeArguments

В более поздних версиях Shake вы можете использовать shakeArgsWith функция для записи:

main = shakeArgsWith shakeOptions [] $ \_ targets ->
  if "clean" `elem` targets then do
    removeFiles "_make" "//*"
    return Nothing
  else return $ Just $ do
    when ("install" `elem` targets) $ do
       ... install code ...
    ... other rules ...
    want $ delete "install" targets

Это дает вам полный контроль над тем, как обрабатываются цели, так что вы можете делать что-то гораздо более мощное, чем фальшивые цели, но это больше работает.

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