diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## Changes in 0.28.0
+  - Add support for `cxx-options` and `cxx-sources` (see #205)
+  - Add support for `data-dir` (see #100)
+  - Generate valid `.cabal` files when `verbatim` is used top-level (see #280)
+
 ## Changes in 0.27.0
   - Local defaults are now resolved relative to the file they are
     mentioned in, not the CWD that hpack is invoked from.
diff --git a/hpack.cabal b/hpack.cabal
--- a/hpack.cabal
+++ b/hpack.cabal
@@ -1,11 +1,11 @@
--- This file has been generated from package.yaml by hpack version 0.26.0.
+-- This file has been generated from package.yaml by hpack version 0.27.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 3172713e09611ee19cc9d92dafaabdc4ca26daada30517f9458fa486d4ae02ba
+-- hash: e6f8fbe41b4e0a521f34c4fea72bce81d6d2fbe27b00462a16c07b3b3d049d34
 
 name:           hpack
-version:        0.27.0
+version:        0.28.0
 synopsis:       An alternative format for Haskell packages
 description:    See README at <https://github.com/sol/hpack#readme>
 category:       Development
@@ -117,7 +117,7 @@
   build-depends:
       Cabal
     , Glob >=0.9.0
-    , HUnit
+    , HUnit >=1.6.0.0
     , QuickCheck
     , aeson >=1.2.1.0
     , base >=4.9 && <5
diff --git a/src/Hpack/Config.hs b/src/Hpack/Config.hs
--- a/src/Hpack/Config.hs
+++ b/src/Hpack/Config.hs
@@ -124,6 +124,7 @@
   , packageExtraSourceFiles = []
   , packageExtraDocFiles = []
   , packageDataFiles = []
+  , packageDataDir = Nothing
   , packageSourceRepository = Nothing
   , packageCustomSetup = Nothing
   , packageLibrary = Nothing
@@ -162,7 +163,7 @@
     deps xs = [(name, version) | (name, version) <- (Map.toList . unDependencies . sectionDependencies) xs]
 
 section :: a -> Section a
-section a = Section a [] mempty [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] mempty []
+section a = Section a [] mempty [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] mempty []
 
 packageConfig :: FilePath
 packageConfig = "package.yaml"
@@ -234,7 +235,7 @@
     Object _ -> VerbatimObject <$> fromValue v
     _ -> typeMismatch (formatOrList ["String", "Object"]) v
 
-data CommonOptions cSources jsSources a = CommonOptions {
+data CommonOptions cSources cxxSources jsSources a = CommonOptions {
   commonOptionsSourceDirs :: Maybe (List FilePath)
 , commonOptionsDependencies :: Maybe Dependencies
 , commonOptionsPkgConfigDependencies :: Maybe (List String)
@@ -246,6 +247,8 @@
 , commonOptionsCppOptions :: Maybe (List CppOption)
 , commonOptionsCcOptions :: Maybe (List CcOption)
 , commonOptionsCSources :: cSources
+, commonOptionsCxxOptions :: Maybe (List CxxOption)
+, commonOptionsCxxSources :: cxxSources
 , commonOptionsJsSources :: jsSources
 , commonOptionsExtraLibDirs :: Maybe (List FilePath)
 , commonOptionsExtraLibraries :: Maybe (List FilePath)
@@ -255,15 +258,15 @@
 , commonOptionsInstallIncludes :: Maybe (List FilePath)
 , commonOptionsLdOptions :: Maybe (List LdOption)
 , commonOptionsBuildable :: Maybe Bool
-, commonOptionsWhen :: Maybe (List (ConditionalSection cSources jsSources a))
+, commonOptionsWhen :: Maybe (List (ConditionalSection cSources cxxSources jsSources a))
 , commonOptionsBuildTools :: Maybe Dependencies
 , commonOptionsVerbatim :: Maybe (List Verbatim)
 } deriving (Functor, Generic)
 
-type ParseCommonOptions = CommonOptions ParseCSources ParseJsSources
+type ParseCommonOptions = CommonOptions ParseCSources ParseCxxSources ParseJsSources
 instance FromValue a => FromValue (ParseCommonOptions a)
 
-instance (Monoid cSources, Monoid jsSources) => Monoid (CommonOptions cSources jsSources a) where
+instance (Monoid cSources, Monoid cxxSources, Monoid jsSources) => Monoid (CommonOptions cSources cxxSources jsSources a) where
   mempty = CommonOptions {
     commonOptionsSourceDirs = Nothing
   , commonOptionsDependencies = Nothing
@@ -276,6 +279,8 @@
   , commonOptionsCppOptions = Nothing
   , commonOptionsCcOptions = Nothing
   , commonOptionsCSources = mempty
+  , commonOptionsCxxOptions = Nothing
+  , commonOptionsCxxSources = mempty
   , commonOptionsJsSources = mempty
   , commonOptionsExtraLibDirs = Nothing
   , commonOptionsExtraLibraries = Nothing
@@ -301,6 +306,8 @@
   , commonOptionsCppOptions = commonOptionsCppOptions a <> commonOptionsCppOptions b
   , commonOptionsCcOptions = commonOptionsCcOptions a <> commonOptionsCcOptions b
   , commonOptionsCSources = commonOptionsCSources a <> commonOptionsCSources b
+  , commonOptionsCxxOptions = commonOptionsCxxOptions a <> commonOptionsCxxOptions b
+  , commonOptionsCxxSources = commonOptionsCxxSources a <> commonOptionsCxxSources b
   , commonOptionsJsSources = commonOptionsJsSources a <> commonOptionsJsSources b
   , commonOptionsExtraLibDirs = commonOptionsExtraLibDirs a <> commonOptionsExtraLibDirs b
   , commonOptionsExtraLibraries = commonOptionsExtraLibraries a <> commonOptionsExtraLibraries b
@@ -316,35 +323,40 @@
   }
 
 type ParseCSources = Maybe (List FilePath)
+type ParseCxxSources = Maybe (List FilePath)
 type ParseJsSources = Maybe (List FilePath)
 
 type CSources = [FilePath]
+type CxxSources = [FilePath]
 type JsSources = [FilePath]
 
-type WithCommonOptions cSources jsSources a = Product (CommonOptions cSources jsSources a) a
+type WithCommonOptions cSources cxxSources jsSources a = Product (CommonOptions cSources cxxSources jsSources a) a
 
-data Traverse m cSources cSources_ jsSources jsSources_ = Traverse {
+data Traverse m cSources cSources_ cxxSources cxxSources_ jsSources jsSources_ = Traverse {
   traverseCSources :: cSources -> m cSources_
+, traverseCxxSources :: cxxSources -> m cxxSources_
 , traverseJsSources :: jsSources -> m jsSources_
 }
 
-type Traversal t = forall m cSources cSources_ jsSources jsSources_. Monad m
-  => Traverse m cSources cSources_ jsSources jsSources_
-  -> t cSources jsSources
-  -> m (t cSources_ jsSources_)
+type Traversal t = forall m cSources cSources_ cxxSources cxxSources_ jsSources jsSources_. Monad m
+  => Traverse m cSources cSources_ cxxSources cxxSources_ jsSources jsSources_
+  -> t cSources cxxSources jsSources
+  -> m (t cSources_ cxxSources_ jsSources_)
 
-type Traversal_ t = forall m cSources cSources_ jsSources jsSources_ a. Monad m
-  => Traverse m cSources cSources_ jsSources jsSources_
-  -> t cSources jsSources a
-  -> m (t cSources_ jsSources_ a)
+type Traversal_ t = forall m cSources cSources_ cxxSources cxxSources_ jsSources jsSources_ a. Monad m
+  => Traverse m cSources cSources_ cxxSources cxxSources_ jsSources jsSources_
+  -> t cSources cxxSources jsSources a
+  -> m (t cSources_ cxxSources_ jsSources_ a)
 
 traverseCommonOptions :: Traversal_ CommonOptions
 traverseCommonOptions t@Traverse{..} c@CommonOptions{..} = do
   cSources <- traverseCSources commonOptionsCSources
+  cxxSources <- traverseCxxSources commonOptionsCxxSources
   jsSources <- traverseJsSources commonOptionsJsSources
   xs <- traverse (traverse (traverseConditionalSection t)) commonOptionsWhen
   return c {
       commonOptionsCSources = cSources
+    , commonOptionsCxxSources = cxxSources
     , commonOptionsJsSources = jsSources
     , commonOptionsWhen = xs
     }
@@ -363,16 +375,16 @@
 traverseWithCommonOptions :: Traversal_ WithCommonOptions
 traverseWithCommonOptions t = bitraverse (traverseCommonOptions t) return
 
-data ConditionalSection cSources jsSources a =
-    ThenElseConditional (Product (ThenElse cSources jsSources a) Condition)
-  | FlatConditional (Product (WithCommonOptions cSources jsSources a) Condition)
+data ConditionalSection cSources cxxSources jsSources a =
+    ThenElseConditional (Product (ThenElse cSources cxxSources jsSources a) Condition)
+  | FlatConditional (Product (WithCommonOptions cSources cxxSources jsSources a) Condition)
 
-instance Functor (ConditionalSection cSources jsSources) where
+instance Functor (ConditionalSection cSources cxxSources jsSources) where
   fmap f = \ case
     ThenElseConditional c -> ThenElseConditional (first (fmap f) c)
     FlatConditional c -> FlatConditional (first (bimap (fmap f) f) c)
 
-type ParseConditionalSection = ConditionalSection ParseCSources ParseJsSources
+type ParseConditionalSection = ConditionalSection ParseCSources ParseCxxSources ParseJsSources
 
 instance FromValue a => FromValue (ParseConditionalSection a) where
   fromValue v
@@ -397,17 +409,17 @@
     Bool False -> return (Cond "false")
     _ -> typeMismatch "Boolean or String" v
 
-data ThenElse cSources jsSources a = ThenElse {
-  thenElseThen :: WithCommonOptions cSources jsSources a
-, thenElseElse :: WithCommonOptions cSources jsSources a
+data ThenElse cSources cxxSources jsSources a = ThenElse {
+  thenElseThen :: WithCommonOptions cSources cxxSources jsSources a
+, thenElseElse :: WithCommonOptions cSources cxxSources jsSources a
 } deriving Generic
 
-instance Functor (ThenElse cSources jsSources) where
+instance Functor (ThenElse cSources cxxSources jsSources) where
   fmap f c@ThenElse{..} = c{thenElseThen = map_ thenElseThen, thenElseElse = map_ thenElseElse}
     where
       map_ = bimap (fmap f) f
 
-type ParseThenElse = ThenElse ParseCSources ParseJsSources
+type ParseThenElse = ThenElse ParseCSources ParseCxxSources ParseJsSources
 
 instance FromValue a => FromValue (ParseThenElse a)
 
@@ -444,17 +456,15 @@
   y : x : [] -> x ++ " or " ++ y
   x : ys@(_:_:_) -> intercalate ", " . reverse $ ("or " ++ x) : ys
 
-type SectionConfigWithDefaluts cSources jsSources a = Product DefaultsConfig (WithCommonOptions cSources jsSources a)
+type SectionConfigWithDefaluts cSources cxxSources jsSources a = Product DefaultsConfig (WithCommonOptions cSources cxxSources jsSources a)
 
-type PackageConfigWithDefaults cSources jsSources = PackageConfig_
-  (SectionConfigWithDefaluts cSources jsSources LibrarySection)
-  (SectionConfigWithDefaluts cSources jsSources ExecutableSection)
-  cSources jsSources
+type PackageConfigWithDefaults cSources cxxSources jsSources = PackageConfig_
+  (SectionConfigWithDefaluts cSources cxxSources jsSources LibrarySection)
+  (SectionConfigWithDefaluts cSources cxxSources jsSources ExecutableSection)
 
-type PackageConfig cSources jsSources = PackageConfig_
-  (WithCommonOptions cSources jsSources LibrarySection)
-  (WithCommonOptions cSources jsSources ExecutableSection)
-  cSources jsSources
+type PackageConfig cSources cxxSources jsSources = PackageConfig_
+  (WithCommonOptions cSources cxxSources jsSources LibrarySection)
+  (WithCommonOptions cSources cxxSources jsSources ExecutableSection)
 
 data PackageVersion = PackageVersion {unPackageVersion :: String}
 
@@ -464,7 +474,7 @@
     String s -> return (T.unpack s)
     _ -> typeMismatch "Number or String" v
 
-data PackageConfig_ library executable cSources jsSources = PackageConfig {
+data PackageConfig_ library executable = PackageConfig {
   packageConfigName :: Maybe String
 , packageConfigVersion :: Maybe PackageVersion
 , packageConfigSynopsis :: Maybe String
@@ -484,6 +494,7 @@
 , packageConfigExtraSourceFiles :: Maybe (List FilePath)
 , packageConfigExtraDocFiles :: Maybe (List FilePath)
 , packageConfigDataFiles :: Maybe (List FilePath)
+, packageConfigDataDir :: Maybe FilePath
 , packageConfigGithub :: Maybe Text
 , packageConfigGit :: Maybe String
 , packageConfigCustomSetup :: Maybe CustomSetupSection
@@ -518,7 +529,7 @@
   where
     traverseNamedConfigs = traverse . traverse . traverseWithCommonOptions
 
-type ParsePackageConfig = PackageConfigWithDefaults ParseCSources ParseJsSources
+type ParsePackageConfig = PackageConfigWithDefaults ParseCSources ParseCxxSources ParseJsSources
 
 instance FromValue ParsePackageConfig
 
@@ -588,6 +599,7 @@
 , packageExtraSourceFiles :: [FilePath]
 , packageExtraDocFiles :: [FilePath]
 , packageDataFiles :: [FilePath]
+, packageDataDir :: Maybe FilePath
 , packageSourceRepository :: Maybe SourceRepository
 , packageCustomSetup :: Maybe CustomSetup
 , packageLibrary :: Maybe (Section Library)
@@ -630,6 +642,8 @@
 , sectionCppOptions :: [CppOption]
 , sectionCcOptions :: [CcOption]
 , sectionCSources :: [FilePath]
+, sectionCxxOptions :: [CxxOption]
+, sectionCxxSources :: [FilePath]
 , sectionJsSources :: [FilePath]
 , sectionExtraLibDirs :: [FilePath]
 , sectionExtraLibraries :: [FilePath]
@@ -671,18 +685,18 @@
 , sourceRepositorySubdir :: Maybe String
 } deriving (Eq, Show)
 
-type Config cSources jsSources =
-  Product (CommonOptions cSources jsSources Empty) (PackageConfig cSources jsSources)
+type Config cSources cxxSources jsSources =
+  Product (CommonOptions cSources cxxSources jsSources Empty) (PackageConfig cSources cxxSources jsSources)
 
 traverseConfig :: Traversal Config
 traverseConfig t = bitraverse (traverseCommonOptions t) (traversePackageConfig t)
 
 type ConfigWithDefaults = Product
   (CommonOptionsWithDefaults Empty)
-  (PackageConfigWithDefaults ParseCSources ParseJsSources)
+  (PackageConfigWithDefaults ParseCSources ParseCxxSources ParseJsSources)
 
-type CommonOptionsWithDefaults a = Product DefaultsConfig (CommonOptions ParseCSources ParseJsSources a)
-type WithCommonOptionsWithDefaults a = Product DefaultsConfig (WithCommonOptions ParseCSources ParseJsSources a)
+type CommonOptionsWithDefaults a = Product DefaultsConfig (CommonOptions ParseCSources ParseCxxSources ParseJsSources a)
+type WithCommonOptionsWithDefaults a = Product DefaultsConfig (WithCommonOptions ParseCSources ParseCxxSources ParseJsSources a)
 
 toPackage :: FilePath -> FilePath -> ConfigWithDefaults -> Warnings (Errors IO) Package
 toPackage userDataDir dir =
@@ -694,22 +708,22 @@
   :: FilePath
   -> FilePath
   -> ConfigWithDefaults
-  -> Warnings (Errors IO) (Config ParseCSources ParseJsSources)
+  -> Warnings (Errors IO) (Config ParseCSources ParseCxxSources ParseJsSources)
 expandDefaultsInConfig userDataDir dir = bitraverse (expandGlobalDefaults userDataDir dir) (expandSectionDefaults userDataDir dir)
 
 expandGlobalDefaults
   :: FilePath
   -> FilePath
   -> CommonOptionsWithDefaults Empty
-  -> Warnings (Errors IO) (CommonOptions ParseCSources ParseJsSources Empty)
+  -> Warnings (Errors IO) (CommonOptions ParseCSources ParseCxxSources ParseJsSources Empty)
 expandGlobalDefaults userDataDir dir = do
   fmap (`Product` Empty) >>> expandDefaults userDataDir dir >=> \ (Product c Empty) -> return c
 
 expandSectionDefaults
   :: FilePath
   -> FilePath
-  -> PackageConfigWithDefaults ParseCSources ParseJsSources
-  -> Warnings (Errors IO) (PackageConfig ParseCSources ParseJsSources)
+  -> PackageConfigWithDefaults ParseCSources ParseCxxSources ParseJsSources
+  -> Warnings (Errors IO) (PackageConfig ParseCSources ParseCxxSources ParseJsSources)
 expandSectionDefaults userDataDir dir p@PackageConfig{..} = do
   library <- traverse (expandDefaults userDataDir dir) packageConfigLibrary
   internalLibraries <- traverse (traverse (expandDefaults userDataDir dir)) packageConfigInternalLibraries
@@ -731,14 +745,14 @@
   => FilePath
   -> FilePath
   -> WithCommonOptionsWithDefaults a
-  -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseJsSources a)
+  -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseCxxSources ParseJsSources a)
 expandDefaults userDataDir = expand []
   where
     expand :: (FromValue a, Monoid a) =>
          [FilePath]
       -> FilePath
       -> WithCommonOptionsWithDefaults a
-      -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseJsSources a)
+      -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseCxxSources ParseJsSources a)
     expand seen dir (Product DefaultsConfig{..} c) = do
       d <- mconcat <$> mapM (get seen dir) (fromMaybeList defaultsConfigDefaults)
       return (d <> c)
@@ -747,7 +761,7 @@
          [FilePath]
       -> FilePath
       -> Defaults
-      -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseJsSources a)
+      -> Warnings (Errors IO) (WithCommonOptions ParseCSources ParseCxxSources ParseJsSources a)
     get seen dir defaults = do
       file <- lift $ ExceptT (ensure userDataDir dir defaults)
       seen_ <- lift (checkCycle seen file)
@@ -771,9 +785,9 @@
       return $ Just (Map.fromList [(name, executable)])
     Nothing -> return executables
 
-type GlobalOptions = CommonOptions CSources JsSources Empty
+type GlobalOptions = CommonOptions CSources CxxSources JsSources Empty
 
-toPackage_ :: MonadIO m => FilePath -> Product GlobalOptions (PackageConfig CSources JsSources) -> Warnings m Package
+toPackage_ :: MonadIO m => FilePath -> Product GlobalOptions (PackageConfig CSources CxxSources JsSources) -> Warnings m Package
 toPackage_ dir (Product g PackageConfig{..}) = do
   let
     globalVerbatim = commonOptionsVerbatim g
@@ -801,8 +815,11 @@
 
   extraSourceFiles <- expandGlobs "extra-source-files" dir (fromMaybeList packageConfigExtraSourceFiles)
   extraDocFiles <- expandGlobs "extra-doc-files" dir (fromMaybeList packageConfigExtraDocFiles)
-  dataFiles <- expandGlobs "data-files" dir (fromMaybeList packageConfigDataFiles)
 
+  let dataBaseDir = maybe dir (dir </>) packageConfigDataDir
+
+  dataFiles <- expandGlobs "data-files" dataBaseDir (fromMaybeList packageConfigDataFiles)
+
   let defaultBuildType :: BuildType
       defaultBuildType = maybe Simple (const Custom) mCustomSetup
 
@@ -831,6 +848,7 @@
       , packageExtraSourceFiles = extraSourceFiles
       , packageExtraDocFiles = extraDocFiles
       , packageDataFiles = dataFiles
+      , packageDataDir = packageConfigDataDir
       , packageSourceRepository = sourceRepository
       , packageCustomSetup = mCustomSetup
       , packageLibrary = mLibrary
@@ -893,9 +911,10 @@
 expandForeignSources
   :: MonadIO m
   => FilePath
-  -> Traverse (Warnings m) ParseCSources CSources ParseJsSources JsSources
+  -> Traverse (Warnings m) ParseCSources CSources ParseCxxSources CxxSources ParseJsSources JsSources
 expandForeignSources dir = Traverse {
     traverseCSources = expand "c-sources"
+  , traverseCxxSources = expand "cxx-sources"
   , traverseJsSources = expand "js-sources"
   }
   where
@@ -955,7 +974,7 @@
         r = fromConfig pathsModule inferableModules conf
       return (outerModules ++ getInferredModules r, r)
 
-toLibrary :: FilePath -> String -> GlobalOptions -> WithCommonOptions CSources JsSources LibrarySection -> IO (Section Library)
+toLibrary :: FilePath -> String -> GlobalOptions -> WithCommonOptions CSources CxxSources JsSources LibrarySection -> IO (Section Library)
 toLibrary dir name globalOptions =
     inferModules dir name getMentionedLibraryModules getLibraryModules fromLibrarySectionTopLevel fromLibrarySectionInConditional
   . toSection (mempty <$ globalOptions)
@@ -997,17 +1016,17 @@
   , librarySignatures = fromMaybeList librarySectionSignatures
   }
 
-toInternalLibraries :: FilePath -> String -> GlobalOptions -> Maybe (Map String (WithCommonOptions CSources JsSources LibrarySection)) -> IO (Map String (Section Library))
+toInternalLibraries :: FilePath -> String -> GlobalOptions -> Maybe (Map String (WithCommonOptions CSources CxxSources JsSources LibrarySection)) -> IO (Map String (Section Library))
 toInternalLibraries dir packageName_ globalOptions = traverse (toLibrary dir packageName_ globalOptions) . fromMaybe mempty
 
-toExecutables :: FilePath -> String -> GlobalOptions -> Maybe (Map String (WithCommonOptions CSources JsSources ExecutableSection)) -> IO (Map String (Section Executable))
+toExecutables :: FilePath -> String -> GlobalOptions -> Maybe (Map String (WithCommonOptions CSources CxxSources JsSources ExecutableSection)) -> IO (Map String (Section Executable))
 toExecutables dir packageName_ globalOptions = traverse (toExecutable dir packageName_ globalOptions) . fromMaybe mempty
 
 getMentionedExecutableModules :: ExecutableSection -> [String]
 getMentionedExecutableModules (ExecutableSection main otherModules generatedModules)=
   maybe id (:) (main >>= toModule . splitDirectories) $ fromMaybeList (otherModules <> generatedModules)
 
-toExecutable :: FilePath -> String -> GlobalOptions -> WithCommonOptions CSources JsSources ExecutableSection -> IO (Section Executable)
+toExecutable :: FilePath -> String -> GlobalOptions -> WithCommonOptions CSources CxxSources JsSources ExecutableSection -> IO (Section Executable)
 toExecutable dir packageName_ globalOptions =
     inferModules dir packageName_ getMentionedExecutableModules executableOtherModules fromExecutableSection (fromExecutableSection [])
   . expandMain
@@ -1039,10 +1058,10 @@
       , sectionConditionals = map (fmap flatten) sectionConditionals
       }
 
-toSection :: CommonOptions CSources JsSources a -> WithCommonOptions CSources JsSources a -> Section a
+toSection :: CommonOptions CSources CxxSources JsSources a -> WithCommonOptions CSources CxxSources JsSources a -> Section a
 toSection globalOptions (Product options a) = toSection_ (Product (globalOptions <> options) a)
 
-toSection_ :: WithCommonOptions CSources JsSources a -> Section a
+toSection_ :: WithCommonOptions CSources CxxSources JsSources a -> Section a
 toSection_ (Product CommonOptions{..} a) = Section {
         sectionData = a
       , sectionSourceDirs = fromMaybeList commonOptionsSourceDirs
@@ -1054,6 +1073,8 @@
       , sectionCppOptions = fromMaybeList commonOptionsCppOptions
       , sectionCcOptions = fromMaybeList commonOptionsCcOptions
       , sectionCSources = commonOptionsCSources
+      , sectionCxxOptions = fromMaybeList commonOptionsCxxOptions
+      , sectionCxxSources = commonOptionsCxxSources
       , sectionJsSources = commonOptionsJsSources
       , sectionExtraLibDirs = fromMaybeList commonOptionsExtraLibDirs
       , sectionExtraLibraries = fromMaybeList commonOptionsExtraLibraries
@@ -1072,7 +1093,7 @@
   where
     conditionals = map toConditional (fromMaybeList commonOptionsWhen)
 
-    toConditional :: ConditionalSection CSources JsSources a -> Conditional (Section a)
+    toConditional :: ConditionalSection CSources CxxSources JsSources a -> Conditional (Section a)
     toConditional x = case x of
       ThenElseConditional (Product (ThenElse then_ else_) c) -> conditional c (toSection_ then_) (Just $ toSection_ else_)
       FlatConditional (Product sect c) -> conditional c (toSection_ sect) Nothing
diff --git a/src/Hpack/Render.hs b/src/Hpack/Render.hs
--- a/src/Hpack/Render.hs
+++ b/src/Hpack/Render.hs
@@ -59,19 +59,18 @@
 renderPackageWith settings headerFieldsAlignment existingFieldOrder sectionsFieldOrder Package{..} = intercalate "\n" (unlines header : chunks)
   where
     chunks :: [String]
-    chunks = map unlines . filter (not . null) . map (render settings 0) $ sortSectionFields sectionsFieldOrder stanzas
+    chunks = map unlines . filter (not . null) . map (render settings 0) $ sortStanzaFields sectionsFieldOrder stanzas
 
     header :: [String]
-    header = concatMap (render settings {renderSettingsFieldAlignment = headerFieldsAlignment} 0) (filterVerbatim packageVerbatim $ headerFields)
-
-    extraSourceFiles :: Element
-    extraSourceFiles = Field "extra-source-files" (LineSeparatedList packageExtraSourceFiles)
-
-    extraDocFiles :: Element
-    extraDocFiles = Field "extra-doc-files" (LineSeparatedList packageExtraDocFiles)
+    header = concatMap (render settings {renderSettingsFieldAlignment = headerFieldsAlignment} 0) packageFields
 
-    dataFiles :: Element
-    dataFiles = Field "data-files" (LineSeparatedList packageDataFiles)
+    packageFields :: [Element]
+    packageFields = addVerbatim packageVerbatim . sortFieldsBy existingFieldOrder $
+      headerFields ++ [
+        Field "extra-source-files" (LineSeparatedList packageExtraSourceFiles)
+      , Field "extra-doc-files" (LineSeparatedList packageExtraDocFiles)
+      , Field "data-files" (LineSeparatedList packageDataFiles)
+      ] ++ maybe [] (return . Field "data-dir" . Literal) packageDataDir
 
     sourceRepository :: [Element]
     sourceRepository = maybe [] (return . renderSourceRepository) packageSourceRepository
@@ -83,13 +82,9 @@
     library = maybe [] (return . renderLibrary) packageLibrary
 
     stanzas :: [Element]
-    stanzas = addVerbatim packageVerbatim $
-      extraSourceFiles
-      : extraDocFiles
-      : dataFiles
-      : sourceRepository
-      ++ concat [
-        customSetup
+    stanzas = concat [
+        sourceRepository
+      , customSetup
       , map renderFlag packageFlags
       , library
       , renderInternalLibraries packageInternalLibraries
@@ -99,7 +94,7 @@
       ]
 
     headerFields :: [Element]
-    headerFields = sortFieldsBy existingFieldOrder . mapMaybe (\(name, value) -> Field name . Literal <$> value) $ [
+    headerFields = mapMaybe (\(name, value) -> Field name . Literal <$> value) $ [
         ("name", Just packageName)
       , ("version", Just packageVersion)
       , ("synopsis", packageSynopsis)
@@ -148,6 +143,7 @@
           makeVersion [1,22] <$ guard hasReexportedModules
         , makeVersion [2,0]  <$ guard hasSignatures
         , makeVersion [2,0] <$ guard hasGeneratedModules
+        , makeVersion [2,2] <$ guard (hasCxxParams sect)
         ]
         where
           hasReexportedModules = any (not . null . libraryReexportedModules) sect
@@ -155,19 +151,37 @@
           hasGeneratedModules = any (not . null . libraryGeneratedModules) sect
 
       internalLibsCabalVersion :: Map String (Section Library) -> Maybe Version
-      internalLibsCabalVersion internalLibraries = makeVersion [2,0] <$ guard (not (Map.null internalLibraries))
+      internalLibsCabalVersion internalLibraries
+        | Map.null internalLibraries = Nothing
+        | otherwise = foldr max (Just $ makeVersion [2,0]) versions
+        where
+          versions = libraryCabalVersion <$> Map.elems internalLibraries
 
       executablesCabalVersion :: Map String (Section Executable) -> Maybe Version
       executablesCabalVersion = foldr max Nothing . map executableCabalVersion . Map.elems
 
       executableCabalVersion :: Section Executable -> Maybe Version
-      executableCabalVersion sect = makeVersion [2,0] <$ guard (executableHasGeneratedModules sect)
+      executableCabalVersion sect = maximum [
+          makeVersion [2,0] <$ guard (executableHasGeneratedModules sect)
+        , makeVersion [2,2] <$ guard (hasCxxParams sect)
+        ]
 
       executableHasGeneratedModules :: Section Executable -> Bool
       executableHasGeneratedModules = any (not . null . executableGeneratedModules)
 
-sortSectionFields :: [(String, [String])] -> [Element] -> [Element]
-sortSectionFields sectionsFieldOrder = go
+      hasCxxParams :: Section a -> Bool
+      hasCxxParams sect = or [
+          check sect
+        , any (any check) (sectionConditionals sect)
+        ]
+        where
+          check s = or [
+              (not . null . sectionCxxOptions) s
+            , (not . null . sectionCxxSources) s
+            ]
+
+sortStanzaFields :: [(String, [String])] -> [Element] -> [Element]
+sortStanzaFields sectionsFieldOrder = go
   where
     go sections = case sections of
       [] -> []
@@ -278,9 +292,11 @@
   , renderGhcjsOptions sectionGhcjsOptions
   , renderCppOptions sectionCppOptions
   , renderCcOptions sectionCcOptions
+  , renderCxxOptions sectionCxxOptions
   , renderDirectories "include-dirs" sectionIncludeDirs
   , Field "install-includes" (LineSeparatedList sectionInstallIncludes)
   , Field "c-sources" (LineSeparatedList sectionCSources)
+  , Field "cxx-sources" (LineSeparatedList sectionCxxSources)
   , Field "js-sources" (LineSeparatedList sectionJsSources)
   , renderDirectories "extra-lib-dirs" sectionExtraLibDirs
   , Field "extra-libraries" (LineSeparatedList sectionExtraLibraries)
@@ -386,6 +402,9 @@
 
 renderCcOptions :: [CcOption] -> Element
 renderCcOptions = Field "cc-options" . WordList
+
+renderCxxOptions :: [CxxOption] -> Element
+renderCxxOptions = Field "cxx-options" . WordList
 
 renderLdOptions :: [LdOption] -> Element
 renderLdOptions = Field "ld-options" . WordList
diff --git a/src/Hpack/Util.hs b/src/Hpack/Util.hs
--- a/src/Hpack/Util.hs
+++ b/src/Hpack/Util.hs
@@ -4,6 +4,7 @@
 , GhcjsOption
 , CppOption
 , CcOption
+, CxxOption
 , LdOption
 , parseMain
 , toModule
@@ -43,6 +44,7 @@
 type GhcjsOption = String
 type CppOption = String
 type CcOption = String
+type CxxOption = String
 type LdOption = String
 
 parseMain :: String -> (FilePath, [GhcOption])
diff --git a/test/EndToEndSpec.hs b/test/EndToEndSpec.hs
--- a/test/EndToEndSpec.hs
+++ b/test/EndToEndSpec.hs
@@ -37,6 +37,34 @@
           Paths_foo
       |]
 
+    describe "data-files" $ do
+      it "accepts data-files" $ do
+        touch "data/foo/index.html"
+        touch "data/bar/index.html"
+        [i|
+        data-files:
+          - data/**/*.html
+        |] `shouldRenderTo` package [i|
+        data-files:
+            data/bar/index.html
+            data/foo/index.html
+        |]
+
+    describe "data-dir" $ do
+      it "accepts data-dir" $ do
+        touch "data/foo.html"
+        touch "data/bar.html"
+        [i|
+        data-dir: data
+        data-files:
+          - "*.html"
+        |] `shouldRenderTo` package [i|
+        data-files:
+            bar.html
+            foo.html
+        data-dir: data
+        |]
+
     describe "github" $ do
       it "accepts owner/repo" $ do
         [i|
@@ -440,6 +468,29 @@
             foo.js
             jsbits/bar.js
         |]
+
+    describe "cxx-options" $ do
+      it "accepts cxx-options" $ do
+        [i|
+        executable:
+          cxx-options: -Wall
+        |] `shouldRenderTo` (executable_ "foo" [i|
+        cxx-options: -Wall
+        |]) {packageCabalVersion = ">= 2.2"}
+
+    describe "cxx-sources" $ before_ (touch "foo.cc" >> touch "cxxbits/bar.cc") $ do
+      it "accepts cxx-sources" $ do
+        [i|
+        executable:
+          cxx-sources:
+            - foo.cc
+            - cxxbits/*.cc
+        |] `shouldRenderTo` (executable_ "foo" [i|
+        cxx-sources:
+            cxxbits/bar.cc
+            foo.cc
+        |]) {packageCabalVersion = ">= 2.2"}
+
     describe "extra-lib-dirs" $ do
       it "accepts extra-lib-dirs" $ do
         [i|
@@ -1160,11 +1211,11 @@
             foo: 23
           library: {}
           |] `shouldRenderTo` package [i|
+          foo: 23
           library
             other-modules:
                 Paths_foo
             default-language: Haskell2010
-          foo: 23
           |]
 
       context "within a section" $ do
diff --git a/test/Hpack/ConfigSpec.hs b/test/Hpack/ConfigSpec.hs
--- a/test/Hpack/ConfigSpec.hs
+++ b/test/Hpack/ConfigSpec.hs
@@ -277,17 +277,6 @@
         )
         (packageExtraSourceFiles >>> (`shouldBe` ["CHANGES.markdown", "README.markdown"]))
 
-    it "accepts data-files" $ do
-      withPackageConfig [i|
-        data-files:
-          - data/**/*.html
-        |]
-        (do
-        touch "data/foo/index.html"
-        touch "data/bar/index.html"
-        )
-        (packageDataFiles >>> (`shouldMatchList` ["data/foo/index.html", "data/bar/index.html"]))
-
     it "accepts arbitrary git URLs as source repository" $ do
       withPackageConfig_ [i|
         git: https://gitlab.com/gitlab-org/gitlab-ce.git
diff --git a/test/Hpack/RenderSpec.hs b/test/Hpack/RenderSpec.hs
--- a/test/Hpack/RenderSpec.hs
+++ b/test/Hpack/RenderSpec.hs
@@ -114,7 +114,6 @@
         , "version: 0.0.0"
         , "build-type: Simple"
         , "cabal-version: >= 1.10"
-        , ""
         , "extra-source-files:"
         , "    foo"
         , "    bar"
