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.2.1.0
+version:             0.3.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.
@@ -54,13 +54,16 @@
     . 
       * Execute the application to obtain the Makefile
     .
-    See the README on the GitHub <https://github.com/grwlf/cake3> for more information.
+    See the README on the GitHub <https://github.com/grwlf/cake3> for more
+    information. Distribution contains several example projects.
     .
     /Changes/
     .
     * 0.1 - Initial release
     .
     * 0.2 - Redesign (simplify) monadic interface, add support for prebuild/postbuild actions.
+    .
+    * 0.3 - API changes, improve documentation, improve UrWeb extension
 
 
 category:            Development
diff --git a/src/Development/Cake3.hs b/src/Development/Cake3.hs
--- a/src/Development/Cake3.hs
+++ b/src/Development/Cake3.hs
@@ -130,8 +130,7 @@
 runMake :: Make a -> IO String
 runMake mk = runMake' defaultMakefile mk return
 
--- | Execute Make action, place the recipe above all other recipes (it will be
--- higher in the final Makefile)
+-- | Raise the recipe's priority (it will appear higher in the final Makefile)
 withPlacement :: (MonadMake m) => m (Recipe,a) -> m (Recipe,a)
 withPlacement mk = do
   (r,a) <- mk
@@ -145,33 +144,42 @@
 -- >  phony "clean"
 -- >  unsafeShell [cmd|rm $elf $os $d|]
 -- >
-phony :: String -> A ()
+phony ::
+  String -- ^ A name of phony target
+  -> A ()
 phony name = do
   produce (W.fromFilePath name :: File)
   markPhony
 
--- | Build a Recipe using recipe builder @act. Don't change recipe's priority.
-rule2 :: (MonadMake m) => A a -> m (Recipe,a)
+-- | 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.
+--
+-- /Example/
+-- Lets declare a rule which builds "main.o" out of "main.c" and "CFLAGS"
+-- variable
+--
+-- > let c = file "main.c"
+-- > rule $ shell [cmd| gcc -c $(extvar "CFLAGS") -o @(c.="o") $c |]
+--
+rule2 :: (MonadMake m)
+  => A a -- ^ Recipe builder
+  -> m (Recipe,a) -- ^ The recipe itself and the recipe builder's result
 rule2 act = liftMake $ do
   loc <- getLoc
   (r,a) <- runA loc act
   addRecipe r
   return (r,a)
 
--- | Version of rule2 which places it's recipe above all other recipies.
---
--- > let c = file "main.c"
---
--- Declare a rule to build "main.o" out of "main.c" and "CFLAGS" variable
---
--- > rule $ shell [cmd| gcc -c $(extvar "CFLAGS") -o @(c.="o") $c |]
---
+-- | A version of rule2. Rule places it's recipe above all recipies defined so
+-- far.
 rule
-  :: A a    -- ^ Rule builder
+  :: A a    -- ^ Recipe builder
   -> Make a
 rule act = snd <$> withPlacement (rule2 act)
 
--- | Version of rule2, without Make monad set explicitly
+-- | A version of rule, without monad set explicitly
 rule' :: (MonadMake m) => A a -> m a
 rule' act = liftMake $ snd <$> withPlacement (rule2 act)
 
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,10 +39,10 @@
 import Development.Cake3.Monad
 import Development.Cake3
 
-data UrpAllow = UrpMime | UrpUrl
+data UrpAllow = UrpMime | UrpUrl | UrpResponseHeader
   deriving(Show,Data,Typeable)
 
-data UrpRewrite = UrpStyle
+data UrpRewrite = UrpStyle | UrpAll
   deriving(Show,Data,Typeable)
 
 data UrpHdrToken = UrpDatabase String
@@ -52,10 +52,13 @@
                  | UrpLibrary File
                  | UrpDebug
                  | UrpInclude File
-                 | UrpLink File
+                 | UrpLink File String
+                 | UrpSrc File String String
+                 | UrpPkgConfig String
                  | UrpFFI File
-                 | UrpJSFunc String String
+                 | UrpJSFunc String String String -- ^ Module name, UrWeb name, JavaScript name
                  | UrpSafeGet String
+                 | UrpScript String
   deriving(Show,Data,Typeable)
 
 data UrpModToken
@@ -83,10 +86,23 @@
 instance (MonadAction a m) => RefInput a m UWExe where
   refInput (UWExe u) = refInput (urpExe u)
  
+class UrpLike x where
+  toUrp :: x -> Urp
+  tempfiles :: x -> [File]
+  tempfiles = (\x -> (urpObjs x) ++ maybeToList (urpSql' x) ++ maybeToList (urpExe' x)) . toUrp
 
+instance UrpLike Urp where
+  toUrp = id
+
+instance UrpLike UWLib where
+  toUrp (UWLib x) = x
+instance UrpLike UWExe where
+  toUrp (UWExe x) = x
+
 urpDeps :: Urp -> [File]
 urpDeps (Urp _ _ hdr mod) = foldl' scan2 (foldl' scan1 mempty hdr) mod where
-  scan1 a (UrpLink f) = f:a
+  scan1 a (UrpLink f _) = f:a
+  scan1 a (UrpSrc f _ _) = (f.="o"):a
   scan1 a (UrpInclude f) = f:a
   scan1 a _ = a
   scan2 a (UrpModule1 f) = f:a
@@ -104,18 +120,28 @@
   Nothing -> error "ur project defines no SQL file"
   Just sql -> sql
 
+urpSrcs (Urp _ _ hdr _) = foldl' scan [] hdr where
+  scan a (UrpSrc f cfl lfl) = (f,cfl):a
+  scan a _ = a
+
 urpObjs (Urp _ _ hdr _) = foldl' scan [] hdr where
-  scan a (UrpLink f) = f:a
+  scan a (UrpSrc f _ lfl) = (f.="o"):a
+  scan a (UrpLink f lfl) = (f):a
   scan a _ = a
 
 urpLibs (Urp _ _ hdr _) = foldl' scan [] hdr where
   scan a (UrpLibrary f) = f:a
   scan a _ = a
 
+urpExe' = uexe
 urpExe u = case uexe u of
   Nothing -> error "ur project defines no EXE file"
   Just exe -> exe
 
+urpPkgCfg (Urp _ _ hdr _) = foldl' scan [] hdr where
+  scan a (UrpPkgConfig s) = s:a
+  scan a _ = a
+
 data UrpState = UrpState {
     urpst :: Urp
   } deriving (Show)
@@ -128,24 +154,35 @@
 instance ToUrpWord UrpAllow where
   toUrpWord (UrpMime) = "mime"
   toUrpWord (UrpUrl) = "url"
+  toUrpWord (UrpResponseHeader) = "responseHeader"
 
 instance ToUrpWord UrpRewrite where
   toUrpWord (UrpStyle) = "style"
+  toUrpWord (UrpAll) = "all"
 
 class ToUrpLine a where
   toUrpLine :: FilePath -> a -> String
 
+maskPkgCfg s = "%" ++ (map toUpper s) ++ "%"
+
 instance ToUrpLine UrpHdrToken where
   toUrpLine up (UrpDatabase dbs) = printf "database %s" dbs
   toUrpLine up (UrpSql f) = printf "sql %s" (up </> toFilePath f)
   toUrpLine up (UrpAllow a s) = printf "allow %s %s" (toUrpWord a) s
   toUrpLine up (UrpRewrite a s) = printf "rewrite %s %s" (toUrpWord a) s
-  toUrpLine up (UrpLibrary f) = printf "library %s" (up </> toFilePath (dropExtensions f))
+  toUrpLine up (UrpLibrary f)
+    | (takeFileName f) == "lib.urp" = printf "library %s" (up </> toFilePath (takeDirectory f))
+    | 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) = printf "link %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 (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)
+  toUrpLine up (UrpJSFunc s1 s2 s3) = printf "jsFunc %s.%s = %s" s1 s2 s3
+  toUrpLine up (UrpScript s) = printf "script %s" s
+  toUrpLine up e = error $ "toUrpLine: unhandled case " ++ (show e)
 
 instance ToUrpLine UrpModToken where
   toUrpLine up (UrpModule1 f) = up </> toFilePath (dropExtensions f)
@@ -155,40 +192,53 @@
 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)
+-- instance (Monad m) => MonadAction (UrpGen (A' m)) m where
+--   liftAction a = UrpGen (lift a)
 
 toFile f wr = liftIO $ writeFile (toFilePath f) $ execWriter $ wr
 
 line :: (MonadWriter String m) => String -> m ()
 line s = tell (s++"\n")
 
-uwlib :: File -> UrpGen (A' (Make' IO)) () -> Make UWLib
+uwlib :: File -> UrpGen (Make' IO) () -> Make UWLib
 uwlib urpfile m = do
-  (_,u) <- rule2 $ do
-    ((),s) <- runStateT (unUrpGen m) (defState urpfile)
-    let u@(Urp _ _ hdr mod) = urpst s
-    let up = urpUp urpfile
+  ((),s) <- runStateT (unUrpGen m) (defState urpfile)
+  let u@(Urp _ _ hdr mod) = urpst s
+  let pkgcfg = (urpPkgCfg u)
 
-    toFile urpfile $ do
-      forM hdr (line . toUrpLine up)
+  inp <- rule' $ do
+    let inp = urpfile .= "urp.in"
+    toFile inp $ do
+      forM hdr (line . toUrpLine (urpUp urpfile))
       line ""
-      forM mod (line . toUrpLine up)
+      forM mod (line . toUrpLine (urpUp urpfile))
 
-    forM_ (urpObjs u) $ \o -> do
-      let incl = makevar "URINCL" "$(shell urweb -print-cinclude)"
+    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
-        shell [cmd| $cc -c -I $incl -o @o $(o .= "c") |]
+        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 @urpfile|]
-    return u
+    shell [cmd|touch @inp|]
 
+  rule' $ do
+    let cpy = [cmd|cat $inp|] :: 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 |]
+
   return $ UWLib u
 
-uwapp :: String -> File -> UrpGen (A' (Make' IO)) () -> Make UWExe
+uwapp :: String -> File -> UrpGen (Make' IO) () -> Make UWExe
 uwapp opts urpfile m = do
   (UWLib u') <- uwlib urpfile m
   let u = u' { uexe = Just (urpfile .= "exe") }
@@ -198,6 +248,7 @@
     case urpSql' u of
       Nothing -> return ()
       Just sql -> produce sql
+    depend (makevar "URVERSION" "$(shell urweb -version)")
     unsafeShell [cmd|urweb $(string opts) $((takeDirectory urpfile)</>(takeBaseName urpfile))|]
   return $ UWExe u
 
@@ -218,35 +269,57 @@
 urpUp :: File -> FilePath
 urpUp f = F.joinPath $ map (const "..") $ filter (/= ".") $ F.splitDirectories $ F.takeDirectory $ toFilePath f
 
-newtype UrEmbed = Urembed File
-  deriving (Show)
+-- | Dir name , file to embed
+-- data UrEmbed = Urembed File File
+--   deriving (Show)
 
-data UrpLibReference
-  = UrpLibStandalone File 
-  | UrpLibInternal UWLib
-  | UrpLibEmbed UrEmbed
-  deriving(Show)
+-- data UrpLibReference
+--   = UrpLibStandaloneMake File 
+--   | UrpLibStandaloneMake2 File 
+--   | UrpLibInternal UWLib
+--   | UrpLibEmbed File File
+--   deriving(Show)
 
-library' :: (MonadMake m) => File -> UrpGen m ()
-library' l = do
-  when ((takeExtension l) /= ".urp") $ do
-    fail "library declaration for %s should ends with '.urp'" (toFilePath l)
-  addHdr $ UrpLibrary l
+-- | 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
+  -> UrpGen m ()
+library' ml = do
+  ls <- liftMake ml
+  forM_ ls $ \l -> do
+    when ((takeExtension l) /= ".urp") $ do
+      fail $ printf "library declaration for %s should ends with '.urp'" (toFilePath l)
+    addHdr $ UrpLibrary l
 
-library :: (MonadMake m) => UrpLibReference -> UrpGen m ()
-library (UrpLibStandalone l) = do
-  library' l
-  when ((toFilePath $ takeDirectory l) /= ".") $ do
-    prebuild [cmd| $(make) -C $(takeDirectory l) |]
-library (UrpLibInternal (UWLib u)) = library' (urp u)
-library (UrpLibEmbed ue) = error "urembed is not defined"
+-- | Include a library defined somewhere in the current project
+library :: (MonadMake m) => UWLib -> UrpGen m ()
+library (UWLib u) = library' $ do
+  return [urp u]
 
-standalone f = UrpLibStandalone f
-internal u = UrpLibInternal u
-embed e = UrpLibEmbed e
+-- | Build a file using external Makefile facility.
+externalMake' ::
+     File -- ^ External Makefile
+  -> File -- ^ External file to refer to
+  -> Make [File]
+externalMake' mk f = do
+  prebuild [cmd|$(make) -C $(string $ toFilePath $ takeDirectory mk) -f $(string $ takeFileName mk)|]
+  return [f]
 
-module_ :: (MonadMake m) => UrpModToken -> UrpGen m ()
+-- | Build a file from external project. It is expected, that this project has a
+-- 'Makwfile' in it's root directory
+externalMake ::
+     File -- ^ File from the external project to build
+  -> Make [File]
+externalMake f = externalMake' (takeDirectory f </> "Makefile") f
+
+-- | Build a file from external project. It is expected, that this project has a
+-- fiel.mk (a Makefile with an unusual name) in it's root directory
+externalMake2 :: File -> Make [File]
+externalMake2 f = externalMake' ((takeDirectory f </> takeFileName f) .= "mk") f
+
+ur, module_ :: (MonadMake m) => UrpModToken -> UrpGen m ()
 module_ = addMod
+ur = addMod
 
 pair f = UrpModule2 (f.="ur") (f.="urs")
 single f = UrpModule1 f
@@ -258,16 +331,25 @@
 include :: (MonadMake m) => File -> UrpGen m ()
 include f = addHdr $ UrpInclude f
 
+link' :: (MonadMake m) => File -> String -> UrpGen m ()
+link' f fl = addHdr $ UrpLink f fl
+
 link :: (MonadMake m) => File -> UrpGen m ()
-link f = addHdr $ UrpLink f
+link f = link' f []
 
+csrc'  :: (MonadMake m) => File -> String -> String -> UrpGen m ()
+csrc' f cfl lfl = addHdr $ UrpSrc f cfl lfl
+
+csrc  :: (MonadMake m) => File -> UrpGen m ()
+csrc f = csrc' f [] []
+
 ffi :: (MonadMake m) => File -> UrpGen m ()
 ffi s = addHdr $ UrpFFI s
 
 sql :: (MonadMake m) => File -> UrpGen m ()
 sql f = addHdr $ UrpSql f
   
-jsFunc n s = addHdr $ UrpJSFunc n s
+jsFunc m u j = addHdr $ UrpJSFunc m u j
 
 safeGet s = addHdr $ UrpSafeGet s
 
@@ -277,14 +359,24 @@
 
 style = UrpStyle
 
+all = UrpAll
+
+responseHeader = UrpResponseHeader
+
+script :: (MonadMake m) => String -> UrpGen m ()
+script s = addHdr $ UrpScript s
+
 guessMime inf = fixup $ BS.unpack (defaultMimeLookup (fromString inf)) where
   fixup "application/javascript" = "text/javascript"
   fixup m = m
 
+pkgconfig :: (MonadMake m) => String -> UrpGen m ()
+pkgconfig l = addHdr $ UrpPkgConfig l
+
 data JSFunc = JSFunc {
-    urdecl :: String
-  , urname :: String
-  , jsname :: String
+    urdecl :: String -- ^ URS declaration for this function
+  , urname :: String -- ^ UrWeb name of this function
+  , jsname :: String -- ^ JavaScript name of this function
   } deriving(Show)
 
 data JSType = JSType {
@@ -467,7 +559,7 @@
     line $ "val geturl = url(blobpage {})"
 
   forM_ jsdecls $ \decl -> do
-    jsFunc (printf "%s.%s = %s" (modname jsmod) (urname decl)) (jsname decl)
+    addHdr $ UrpJSFunc (modname jsmod) (urname decl) (jsname decl)
   ffi (jsmod ".urs")
 
   safeGet $ printf "%s/blobpage" (modname wrapmod)
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
@@ -107,7 +107,8 @@
   let file = file' loc
   let bin = bin' (file ".")
 
-  s <- runMake $ do
+  let mk = (("." </> takeFileName tgturp) .= "mk")
+  writeMake (file mk) $ do
     let urp = file (takeFileName tgturp)
     u <- uwlib urp $ do
       forM_ (ins`zip`cntnts) $ \(i,c) -> do
@@ -116,9 +117,6 @@
       phony "all"
       depend u
   
-  let mk = (("." </> takeFileName tgturp) .= "mk")
-  writeFile mk s
-
   when (drm == False) $ do
     system $ printf "make -f %s" mk
     return ()
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
@@ -331,6 +331,9 @@
   refInput v@(CakeString s) = do
     return_text s
 
+instance (MonadAction a m) => RefInput a m (CommandGen' m) where
+  refInput (CommandGen' a) = liftAction a
+
 -- | Add it's argument to the list of dependencies (prerequsites) of a current
 -- recipe under construction
 depend :: (RefInput a m x)
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
@@ -215,11 +215,10 @@
     line ""
     r <- runA_ "<internal>" $ do
       produce (queryTargets (recipes ms))
+      unsafeShell [cmd|-mkdir .cake3|]
       commands (rcmd $ prebuilds ms)
-      commands [[CmdStr "$(MAKE) MAIN=1 $(MAKECMDGOALS)"]]
+      unsafeShell [cmd|$(make) -f $(outputFile ms) MAIN=1 $(makecmdgoals)|]
       commands (rcmd $ postbuilds ms)
-      variables (rvars $ prebuilds ms)
-      variables (rvars $ postbuilds ms)
       markPhony
     writeRules $ applyPlacement (placement ms) $ fixMultiTarget [r]
     line ""
@@ -228,7 +227,7 @@
     line "# This Makefile was generated by the Cake3"
     line "# https://github.com/grwlf/cake3"
     line ""
-    line "GUARD = .GUARD_$(1)_$(shell echo $($(1)) | md5sum | cut -d ' ' -f 1)"
+    line "GUARD = .cake3/GUARD_$(1)_$(shell echo $($(1)) | md5sum | cut -d ' ' -f 1)"
     line ""
     
   writeRegions hdr [mr,sr]
@@ -302,6 +301,6 @@
   -- FIXME: add those on the higher level
   forM_ vs $ \v -> do
     line (printf "$(call GUARD,%s):" (vname v))
-    line (printf "\trm -f .GUARD_%s_*" (vname v))
+    line (printf "\trm -f .cake3/GUARD_%s_*" (vname v))
     line "\ttouch $@"
 
diff --git a/src/System/FilePath/Wrapper.hs b/src/System/FilePath/Wrapper.hs
--- a/src/System/FilePath/Wrapper.hs
+++ b/src/System/FilePath/Wrapper.hs
@@ -42,6 +42,7 @@
   takeExtension :: a -> String
   takeExtensions :: a -> String
   dropExtensions :: a -> a
+  dropExtension :: a -> a
 
 -- | Redefine standard @</>@ operator to work with Files
 (</>) :: (FileLike a) => a -> String -> a
@@ -62,6 +63,7 @@
   replaceExtension (FileT a) ext = FileT (replaceExtension a ext)
   takeDirectory (FileT a) = FileT (takeDirectory a)
   dropExtensions (FileT a) = FileT (dropExtensions a)
+  dropExtension (FileT a) = FileT (dropExtension a)
 
 instance FileLike FilePath where
   -- fromFilePath = id
@@ -74,4 +76,5 @@
   takeExtension = F.takeExtension
   takeExtensions = F.takeExtensions
   dropExtensions = F.dropExtensions
+  dropExtension = F.dropExtension
 
