diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+Version 0.4
+-----------
+Autobuild 'clean' rule. genFile and genTmpFile functions allowing to embed text
+files into the Makefile.
+
 Version 0.3
 -----------
 API changes, improve documentation, improve UrWeb extension
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -72,8 +72,8 @@
 ----------------
 
 Cake3 allows user to write Cakefile.hs in plain Haskell to define rules, targets
-and other stuff as usual. After that, `cake3` compiles it into ./Cakegen
-application which builds your Makefile (ghc is required for that). GNU Make
+and other things as usual. `cake3` executable compiles it into ./Cakegen
+application which outputs your Makefile (ghc is required for that). GNU Make
 knows how to do the rest.
 
 ### Example
@@ -102,32 +102,34 @@
         shell [cmd| gcc -o @(file "main.elf") $os |]
 
       rule $ do
-        phony "clean"
-        unsafeShell [cmd|rm $elf $os $d|]
-
-      rule $ do
         phony "all"
         depend elf
 
       includeMakefile d
 
-
   * Cakefile\_P is an autogenerated module. It defines `file :: String -> File`
     function plus some others.
   * Main building blocks - `rule` functions - build Makefile rules one-to-one.
     The prerequisites are computed based on it's actions.
   * All actions live in Action monad (`A` Monad). `shell` is the most important
     operation of this monad.
-  * Quasy-quotation is used to simplify the shell code. `[cmd|..|]` takes a string
-    as an argument. It's syntax includes:
-    *  $name untiquotes hasell expressions `name` of type File, Variable plus few
-       others. They define a prerequisites of a rule
-    *  @name untiquotes hasell expressions `name` of type File. They define
-       rule's targets
-    *  complex expressions are also supported with $(foo bar) and @(bar baz).
-    *  $$ and @@ expands to $ and @
+  * Quasy-quotation is used to simplify writing of the shell code. `[cmd|..|]`
+    takes a string as an argument. The following antiquotations are supported:
+    *  $name antiquotes Hasell expressions `name` of type File, Variable, few
+       others. The name will be placed to the set of prerequisites of the rule.
+    *  @name antiquotes Hasell expressions `name` of type File. The name will be
+       placed to the set of rule's targets.
+    *  complex Haskell expressions inside antiquotations are supported with
+       $(foo bar) and @(bar baz) syntax.
+    *  $$ and @@ expands to $ and @.
   * Rules appears in the Makefile in the reversed order. Normally, you want
-    'all' rule to be at the bottom.
+    'all' rule to be defined at the bottom of Cakefile.hs.
+  * Starting from 0.4, cake3 outputs rule named 'clean' automatically. This rule
+    contains recipe which deletes all intermediate files with 'rm' command.
+  * selfUpdate call includes the self-updating dependencies. That means, that
+    Makefile will depend on Cakefile.hs and thus will require ghc to present in
+    the system. Removing selfUpdate call will make the Makefile fully
+    Haskell-independent.
 
 
 Features and limitations
@@ -147,20 +149,23 @@
 
 ### Features
 
-  * *Allows spaces inside the filenames.*
+  * *Cake3 generates the 'clean' rule automatically.*
+    But if you define your own 'clean', cake3 will take it as is.
+
+  * *Cake3 takes care of spaces inside the filenames.*
   
     Everyone knows that Makefiles don't like spaces in filenames. Cake3
     carefully inserts '\ ' to make make happy.
 
-  * *Rebuilds a rule when variable changes.*
+  * *Cake3 rebuilds a rule's target when variable changes.*
   
     Consider following antipattern:
 
         # You often write rules like this, don't you?
-        out : in
-             foo $(FLAGS) -o $@ $^
+        program : program.c
+             gcc $(FLAGS) -o $@ $^
 
-    Unfortunately, changes in FLAGS don't lead to rebuilding of out.
+    Unfortunately, changes in FLAGS don't lead to rebuilding of the program.
     Hardly-trackable bugs may appear if one part of a project was built with one
     set of optimisation flags and another part was build with another set by
     mistake.
@@ -170,20 +175,21 @@
     detect changes in variables and rebuild targets when nessesary.
 
         rule $ do
-          shell [cmd|foo $(extvar "FLAGS") -o @out $in |]
+          shell [cmd|gcc $(extvar "FLAGS") -o @program $program_c |]
 
-    will rebuild `out` on FLAGS change
+    will rebuild `program` every time the FLAGS change
  
-  * *Supports rules with more than one target.*
+  * *Rules may have more than one target.*
     
-    It is not that simple to write a rule which has more than one target. Really,
+    It is not that simple to write a rule which has more than one target in
+    Makefile. Indeed,
         
         out1 out2 : in1 in2
             foo in1 in2 -o out1 -o out2
 
     is not corret. Read this [Automake
     article](http://www.gnu.org/software/automake/manual/html_node/Multiple-Outputs.html#Multiple-Outputs)
-    if you are surprised. Thirdcake implements [.INTERMEDIATE
+    if you are surprised. Cake3 implements [.INTERMEDIATE
     pattern](http://stackoverflow.com/a/10609434/1133157) to deal with this
     problem so `rule` like this
 
@@ -192,13 +198,13 @@
 
     will always notice inputs changes and rebuild both outputs
 
-  * *Supports global prebuild\postbuild actions*
+  * *Cake3 supports global prebuild\postbuild actions*
 
     Common human-made Makefile with prebuild commands would support them for one
     rule, typically, "all". Other targets often stay uncovered. Cake3 makes sure
     that actions are executed for any target you call.
 
-  * *Lets user organize build hierarchy.*
+  * *Cake3 lets user organize build hierarchy.*
   
     Say, we have a project A with subproject L. L has it's own Makefile and we
     want to re-use it from our global A/Makefile. Make provides only two ways of
@@ -234,22 +240,24 @@
 
 #### Make syntax
 
-  * Make is not able to detect directory content chages. For example, user has
-    to rerun the ./Cakegen if they add/remove a source file. I plan to automate
-    this kind of checks. so it is on my TODO list.
-  * ifdef/endif instructions is not supported generally. User has to move this
-    logic in Haskell for now. Also on my TODO list
+As a summary - only a samll subset of Make syntax is supported for generation.
+For complex algorithms Haskell looks more suitable so implement everything you
+need inside the Cakefile.hs. In particular:
+
+  * Cake3 offers no way of detecting directory content chages. For example, user
+    has to rerun the ./Cakegen if they add/remove a source file.
   * Cake3 doesn't check the contents of Makefile variables. It is user's
     responsibility to keep them safe.
   * Variables as targets is not supported. Implement this logic in Haskell for
     now.
 
+
 #### General
 
   * Resulting Makefile is actually a GNUMakefile. GNU extensions (shell function
     and others) are needed to make various tricks to work. Also, posix
     environment with coreututils package is required. So, Linux, Probably Mac,
-    Probably Windows+Cygwin.
+    Probably Windows+Cygwin are the platforms which run cake3.
   * All Cakefiles across the project tree should have unique names in order to
     be copied. Duplicates are found, the first one is used
 
diff --git a/cake3.cabal b/cake3.cabal
--- a/cake3.cabal
+++ b/cake3.cabal
@@ -2,7 +2,7 @@
 -- see http://haskell.org/cabal/users-guide/
 
 name:                cake3
-version:             0.3.0.1
+version:             0.4.0.0
 synopsis:            Third cake the Makefile EDSL
 description:         Cake3 is a Makefile EDSL written in Haskell. Write your build logic in
                      Haskell, obtain clean and safe Makefile, distribute it to the end-users.
@@ -36,9 +36,6 @@
     >       shell [cmd| gcc -c $(extvar "CFLAGS") -o @(c.="o") $c |]
     >   elf <- rule $ do
     >     shell [cmd| gcc -o @(file "main.elf") $os |]
-    >   rule $ do
-    >     phony "clean"
-    >     unsafeShell [cmd|rm $elf $os $d|]
     >   rule $ do
     >     phony "all"
     >     depend elf
diff --git a/src/Development/Cake3.hs b/src/Development/Cake3.hs
--- a/src/Development/Cake3.hs
+++ b/src/Development/Cake3.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -40,6 +41,8 @@
   , (</>)
   , toFilePath
   , readFileForMake
+  , genFile
+  , genTmpFile
 
   -- Make parts
   , prerequisites
@@ -138,23 +141,10 @@
     addPlacement 0 (S.findMin (rtgt r))
     return (r,a)
 
--- | Adds the phony target for a rule. Typical usage:
--- 
--- > rule $ do
--- >  phony "clean"
--- >  unsafeShell [cmd|rm $elf $os $d|]
--- >
-phony ::
-  String -- ^ A name of phony target
-  -> A ()
-phony name = do
-  produce (W.fromFilePath name :: File)
-  markPhony
-
--- | Build a Recipe using recipe builder provided, than record the Recipe to the
--- MakeState. Return the copy of Recipe (which should not be changed in future)
--- and the result of recipe builder. The typical recipe builder result is the
--- list of it's targets.
+-- | Build a Recipe using the builder provided and record it to the MakeState.
+-- Return the copy of Recipe (which should not be changed in future) and the
+-- result of recipe builder. The typical recipe builder result is the list of
+-- it's targets.
 --
 -- /Example/
 -- Lets declare a rule which builds "main.o" out of "main.c" and "CFLAGS"
@@ -182,5 +172,20 @@
 -- | A version of rule, without monad set explicitly
 rule' :: (MonadMake m) => A a -> m a
 rule' act = liftMake $ snd <$> withPlacement (rule2 act)
+
+
+genFile :: (MonadMake m) => File -> String -> m File
+genFile tgt cnt = rule' $do
+  shell [cmd|-rm -rf @tgt |]
+  forM_ (lines cnt) $ \l -> do
+    shell [cmd|echo '$(string (quote_dollar l))' >> @tgt |]
+  return tgt
+  where
+    quote_dollar [] = []
+    quote_dollar ('$':cs) = '$':'$':(quote_dollar cs)
+    quote_dollar (c:cs) = c : (quote_dollar cs)
+
+genTmpFile :: (MonadMake m) => String -> m File
+genTmpFile cnt = tmpFile >>= \f -> genFile f cnt
 
 
diff --git a/src/Development/Cake3/Ext/UrWeb.hs b/src/Development/Cake3/Ext/UrWeb.hs
--- a/src/Development/Cake3/Ext/UrWeb.hs
+++ b/src/Development/Cake3/Ext/UrWeb.hs
@@ -39,7 +39,7 @@
 import Development.Cake3.Monad
 import Development.Cake3
 
-data UrpAllow = UrpMime | UrpUrl | UrpResponseHeader
+data UrpAllow = UrpMime | UrpUrl | UrpResponseHeader | UrpEnvVar | UrpHeader
   deriving(Show,Data,Typeable)
 
 data UrpRewrite = UrpStyle | UrpAll
@@ -52,7 +52,7 @@
                  | UrpLibrary File
                  | UrpDebug
                  | UrpInclude File
-                 | UrpLink File String
+                 | UrpLink (Either File String)
                  | UrpSrc File String String
                  | UrpPkgConfig String
                  | UrpFFI File
@@ -101,7 +101,7 @@
 
 urpDeps :: Urp -> [File]
 urpDeps (Urp _ _ hdr mod) = foldl' scan2 (foldl' scan1 mempty hdr) mod where
-  scan1 a (UrpLink f _) = f:a
+  scan1 a (UrpLink (Left f)) = f:a
   scan1 a (UrpSrc f _ _) = (f.="o"):a
   scan1 a (UrpInclude f) = f:a
   scan1 a _ = a
@@ -126,7 +126,7 @@
 
 urpObjs (Urp _ _ hdr _) = foldl' scan [] hdr where
   scan a (UrpSrc f _ lfl) = (f.="o"):a
-  scan a (UrpLink f lfl) = (f):a
+  scan a (UrpLink (Left f)) = (f):a
   scan a _ = a
 
 urpLibs (Urp _ _ hdr _) = foldl' scan [] hdr where
@@ -153,7 +153,9 @@
 
 instance ToUrpWord UrpAllow where
   toUrpWord (UrpMime) = "mime"
+  toUrpWord (UrpHeader) = "requestHeader"
   toUrpWord (UrpUrl) = "url"
+  toUrpWord (UrpEnvVar) = "env"
   toUrpWord (UrpResponseHeader) = "responseHeader"
 
 instance ToUrpWord UrpRewrite where
@@ -175,8 +177,9 @@
     | otherwise = printf "library %s" (up </> toFilePath (dropExtension f))
   toUrpLine up (UrpDebug) = printf "debug"
   toUrpLine up (UrpInclude f) = printf "include %s" (up </> toFilePath f)
-  toUrpLine up (UrpLink f lfl) = printf "link %s %s" lfl (up </> toFilePath f)
-  toUrpLine up (UrpSrc f _ lfl) = printf "link %s %s" lfl (up </> toFilePath (f.="o"))
+  toUrpLine up (UrpLink (Left f)) = printf "link %s" (up </> toFilePath f)
+  toUrpLine up (UrpLink (Right lfl)) = printf "link %s" lfl
+  toUrpLine up (UrpSrc f _ _) = printf "link %s" (up </> toFilePath (f.="o"))
   toUrpLine up (UrpPkgConfig s) = printf "link %s" (maskPkgCfg s)
   toUrpLine up (UrpFFI s) = printf "ffi %s" (up </> toFilePath (dropExtensions s))
   toUrpLine up (UrpSafeGet s) = printf "safeGet %s" (dropExtensions s)
@@ -192,11 +195,10 @@
 newtype UrpGen m a = UrpGen { unUrpGen :: StateT UrpState m a }
   deriving(Functor, Applicative, Monad, MonadState UrpState, MonadMake, MonadIO)
 
--- instance (Monad m) => MonadAction (UrpGen (A' m)) m where
---   liftAction a = UrpGen (lift a)
-
 toFile f wr = liftIO $ writeFile (toFilePath f) $ execWriter $ wr
 
+toTmpFile wr = genTmpFile $ execWriter $ wr
+
 line :: (MonadWriter String m) => String -> m ()
 line s = tell (s++"\n")
 
@@ -206,35 +208,32 @@
   let u@(Urp _ _ hdr mod) = urpst s
   let pkgcfg = (urpPkgCfg u)
 
-  inp <- rule' $ do
-    let inp = urpfile .= "urp.in"
-    toFile inp $ do
+  forM_ (urpSrcs u) $ \(c,fl) -> do
+    let flags = concat $ fl : map (\p -> printf "$(shell pkg-config --cflags %s) " p) (urpPkgCfg u)
+    let i = makevar "URINCL" "-I$(shell urweb -print-cinclude) " 
+    let cc = makevar "URCC" "$(shell $(shell urweb -print-ccompiler) -print-prog-name=gcc)"
+    let cpp = makevar "URCPP" "$(shell $(shell urweb -print-ccompiler) -print-prog-name=g++)"
+    let incfl = extvar "UR_CFLAGS"
+    rule2 $ do
+      case takeExtension c of
+        ".cpp" -> shell [cmd| $cpp -c $incfl $i $(string flags) -o @(c .= "o") $(c) |]
+        ".c" -> shell [cmd| $cc -c $i $incfl $(string flags) -o @(c .= "o") $(c) |]
+        e -> error ("Unknown C-source extension " ++ e)
+
+  inp_in <- toTmpFile $ do
       forM hdr (line . toUrpLine (urpUp urpfile))
       line ""
       forM mod (line . toUrpLine (urpUp urpfile))
 
-    forM_ (urpSrcs u) $ \(c,fl) -> do
-      let flags = concat $ fl : map (\p -> printf "$(shell pkg-config --cflags %s) " p) (urpPkgCfg u)
-      let i = makevar "URINCL" "-I$(shell urweb -print-cinclude) " 
-      let cc = makevar "URCC" "$(shell $(shell urweb -print-ccompiler) -print-prog-name=gcc)"
-      let cpp = makevar "URCPP" "$(shell $(shell urweb -print-ccompiler) -print-prog-name=g++)"
-      rule2 $ do
-        case takeExtension c of
-          ".cpp" -> shell [cmd| $cpp -c $i $(string flags) -o @(c .= "o") $(c) |]
-          ".c" -> shell [cmd| $cc -c $i -o $(string flags) @(c .= "o") $(c) |]
-          e -> error ("Unknown C-source extension " ++ e)
-
-    depend (urpDeps u)
-    depend (urpLibs u)
-    shell [cmd|touch @inp|]
-
   rule' $ do
-    let cpy = [cmd|cat $inp|] :: CommandGen' (Make' IO)
+    let cpy = [cmd|cat $inp_in|] :: CommandGen' (Make' IO)
     let l = foldl' (\a p -> do
                             let l = makevar (map toUpper $ printf "lib%s" p) (printf "$(shell pkg-config --libs %s)" p)
                             [cmd| $a | sed 's@@$(string $ maskPkgCfg p)@@$l@@'  |]
                             ) cpy pkgcfg
     shell [cmd| $l > @urpfile |]
+    depend (urpDeps u)
+    depend (urpLibs u)
 
   return $ UWLib u
 
@@ -269,17 +268,6 @@
 urpUp :: File -> FilePath
 urpUp f = F.joinPath $ map (const "..") $ filter (/= ".") $ F.splitDirectories $ F.takeDirectory $ toFilePath f
 
--- | Dir name , file to embed
--- data UrEmbed = Urembed File File
---   deriving (Show)
-
--- data UrpLibReference
---   = UrpLibStandaloneMake File 
---   | UrpLibStandaloneMake2 File 
---   | UrpLibInternal UWLib
---   | UrpLibEmbed File File
---   deriving(Show)
-
 -- | A general method of including a library into the UrWeb project.
 library' :: (MonadMake m)
   => Make [File] -- ^ A monadic action, returning a list of libraries to include
@@ -332,13 +320,19 @@
 include f = addHdr $ UrpInclude f
 
 link' :: (MonadMake m) => File -> String -> UrpGen m ()
-link' f fl = addHdr $ UrpLink f fl
+link' f fl = do
+  addHdr $ UrpLink (Left f)
+  when (fl /= "") $ do
+    addHdr $ UrpLink (Right fl)
 
 link :: (MonadMake m) => File -> UrpGen m ()
 link f = link' f []
 
 csrc'  :: (MonadMake m) => File -> String -> String -> UrpGen m ()
-csrc' f cfl lfl = addHdr $ UrpSrc f cfl lfl
+csrc' f cfl lfl = do
+  addHdr $ UrpSrc f cfl lfl
+  when (lfl /= "") $ do
+    addHdr $ UrpLink (Right lfl)
 
 csrc  :: (MonadMake m) => File -> UrpGen m ()
 csrc f = csrc' f [] []
@@ -351,7 +345,10 @@
   
 jsFunc m u j = addHdr $ UrpJSFunc m u j
 
-safeGet s = addHdr $ UrpSafeGet s
+safeGet :: (MonadMake m) => File -> String -> UrpGen m ()
+safeGet m fn
+  | (takeExtension m) /= ".ur" = fail (printf "safeGet: not an Ur/Web module name specified (%s)" (toFilePath m))
+  | otherwise = addHdr $ UrpSafeGet (printf "%s/%s" (takeBaseName m) fn)
 
 url = UrpUrl
 
@@ -361,6 +358,10 @@
 
 all = UrpAll
 
+env = UrpEnvVar
+
+hdr = UrpHeader
+
 responseHeader = UrpResponseHeader
 
 script :: (MonadMake m) => String -> UrpGen m ()
@@ -463,6 +464,8 @@
 bin' :: (MonadIO m, MonadMake m) => File -> FilePath -> BS.ByteString -> UrpGen m ()
 bin' dir src_name src_contents = do
 
+  liftIO $ createDirectoryIfMissing True (toFilePath dir)
+
   let mime = guessMime src_name
   let mn = (mkname src_name)
   let wrapmod ext = (dir </> mn) .= ext
@@ -523,7 +526,7 @@
     line $ "val text : unit -> transaction string"
 
   include (binmod ".h")
-  link (binmod ".o")
+  csrc (binmod ".c")
   ffi (binmod ".urs")
 
   -- JavaScript FFI Module
@@ -562,8 +565,8 @@
     addHdr $ UrpJSFunc (modname jsmod) (urname decl) (jsname decl)
   ffi (jsmod ".urs")
 
-  safeGet $ printf "%s/blobpage" (modname wrapmod)
-  safeGet $ printf "%s/blob" (modname wrapmod)
+  safeGet (wrapmod ".ur") "blobpage"
+  safeGet (wrapmod ".ur") "blob"
   module_ (pair $ wrapmod ".ur")
 
   where
diff --git a/src/Development/Cake3/Ext/UrWeb/UrEmbed.hs b/src/Development/Cake3/Ext/UrWeb/UrEmbed.hs
--- a/src/Development/Cake3/Ext/UrWeb/UrEmbed.hs
+++ b/src/Development/Cake3/Ext/UrWeb/UrEmbed.hs
@@ -86,19 +86,16 @@
   when (null ins) $ do
     fail "At least one file should be specified, see --help"
 
-  exists <- doesDirectoryExist tgtdir
-  when (not exists) $ do
-    fail $ "Couldn't create output file, no such directory " ++ show tgtdir
+  -- exists <- doesDirectoryExist tgtdir
+  -- when (not exists) $ do
+  --   fail $ "Couldn't create output file, no such directory " ++ show tgtdir
+  liftIO $ createDirectoryIfMissing True tgtdir
 
   when (null tgtdir) $ do
     fail "An output directory should be specified, use -o"
 
   when (null ins) $ do
     fail "At least one file should be specified, see --help"
-
-  exists <- doesDirectoryExist tgtdir
-  when (not exists) $ do
-    fail "Output is not a directory"
 
   cntnts <- mapM BS.readFile ins
 
diff --git a/src/Development/Cake3/Monad.hs b/src/Development/Cake3/Monad.hs
--- a/src/Development/Cake3/Monad.hs
+++ b/src/Development/Cake3/Monad.hs
@@ -67,10 +67,13 @@
   , warnings :: String
     -- ^ Warnings found so far
   , outputFile :: File
+    -- ^ Name of the Makefile being generated
+  , tmpIndex :: Int
+    -- ^ Index to build temp names
   }
 
 -- Oh, such a boilerplate
-initialMakeState mf = MS defr defr mempty mempty mempty mempty mempty mempty mempty mf where
+initialMakeState mf = MS defr defr mempty mempty mempty mempty mempty mempty mempty mf 0 where
   defr = emptyRecipe "<internal>"
 
 getPlacementPos :: Make Int
@@ -83,6 +86,12 @@
 addMakeDep :: File -> Make ()
 addMakeDep f = modify (\ms -> ms { makeDeps = S.insert f (makeDeps ms) })
 
+tmpFile :: (MonadMake m) => m File
+tmpFile = liftMake $ do
+  s <- get
+  put s{tmpIndex = (tmpIndex s)+1}
+  return (fromFilePath (".cake3" </> ("tmp"++(show (tmpIndex s)))))
+
 -- | Add prebuild command
 prebuild, postbuild :: (MonadMake m) => CommandGen -> m ()
 prebuild cmdg = liftMake $ do
@@ -203,6 +212,19 @@
 -- files. Makefile-specific.
 markPhony :: (Monad m) => A' m ()
 markPhony = modify $ \r -> r { rflags = S.insert Phony (rflags r) }
+
+-- | Adds the phony target for a rule. Typical usage:
+-- 
+-- > rule $ do
+-- >  phony "clean"
+-- >  unsafeShell [cmd|rm $elf $os $d|]
+-- >
+phony :: (Monad m)
+  => String -- ^ A name of phony target
+  -> A' m ()
+phony name = do
+  produce (fromFilePath name :: File)
+  markPhony
 
 -- | Mark the recipe as 'INTERMEDIATE' i.e. claim that all it's targets may be
 -- removed after the build process. Makefile-specific.
diff --git a/src/Development/Cake3/Writer.hs b/src/Development/Cake3/Writer.hs
--- a/src/Development/Cake3/Writer.hs
+++ b/src/Development/Cake3/Writer.hs
@@ -9,13 +9,14 @@
 import Control.Monad.Identity (runIdentity)
 import Control.Monad.State (MonadState, StateT(..), runStateT, State(..), execState, evalState, runState, modify, get, put)
 import Control.Monad.Trans
+import Control.Monad.Writer (MonadWriter, WriterT(..), execWriterT, execWriter, tell)
 import Data.List as L
 import Data.Char
 import Data.Maybe (catMaybes)
 import Data.Monoid
 import Data.String
-import Data.Foldable (Foldable(..), foldl')
-import Data.Foldable (forM_)
+import Data.Foldable (Foldable(..), forM_)
+import qualified Data.Foldable as F
 import Data.Traversable (forM)
 import Data.Set (Set)
 import qualified Data.Set as S
@@ -72,18 +73,18 @@
 runMakeLL templ m = snd $ execState (unMakeLL m) (names, S.empty) where
   names = map fromFilePath $ map (\x -> printf ".%s%d" templ x) $ ([1..] :: [Int])
 
-produceLL :: Recipe -> MakeLL ()
-produceLL r = modify (\(a,b) -> (a,S.insert r b))
+copyRecipeLL :: Recipe -> MakeLL ()
+copyRecipeLL r = modify (\(a,b) -> (a,S.insert r b))
 
 ruleLL :: A' MakeLL a -> MakeLL Recipe
 ruleLL act = do
   (r,_) <- runA "<internal>" act
-  produceLL r
+  copyRecipeLL r
   return r
 
 applySubprojects :: Map File [Command] -> Set Recipe -> Set Recipe
 applySubprojects sp rs = runMakeLL "subproject" (transformRecipesM_ f rs) where
-  f r | L.null scmds = produceLL r
+  f r | L.null scmds = copyRecipeLL r
       | otherwise = do
           n1 <- fresh
           n2 <- fresh
@@ -139,7 +140,7 @@
             markIntermediate
           return ()
       | otherwise = do
-          produceLL r
+          copyRecipeLL r
 
 -- | Operate on a prerequisites which themselfs are targets of a multitarget rule. Make
 -- the conversion from:
@@ -167,6 +168,34 @@
           True -> r { rsrc = (rsrc r) `S.union` mulpack }
           False -> r) r badlist
 
+hasClean :: (Foldable t) => t Recipe -> Bool
+hasClean rs = F.foldl' flt False rs where
+  flt True _ = True
+  flt False r = (Phony `S.member`(rflags r)) && ((fromFilePath "clean")`S.member`(rtgt r))
+
+intermediateFiles :: (Foldable t) => t Recipe -> Set File
+intermediateFiles rs = 
+  execWriter $ do
+    forM_ rs $ \r -> do
+      when (not $ Phony `S.member` (rflags r)) $ do
+        tell (rtgt r)
+
+cleanRuleLL :: Set File -> MakeLL Recipe
+cleanRuleLL fs =
+  ruleLL $ do
+    phony "clean"
+    unsafeShell [cmd|-rm $(fs)|]
+    unsafeShell [cmd|-rm -rf .cake3|]
+
+-- | Define a 'clean' phony target. The rule removes all targets except phony
+-- targets and the Makefile itself
+defineClean :: File -> Set Recipe -> Set Recipe
+defineClean mk rs =
+  runMakeLL "defineClean" $ do
+    let fs = intermediateFiles rs
+    cleanRuleLL (fs `S.difference` (S.singleton mk))
+    return ()
+
 -- | Rule referring to the 
 defaultMakefile :: File
 defaultMakefile = fromFilePath ("." </> "Makefile")
@@ -181,17 +210,14 @@
   godeeper = or $ map (\tgt -> or $ map (\r -> isRequiredFor rs r f) (selectBySrc tgt)) (S.toList $ rtgt r)
   selectBySrc f = S.toList . fst $ S.partition (\r -> f`S.member`(rsrc r)) rs
 
--- | There are only 2 kind of rules: 1) ones that depend on a Makefile, and 2) ones
--- that Makefile depends on. Case-2 is known in advance (for example, when the
--- the contents of a file is required to build a Makefile then Makefile depends
--- on this file). This function adds the case-1 dependencies.
+-- | There are only 2 kind of rules: 1) rules which depend on the Makefile, and
+-- 2) rules which Makefile depends on. Case-2 is known in advance (for example,
+-- when the contents of a file is required to build a Makefile then Makefile
+-- depends on this file). This function adds the case-1 dependencies.
 addMakeDeps :: File -> Set Recipe -> Set Recipe
-addMakeDeps makefile rs
-  | S.null (S.filter (\r -> makefile `S.member` (rtgt r)) rs) = rs
-  | otherwise = S.map addMakeDeps_ rs
-  where
-    addMakeDeps_ r | not (isRequiredFor rs r makefile) = addPrerequisite makefile r
-                   | otherwise = r
+addMakeDeps makefile rs = S.map addMakeDeps_ rs where
+  addMakeDeps_ r | not (isRequiredFor rs r makefile) = addPrerequisite makefile r
+                 | otherwise = r
 
 
 
@@ -210,19 +236,34 @@
     line ""
 
   sr <- region "SERVICE" $ do
-    line ""
-    line "# Prebuild/postbuild section"
-    line ""
     r <- runA_ "<internal>" $ do
       produce (queryTargets (recipes ms))
       unsafeShell [cmd|-mkdir .cake3|]
       commands (rcmd $ prebuilds ms)
-      unsafeShell [cmd|$(make) -f $(outputFile ms) MAIN=1 $(makecmdgoals)|]
+      unsafeShell [cmd|$(make) -f $(outputFile ms) $(makecmdgoals)|]
       commands (rcmd $ postbuilds ms)
       markPhony
-    writeRules $ applyPlacement (placement ms) $ fixMultiTarget [r]
+
     line ""
+    line "# Prebuild/postbuild section"
+    line ""
+    line "export MAIN=1" 
+    line ""
 
+    case hasClean (recipes ms) of
+      True -> do
+        writeRules $ applyPlacement (placement ms)
+                   $ fixMultiTarget [r]
+      False -> do
+        line "ifneq ($(MAKECMDGOALS),clean)"
+        line ""
+        writeRules $ applyPlacement (placement ms)
+                   $ fixMultiTarget [r]
+        line ""
+        line "endif"
+        writeRules $ defineClean (outputFile ms) (recipes ms)
+    line ""
+
   hdr <- runLines $ do
     line "# This Makefile was generated by the Cake3"
     line "# https://github.com/grwlf/cake3"
@@ -264,7 +305,8 @@
     | otherwise = do
       inner <- writeRegions' rs
       runLines $ do
-        line (printf "ifdef %s" (map toUpper $ mrname r))
+        line (printf "ifeq ($(%s),1)" (map toUpper $ mrname r))
+        line (printf "unexport %s" (map toUpper $ mrname r))
         text (mrtext r)
         line "else"
         text inner
