diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,32 +1,36 @@
 # Changelog for shake-language-c
 
-## [v0.7.1][]
+## v0.8.0
 
+* Refactor NMF file creation in NaCl module
+
+## v0.7.1
+
 * Fix compilation error with GHC 7.10 in test suite (#25)
 
-## [v0.7.0][]
+## v0.7.0
 
 * Add `arm64` ARM version
 * Add support for `arm64` to OSX toolchains
 * Fix compilation error with GHC 7.10 (#25)
 
-## [v0.6.4][]
+## v0.6.4
 
 * Fix Android toolchain definition for `x86` architecture
 
-## [v0.6.3][]
+## v0.6.3
 
 * Fix bug in `Development.Shake.Language.C.Target.OSX`: `getPlatformVersionsWithRoot` works correctly now with SDK directories without version number, as introduced by Xcode 6
 
-## [v0.6.2][]
+## v0.6.2
 
 Bug fix release.
 
-## [v0.6.1][]
+## v0.6.1
 
 Bug fix release.
 
-## [v0.6.0][]
+## v0.6.0
 
 ### Added
 
@@ -44,13 +48,7 @@
 * Remove `libppapi`, `libppapi_cpp`, `libnacl_io`, `libppapi_simple` from `Development.Shake.Language.C.Target.NaCl`.
 * Remove `Development.Shake.Language.C.Target.archString`.
 
-## [v0.5.0][]
+## v0.5.0
 
 First released version.
 
-[v0.6.4]: https://github.com/samplecount/shake-language-c/tree/v0.6.4
-[v0.6.3]: https://github.com/samplecount/shake-language-c/tree/v0.6.3
-[v0.6.2]: https://github.com/samplecount/shake-language-c/tree/v0.6.2
-[v0.6.1]: https://github.com/samplecount/shake-language-c/tree/v0.6.1
-[v0.6.0]: https://github.com/samplecount/shake-language-c/tree/v0.6.0
-[v0.5.0]: https://github.com/samplecount/shake-language-c/tree/v0.5.0
diff --git a/shake-language-c.cabal b/shake-language-c.cabal
--- a/shake-language-c.cabal
+++ b/shake-language-c.cabal
@@ -13,7 +13,7 @@
 -- limitations under the License.
 
 Name:         shake-language-c
-Version:      0.7.1
+Version:      0.8.0
 Synopsis:     Utilities for cross-compiling with Shake
 Description:  This library provides <http://hackage.haskell.org/package/shake Shake> utilities for cross-compiling @C@, @C++@ and @ObjC@ code for various target platforms. Currently supported target platforms are Android, iOS, Linux, MacOS X, Windows\/MinGW and Google Portable Native Client (PNaCl). Supported host platforms are MacOS X, Linux and Windows.
 Category:     Development
diff --git a/src/Development/Shake/Language/C/Target/NaCl.hs b/src/Development/Shake/Language/C/Target/NaCl.hs
--- a/src/Development/Shake/Language/C/Target/NaCl.hs
+++ b/src/Development/Shake/Language/C/Target/NaCl.hs
@@ -28,7 +28,8 @@
   , toolChain
   , finalize
   , translate
-  , Arch(..)
+  , Executable(..)
+  , Program(..)
   , mk_nmf
 ) where
 
@@ -130,44 +131,44 @@
   command_ [] (toolFromString tc "finalize")
               ["-arch", archName, "-o", output, input]
 
--- | Pepper target architecture
-data Arch =
-    PNaCl       -- ^ Portable Native Client architecture
-  | NaCl C.Arch -- ^ Native Client architecture for specific CPU architecture
-  deriving (Eq, Show)
+-- | Executable specification for Native Client Manifest (nmf) files.
+data Executable = Executable {
+    executablePath :: FilePath      -- ^ Relative path to executable.
+  , optimizationLevel :: Maybe Int  -- ^ Optional optimization level.
+  } deriving (Eq, Show)
 
--- | Create Native Client Manifest (nmf) file.
+-- | Program specification for Native Client Manifest (nmf) files.
+data Program = Program {
+    pnaclTranslate :: Executable    -- ^ Release executable (pexe)
+  , pnaclDebug :: Maybe Executable  -- ^ Executable used when debugging (bit code).
+  } deriving (Eq, Show)
+
+-- | Create Native Client Manifest (nmf) files.
 --
--- This file is needed for serving NaCl\/PNaCl outside the Google Play store. See the native client <https://developer.chrome.com/native-client/reference/nacl-manifest-format documentation> for more information on the file format.
-mk_nmf :: [(Arch, FilePath)]  -- ^ List of executables with the corresponding architecture
-       -> FilePath            -- ^ Output file
+-- This file is needed for serving PNaCl outside the Google Play store. See the native client <https://developer.chrome.com/native-client/reference/nacl-manifest-format documentation> for more information on the file format.
+mk_nmf :: Program  -- ^ Program specification
+       -> FilePath    -- ^ Output file
        -> Action ()
-mk_nmf inputs output = do
-  need $ map snd inputs
-  writeFileLines output $ [
+mk_nmf program output = do
+  need $  [executablePath (pnaclTranslate program)]
+       ++ maybe [] ((:[]).executablePath) (pnaclDebug program)
+  writeFileChanged output . unlines $ [
       "{"
     , "  \"program\": {"
+    , "    \"portable\": {"
     ]
-    ++ intercalate [","] (map program inputs) ++
+    ++ entry "pnacl-translate" (pnaclTranslate program)
+    ++ maybe [] (\e -> [","] ++ entry "pnacl-debug" e) (pnaclDebug program)
+    ++
     [ "    }"
     , "  }"
     , "}"
     ]
   where
-    program (PNaCl, input) = [
-        "    \"portable\": {"
-      , "      \"pnacl-translate\": {"
-      , "        \"url\": \"" ++ makeRelative (takeDirectory output) input ++ "\""
-      , "      }"
-      ]
-    program (NaCl arch, input) =
-      let archName = case arch of
-                        X86 X86_64 -> "x86_64"
-                        X86 _      -> "x86_32"
-                        Arm _      -> "arm"
-                        _          -> error $ "mk_nmf: Unsupported architecture " ++ show arch
-      in [
-           "    \"" ++ archName ++ "\": {"
-         , "      \"url\": \"" ++ makeRelative (takeDirectory output) input ++ "\""
-         , "    }"
-         ]
+    entry what exe = [
+        "      \"" ++ what ++ "\": {"
+      , "        \"url\": \"" ++ makeRelative (takeDirectory output) (executablePath exe) ++ "\""
+      ] ++ maybe [] (\n ->
+       ["      , \"optlevel\": " ++ show n]) (optimizationLevel exe)
+        ++
+      [ "      }" ]
