Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix #842 #1077

Closed
wants to merge 2 commits into from

1 participant

@ezyang
Collaborator

Do a no-link build before building C sources.

Signed-off-by: Edward Z. Yang ezyang@mit.edu

ezyang added some commits
@ezyang ezyang Do a no-link build before building C sources, so stub.h headers can b…
…e created.

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
2ec3e8e
@ezyang ezyang Support for C files as main.
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
7a8afe1
@ezyang ezyang closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 22, 2012
  1. @ezyang

    Do a no-link build before building C sources, so stub.h headers can b…

    ezyang authored
    …e created.
    
    Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
  2. @ezyang

    Support for C files as main.

    ezyang authored
    Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
This page is out of date. Refresh to see the latest.
View
1  Cabal/Cabal.cabal
@@ -72,6 +72,7 @@ Library
Distribution.Simple.BuildPaths,
Distribution.Simple.Bench,
Distribution.Simple.Command,
+ Distribution.Simple.CCompiler,
Distribution.Simple.Compiler,
Distribution.Simple.Configure,
Distribution.Simple.GHC,
View
23 Cabal/Distribution/PackageDescription/Check.hs
@@ -80,6 +80,8 @@ import Distribution.System
( OS(..), Arch(..), buildPlatform )
import Distribution.License
( License(..), knownLicenses )
+import Distribution.Simple.CCompiler
+ ( filenameCDialect )
import Distribution.Simple.Utils
( cabalVersion, intercalate, parseFileGlob, FileGlob(..), lowercase )
@@ -253,10 +255,10 @@ checkExecutable exe =
"No 'Main-Is' field found for executable " ++ exeName exe
, check (not (null (modulePath exe))
- && takeExtension (modulePath exe) `notElem` [".hs", ".lhs"]) $
+ && (not $ pathIsKnownProgrammingLanguage $ modulePath exe)) $
PackageBuildImpossible $
- "The 'Main-Is' field must specify a '.hs' or '.lhs' file "
- ++ "(even if it is generated by a preprocessor)."
+ "The 'main-is' field must specify a file with an extension of a"
+ ++ "known programming language."
, check (not (null moduleDuplicates)) $
PackageBuildWarning $
@@ -291,8 +293,8 @@ checkTestSuite pkg test =
, check mainIsWrongExt $
PackageBuildImpossible $
- "The 'main-is' field must specify a '.hs' or '.lhs' file "
- ++ "(even if it is generated by a preprocessor)."
+ "The 'main-is' field must specify a file with an extension of a"
+ ++ "known programming language."
-- Test suites might be built as (internal) libraries named after
-- the test suite and thus their names must not clash with the
@@ -306,7 +308,7 @@ checkTestSuite pkg test =
moduleDuplicates = dups $ testModules test
mainIsWrongExt = case testInterface test of
- TestSuiteExeV10 _ f -> takeExtension f `notElem` [".hs", ".lhs"]
+ TestSuiteExeV10 _ f -> not $ pathIsKnownProgrammingLanguage f
_ -> False
libNameClash = testName test `elem` [ libName
@@ -1493,3 +1495,12 @@ commaSep = intercalate ", "
dups :: Ord a => [a] -> [a]
dups xs = [ x | (x:_:_) <- group (sort xs) ]
+
+pathIsKnownProgrammingLanguage :: FilePath -> Bool
+pathIsKnownProgrammingLanguage path =
+ let extension = takeExtension path
+ isHaskell = elem extension [".hs", ".lhs"]
+ isC = case filenameCDialect extension of
+ Nothing -> False
+ Just _ -> True
+ in isHaskell || isC
View
121 Cabal/Distribution/Simple/CCompiler.hs
@@ -0,0 +1,121 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : Distribution.Simple.CCompiler
+-- Copyright : 2011, Dan Knapp
+--
+-- Maintainer : cabal-devel@haskell.org
+-- Portability : portable
+--
+-- This simple package provides types and functions for interacting with
+-- C compilers. Currently it's just a type enumerating extant C-like
+-- languages, which we call dialects.
+
+{-
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ * Neither the name of Isaac Jones nor the names of other
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}
+
+module Distribution.Simple.CCompiler
+ (CDialect(..),
+ cSourceExtensions,
+ cDialectFilenameExtension,
+ filenameCDialect)
+ where
+
+import Data.Monoid
+ ( Monoid(..) )
+import System.FilePath
+ ( takeExtension )
+
+
+-- | Represents a dialect of C. The Monoid instance expresses backward
+-- compatibility, in the sense that 'mappend a b' is the least inclusive
+-- dialect which both 'a' and 'b' can be correctly interpreted as.
+data CDialect = C
+ | ObjectiveC
+ | CPlusPlus
+ | ObjectiveCPlusPlus
+ deriving (Show)
+
+
+instance Monoid CDialect where
+ mempty = C
+ mappend C anything = anything
+ mappend ObjectiveC CPlusPlus = ObjectiveCPlusPlus
+ mappend CPlusPlus ObjectiveC = ObjectiveCPlusPlus
+ mappend _ ObjectiveCPlusPlus = ObjectiveCPlusPlus
+ mappend ObjectiveC _ = ObjectiveC
+ mappend CPlusPlus _ = CPlusPlus
+ mappend ObjectiveCPlusPlus _ = ObjectiveCPlusPlus
+
+
+-- | A list of all file extensions which are recognized as possibly containing
+-- some dialect of C code. Note that this list is only for source files,
+-- not for header files.
+cSourceExtensions :: [String]
+cSourceExtensions = ["c", "i", "ii", "m", "mi", "mm", "M", "mii", "cc", "cp",
+ "cxx", "cpp", "CPP", "c++", "C"]
+
+
+-- | Takes a dialect of C and whether code is intended to be passed through
+-- the preprocessor, and returns a filename extension for containing that
+-- code.
+cDialectFilenameExtension :: CDialect -> Bool -> String
+cDialectFilenameExtension C True = "c"
+cDialectFilenameExtension C False = "i"
+cDialectFilenameExtension ObjectiveC True = "m"
+cDialectFilenameExtension ObjectiveC False = "mi"
+cDialectFilenameExtension CPlusPlus True = "cpp"
+cDialectFilenameExtension CPlusPlus False = "ii"
+cDialectFilenameExtension ObjectiveCPlusPlus True = "mm"
+cDialectFilenameExtension ObjectiveCPlusPlus False = "mii"
+
+
+-- | Infers from a filename's extension the dialect of C which it contains,
+-- and whether it is intended to be passed through the preprocessor.
+filenameCDialect :: String -> Maybe (CDialect, Bool)
+filenameCDialect filename = do
+ extension <- case takeExtension filename of
+ "" -> Nothing
+ extension -> Just $ drop 1 extension
+ case extension of
+ "c" -> return (C, True)
+ "i" -> return (C, False)
+ "ii" -> return (CPlusPlus, False)
+ "m" -> return (ObjectiveC, True)
+ "mi" -> return (ObjectiveC, False)
+ "mm" -> return (ObjectiveCPlusPlus, True)
+ "M" -> return (ObjectiveCPlusPlus, True)
+ "mii" -> return (ObjectiveCPlusPlus, False)
+ "cc" -> return (CPlusPlus, True)
+ "cp" -> return (CPlusPlus, True)
+ "cxx" -> return (CPlusPlus, True)
+ "cpp" -> return (CPlusPlus, True)
+ "CPP" -> return (CPlusPlus, True)
+ "c++" -> return (CPlusPlus, True)
+ "C" -> return (CPlusPlus, True)
+ _ -> Nothing
View
28 Cabal/Distribution/Simple/GHC.hs
@@ -824,18 +824,6 @@ buildExe verbosity _pkg_descr lbi
-- FIX: what about exeName.hi-boot?
-- build executables
- unless (null (cSources exeBi)) $ do
- info verbosity "Building C Sources."
- sequence_
- [ do let opts = (componentCcGhcOptions verbosity lbi exeBi clbi
- exeDir filename) `mappend` mempty {
- ghcOptDynamic = toFlag (withDynExe lbi),
- ghcOptProfilingMode = toFlag (withProfExe lbi)
- }
- odir = fromFlag (ghcOptObjDir opts)
- createDirectoryIfMissingVerbose verbosity True odir
- runGhcProg opts
- | filename <- cSources exeBi]
srcMainFile <- findFile (exeDir : hsSourceDirs exeBi) modPath
@@ -865,6 +853,22 @@ buildExe verbosity _pkg_descr lbi
}
| otherwise = vanillaOpts
+ -- Gen up stub files
+ runGhcProg exeOpts { ghcOptNoLink = toFlag True }
+
+ unless (null (cSources exeBi)) $ do
+ info verbosity "Building C Sources."
+ sequence_
+ [ do let opts = (componentCcGhcOptions verbosity lbi exeBi clbi
+ exeDir filename) `mappend` mempty {
+ ghcOptDynamic = toFlag (withDynExe lbi),
+ ghcOptProfilingMode = toFlag (withProfExe lbi)
+ }
+ odir = fromFlag (ghcOptObjDir opts)
+ createDirectoryIfMissingVerbose verbosity True odir
+ runGhcProg opts
+ | filename <- cSources exeBi]
+
-- For building exe's for profiling that use TH we actually
-- have to build twice, once without profiling and the again
-- with profiling. This is because the code that TH needs to
View
6 Cabal/Distribution/Simple/PreProcess.hs
@@ -71,6 +71,8 @@ import Distribution.PackageDescription as PD
import qualified Distribution.InstalledPackageInfo as Installed
( InstalledPackageInfo_(..) )
import qualified Distribution.Simple.PackageIndex as PackageIndex
+import Distribution.Simple.CCompiler
+ ( cSourceExtensions )
import Distribution.Simple.Compiler
( CompilerFlavor(..), Compiler(..), compilerFlavor, compilerVersion )
import Distribution.Simple.LocalBuildInfo
@@ -219,9 +221,11 @@ preprocessComponent pd comp lbi isSrcDist verbosity handlers = case comp of
BenchmarkUnsupported tt -> die $ "No support for preprocessing benchmark "
++ "type " ++ display tt
where
- builtinSuffixes
+ builtinHaskellSuffixes
| NHC == compilerFlavor (compiler lbi) = ["hs", "lhs", "gc"]
| otherwise = ["hs", "lhs"]
+ builtinCSuffixes = cSourceExtensions
+ builtinSuffixes = builtinHaskellSuffixes ++ builtinCSuffixes
localHandlers bi = [(ext, h bi lbi) | (ext, h) <- handlers]
pre dirs dir lhndlrs fp =
preprocessFile dirs dir isSrcDist fp verbosity builtinSuffixes lhndlrs
Something went wrong with that request. Please try again.