diff --git a/CHANGES.txt b/CHANGES.txt
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,9 @@
 Changelog for Shake
 
+0.13.1
+    Remove all package upper bounds
+    #126, Ninja compatibility if Ninja fails to create a file
+    #123, generate Chrome compatible traces
 0.13
     #122, make --report=- write a report to stdout
     Improve the profile report summary
diff --git a/Development/Shake/Core.hs b/Development/Shake/Core.hs
--- a/Development/Shake/Core.hs
+++ b/Development/Shake/Core.hs
@@ -376,7 +376,7 @@
                     forM_ shakeReport $ \file -> do
                         when (shakeVerbosity >= Normal) $
                             output Normal $ "Writing report to " ++ file
-                        buildReport report file
+                        buildReport file report
             maybe (return ()) (throwIO . snd) =<< readIORef except
             sequence_ . reverse =<< readIORef after
 
diff --git a/Development/Shake/Report.hs b/Development/Shake/Report.hs
--- a/Development/Shake/Report.hs
+++ b/Development/Shake/Report.hs
@@ -21,17 +21,13 @@
 
 
 -- | Generates an report given some build system profiling data.
-buildReport :: [ReportEntry] -> FilePath -> IO ()
-buildReport reports out
-    | takeExtension out == ".js" = writeFile out $ "var shake = \n" ++ showJSON reports
-    | takeExtension out == ".json" = writeFile out $ showJSON reports
-    | out == "-" = putStr $ unlines $ reportSummary reports
-    | otherwise = do
-        htmlDir <- getDataFileName "html"
-        report <- LBS.readFile $ htmlDir </> "report.html"
-        let f name | name == "data.js" = return $ LBS.pack $ "var shake = \n" ++ showJSON reports
-                   | otherwise = LBS.readFile $ htmlDir </> name
-        LBS.writeFile out =<< runTemplate f report
+buildReport :: FilePath -> [ReportEntry] -> IO ()
+buildReport out xs
+    | takeExtension out == ".js" = writeFile out $ "var shake = \n" ++ reportJSON xs
+    | takeExtension out == ".json" = writeFile out $ reportJSON xs
+    | takeExtension out == ".trace" = writeFile out $ reportTrace xs
+    | out == "-" = putStr $ unlines $ reportSummary xs
+    | otherwise = LBS.writeFile out =<< reportHTML xs
 
 
 reportSummary :: [ReportEntry] -> [String]
@@ -52,19 +48,48 @@
     where ls = filter ((==) 0 . repBuilt) xs
 
 
-showJSON :: [ReportEntry] -> String
-showJSON xs = "[" ++ intercalate "\n," (map showEntry xs) ++ "\n]"
+reportHTML :: [ReportEntry] -> IO LBS.ByteString
+reportHTML xs = do
+    htmlDir <- getDataFileName "html"
+    report <- LBS.readFile $ htmlDir </> "report.html"
+    let f name | name == "data.js" = return $ LBS.pack $ "var shake = \n" ++ reportJSON xs
+               | otherwise = LBS.readFile $ htmlDir </> name
+    runTemplate f report
+
+
+reportTrace :: [ReportEntry] -> String
+reportTrace xs = jsonListLines $
+    showEntries 0 [y{repCommand=repName x} | x <- xs, y <- repTraces x] ++
+    showEntries 1 (concatMap repTraces xs)
     where
-        showEntry ReportEntry{..} = (\xs -> "{" ++ intercalate ", " xs ++ "}") $
-            ["\"name\":" ++ show repName
-            ,"\"built\":" ++ show repBuilt
-            ,"\"changed\":" ++ show repChanged
-            ,"\"depends\":" ++ show repDepends
-            ,"\"execution\":" ++ show repExecution] ++
-            ["\"traces\":[" ++ intercalate "," (map showTrace repTraces) ++ "]" | not $ null repTraces]
-        showTrace ReportTrace{..} =
-            "{\"command\":" ++ show repCommand ++ ",\"start\":" ++ show repStart ++ ",\"stop\":" ++ show repStop ++ "}"
+        showEntries pid xs = map (showEntry pid) $ snd $ mapAccumL alloc [] $ sortBy (compare `on` repStart) xs
+        alloc as r | (a1,an:a2) <- break (\a -> repStop a <= repStart r) as = (a1++r:a2, (length a1,r))
+                   | otherwise = (as++[r], (length as,r))
+        showEntry pid (tid, ReportTrace{..}) = jsonObject
+            [("args","{}"), ("ph",show "X"), ("cat",show "target")
+            ,("name",show repCommand), ("tid",show tid), ("pid",show pid)
+            ,("ts",show $ 1000000*repStart), ("dur",show $ 1000000*(repStop-repStart))]
 
+
+reportJSON :: [ReportEntry] -> String
+reportJSON = jsonListLines . map showEntry
+    where
+        showEntry ReportEntry{..} = jsonObject $
+            [("name", show repName)
+            ,("built", show repBuilt)
+            ,("changed", show repChanged)
+            ,("depends", show repDepends)
+            ,("execution", show repExecution)] ++
+            [("traces", jsonList $ map showTrace repTraces) | not $ null repTraces]
+        showTrace ReportTrace{..} = jsonObject
+            [("command",show repCommand), ("start",show repStart), ("stop",show repStop)]
+
+jsonListLines xs = "[" ++ intercalate "\n," xs ++ "\n]"
+jsonList xs = "[" ++ intercalate "," xs ++ "]"
+jsonObject xs = "{" ++ intercalate ", " [show a ++ ":" ++ b | (a,b) <- xs] ++ "}"
+
+---------------------------------------------------------------------
+-- TEMPLATE ENGINE
 
 -- | Template Engine. Perform the following replacements on a line basis:
 --
diff --git a/Development/Shake/Rules/File.hs b/Development/Shake/Rules/File.hs
--- a/Development/Shake/Rules/File.hs
+++ b/Development/Shake/Rules/File.hs
@@ -79,8 +79,9 @@
         where bool b = if b then EqualCheap else NotEqual
 
 storedValueError :: ShakeOptions -> Bool -> String -> FileQ -> IO FileA
-storedValueError opts input msg x = fromMaybe (error err) <$> storedValue opts2 x
-    where err = msg ++ "\n  " ++ unpackU (fromFileQ x)
+storedValueError opts input msg x = fromMaybe def <$> storedValue opts2 x
+    where def = if shakeCreationCheck opts || input then error err else FileA fileInfoNeq fileInfoNeq fileInfoNeq
+          err = msg ++ "\n  " ++ unpackU (fromFileQ x)
           opts2 = if not input && shakeChange opts == ChangeModtimeAndDigestInput then opts{shakeChange=ChangeModtime} else opts
 
 
diff --git a/Development/Shake/Rules/Files.hs b/Development/Shake/Rules/Files.hs
--- a/Development/Shake/Rules/Files.hs
+++ b/Development/Shake/Rules/Files.hs
@@ -137,6 +137,7 @@
     ys <- liftIO $ mapM (storedValue opts) xs
     case sequence ys of
         Just ys -> return $ FilesA ys
+        Nothing | not $ shakeCreationCheck opts -> return $ FilesA []
         Nothing -> do
             let missing = length $ filter isNothing ys
             error $ "Error, " ++ name ++ " rule failed to build " ++ show missing ++
diff --git a/Development/Shake/Types.hs b/Development/Shake/Types.hs
--- a/Development/Shake/Types.hs
+++ b/Development/Shake/Types.hs
@@ -96,9 +96,10 @@
         -- ^ Defaults to 'False'. Operate in staunch mode, where building continues even after errors,
         --   similar to @make --keep-going@.
     ,shakeReport :: [FilePath]
-        -- ^ Defaults to '[]'. Write a profiling report to a file, showing which rules rebuilt,
+        -- ^ Defaults to @[]@. Write a profiling report to a file, showing which rules rebuilt,
         --   why, and how much time they took. Useful for improving the speed of your build systems.
-        --   If the file extension is @.json@ it will write JSON data, if @.js@ it will write Javascript,
+        --   If the file extension is @.json@ it will write JSON data; if @.js@ it will write Javascript;
+        --   if @.trace@ it will write trace events (load into @about:\/\/tracing@ in Chrome);
         --   otherwise it will write HTML.
     ,shakeLint :: Maybe Lint
         -- ^ Defaults to 'Nothing'. Perform sanity checks during building, see 'Lint' for details.
@@ -124,6 +125,9 @@
         --   are not used. Useful for profiling the non-command portion of the build system.
     ,shakeChange :: Change
         -- ^ Default to 'ChangeModtime'. How to check if a file has changed, see 'Change' for details.
+    ,shakeCreationCheck :: Bool
+        -- ^ Default to 'True'. After running a rule to create a file, is it an error if the file does not exist.
+        --   Provided for compatibility with @make@ and @ninja@ (which have ugly file creation semantics).
     ,shakeProgress :: IO Progress -> IO ()
         -- ^ Defaults to no action. A function called when the build starts, allowing progress to be reported.
         --   The function is called on a separate thread, and that thread is killed when the build completes.
@@ -138,24 +142,25 @@
 
 -- | The default set of 'ShakeOptions'.
 shakeOptions :: ShakeOptions
-shakeOptions = ShakeOptions ".shake" 1 "1" Normal False [] Nothing (Just 10) Nothing [] False True False True ChangeModtime
+shakeOptions = ShakeOptions ".shake" 1 "1" Normal False [] Nothing (Just 10) Nothing [] False True False True ChangeModtime True
     (const $ return ())
     (const $ BS.putStrLn . BS.pack) -- try and output atomically using BS
 
 fieldsShakeOptions =
     ["shakeFiles", "shakeThreads", "shakeVersion", "shakeVerbosity", "shakeStaunch", "shakeReport"
     ,"shakeLint", "shakeFlush", "shakeAssume", "shakeAbbreviations", "shakeStorageLog"
-    ,"shakeLineBuffering", "shakeTimings", "shakeRunCommands", "shakeChange", "shakeProgress", "shakeOutput"]
+    ,"shakeLineBuffering", "shakeTimings", "shakeRunCommands", "shakeChange", "shakeCreationCheck"
+    ,"shakeProgress", "shakeOutput"]
 tyShakeOptions = mkDataType "Development.Shake.Types.ShakeOptions" [conShakeOptions]
 conShakeOptions = mkConstr tyShakeOptions "ShakeOptions" fieldsShakeOptions Prefix
-unhide x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 =
-    ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 (fromFunction x16) (fromFunction x17)
+unhide x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18 =
+    ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 (fromFunction x17) (fromFunction x18)
 
 instance Data ShakeOptions where
-    gfoldl k z (ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17) =
-        z unhide `k` x1 `k` x2 `k` x3 `k` x4 `k` x5 `k` x6 `k` x7 `k` x8 `k` x9 `k` x10 `k` x11 `k` x12 `k` x13 `k` x14 `k` x15 `k`
-        Function x16 `k` Function x17
-    gunfold k z c = k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ z unhide
+    gfoldl k z (ShakeOptions x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17 x18) =
+        z unhide `k` x1 `k` x2 `k` x3 `k` x4 `k` x5 `k` x6 `k` x7 `k` x8 `k` x9 `k` x10 `k` x11 `k` x12 `k` x13 `k` x14 `k` x15 `k` x16 `k`
+        Function x17 `k` Function x18
+    gunfold k z c = k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ k $ z unhide
     toConstr ShakeOptions{} = conShakeOptions
     dataTypeOf _ = tyShakeOptions
 
diff --git a/Examples/Ninja/Main.hs b/Examples/Ninja/Main.hs
--- a/Examples/Ninja/Main.hs
+++ b/Examples/Ninja/Main.hs
@@ -51,6 +51,14 @@
     run "-f../../Examples/Ninja/test5.ninja"
     assertExists $ obj "output file"
 
+    writeFile (obj "nocreate.log") ""
+    writeFile (obj "nocreate.in") ""
+    run "-f../../Examples/Ninja/nocreate.ninja"
+    assertNonSpace (obj "nocreate.log") "x"
+    run "-f../../Examples/Ninja/nocreate.ninja"
+    run "-f../../Examples/Ninja/nocreate.ninja"
+    assertNonSpace (obj "nocreate.log") "xxx"
+
     writeFile (obj "input") ""
     runFail "-f../../Examples/Ninja/lint.ninja bad --lint" "'needed' file required rebuilding"
     run "-f../../Examples/Ninja/lint.ninja good --lint"
diff --git a/Examples/Ninja/nocreate.ninja b/Examples/Ninja/nocreate.ninja
new file mode 100644
--- /dev/null
+++ b/Examples/Ninja/nocreate.ninja
@@ -0,0 +1,5 @@
+
+rule gen
+    command = echo x >> nocreate.log
+
+build nocreate.out: gen nocreate.in
diff --git a/Examples/Test/Docs.hs b/Examples/Test/Docs.hs
--- a/Examples/Test/Docs.hs
+++ b/Examples/Test/Docs.hs
@@ -204,7 +204,7 @@
     ".. /./ /.. ./ // \\ ../ " ++
     "ConstraintKinds GeneralizedNewtypeDeriving DeriveDataTypeable SetConsoleTitle " ++
     "Data.List System.Directory Development.Shake.FilePath main.m run .rot13 " ++
-    "NoProgress Error src rot13 .js .json " ++
+    "NoProgress Error src rot13 .js .json .trace about://tracing " ++
     ".make/i586-linux-gcc/output _make/.database foo/.. file.src file.out build " ++
     "/usr/special /usr/special/userbinary $CFLAGS %PATH% -O2 -j8 -j -j1 " ++
     "-threaded -rtsopts -I0 Function extension $OUT $C_LINK_FLAGS $PATH xterm $TERM main opts result flagValues argValues " ++
diff --git a/Start.hs b/Start.hs
--- a/Start.hs
+++ b/Start.hs
@@ -17,7 +17,7 @@
     resetTimings
     args <- getArgs
     withArgs ("--no-time":args) $
-        shakeArgsWith shakeOptions flags $ \opts targets -> do
+        shakeArgsWith shakeOptions{shakeCreationCheck=False} flags $ \opts targets -> do
             let tool = listToMaybe [x | Tool x <- opts]
             makefile <- case reverse [x | UseMakefile x <- opts] of
                 x:_ -> return x
diff --git a/shake.cabal b/shake.cabal
--- a/shake.cabal
+++ b/shake.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.10
 build-type:         Simple
 name:               shake
-version:            0.13
+version:            0.13.1
 license:            BSD3
 license-file:       LICENSE
 category:           Development
@@ -83,17 +83,17 @@
         base == 4.*,
         old-time,
         directory,
-        hashable >= 1.1.2.3 && < 1.3,
+        hashable >= 1.1.2.3,
         binary,
         filepath,
         process >= 1.1,
-        unordered-containers >= 0.2.1 && < 0.3,
+        unordered-containers >= 0.2.1,
         bytestring,
         utf8-string >= 0.3,
         time,
         random,
-        transformers >= 0.2 && < 0.4,
-        deepseq >= 1.1 && < 1.4
+        transformers >= 0.2,
+        deepseq >= 1.1
 
     if flag(portable)
         cpp-options: -DPORTABLE
@@ -155,17 +155,17 @@
         base == 4.*,
         old-time,
         directory,
-        hashable >= 1.1.2.3 && < 1.3,
+        hashable >= 1.1.2.3,
         binary,
         filepath,
         process >= 1.1,
-        unordered-containers >= 0.2.1 && < 0.3,
+        unordered-containers >= 0.2.1,
         bytestring,
         utf8-string >= 0.3,
         time,
         random,
-        transformers >= 0.2 && < 0.4,
-        deepseq >= 1.1 && < 1.4
+        transformers >= 0.2,
+        deepseq >= 1.1
 
     if flag(portable)
         cpp-options: -DPORTABLE
@@ -192,17 +192,17 @@
         base == 4.*,
         old-time,
         directory,
-        hashable >= 1.1.2.3 && < 1.3,
+        hashable >= 1.1.2.3,
         binary,
         filepath,
         process >= 1.1,
-        unordered-containers >= 0.2.1 && < 0.3,
+        unordered-containers >= 0.2.1,
         bytestring,
         utf8-string >= 0.3,
         time,
         random,
-        transformers >= 0.2 && < 0.4,
-        deepseq >= 1.1 && < 1.4,
+        transformers >= 0.2,
+        deepseq >= 1.1,
         QuickCheck >= 2.0
 
     if flag(portable)
