Commit b12d4d57 authored by Alex Washburn's avatar Alex Washburn Committed by recursion-ninja

Updating changelog, Adding test case for issue #5309

parent 574a9788
......@@ -20,6 +20,11 @@
`Distribution.Simple.Glob` and `FileGlob` has been made abstract.
(#5284, #3178, et al.)
* Fixed `cxx-options` and `cxx-sources` buildinfo fields for
separate compilation of C++ source files to correctly build and link
non-library components (#5309).
* Reduced warnings generated by hsc2hs and c2hs when `cxx-options` field
is present in a component.
----
......
......@@ -666,10 +666,10 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
ghcOptObjSuffix = toFlag "p_o"
}
sharedCxxOpts = vanillaCxxOpts `mappend` mempty {
ghcOptFPic = toFlag True,
ghcOptDynLinkMode = toFlag GhcDynamicOnly,
ghcOptObjSuffix = toFlag "dyn_o"
}
ghcOptFPic = toFlag True,
ghcOptDynLinkMode = toFlag GhcDynamicOnly,
ghcOptObjSuffix = toFlag "dyn_o"
}
odir = fromFlag (ghcOptObjDir vanillaCxxOpts)
createDirectoryIfMissingVerbose verbosity True odir
let runGhcProgIfNeeded cxxOpts = do
......@@ -1083,12 +1083,27 @@ decodeMainIsArg arg
-- 'tail' drops the char satisfying 'pred'
where (r_suf, r_pre) = break pred' (reverse str)
-- | Return C sources, GHC input files and GHC input modules
-- | A collection of:
-- * C input files
-- * C++ input files
-- * GHC input files
-- * GHC input modules
--
-- Used to correctly build and link sources.
data BuildSources = BuildSources {
cSourcesFiles :: [FilePath],
cxxSourceFiles :: [FilePath],
inputSourceFiles :: [FilePath],
inputSourceModules :: [ModuleName]
}
-- | Locate and return the 'BuildSources' required to build and link.
gbuildSources :: Verbosity
-> Version -- ^ specVersion
-> FilePath
-> GBuildMode
-> IO ([FilePath], [FilePath], [FilePath], [ModuleName])
-> IO BuildSources
gbuildSources verbosity specVer tmpDir bm =
case bm of
GBuildExe exe -> exeSources exe
......@@ -1096,7 +1111,7 @@ gbuildSources verbosity specVer tmpDir bm =
GBuildFLib flib -> return $ flibSources flib
GReplFLib flib -> return $ flibSources flib
where
exeSources :: Executable -> IO ([FilePath], [FilePath], [FilePath], [ModuleName])
exeSources :: Executable -> IO BuildSources
exeSources exe@Executable{buildInfo = bnfo, modulePath = modPath} = do
main <- findFile (tmpDir : hsSourceDirs bnfo) modPath
let mainModName = fromMaybe ModuleName.main $ exeMainModuleName exe
......@@ -1121,15 +1136,34 @@ gbuildSources verbosity specVer tmpDir bm =
++ display mainModName
++ "' listed in 'other-modules' illegally!"
return (cSources bnfo, cxxSources bnfo, [main],
filter (/= mainModName) (exeModules exe))
return BuildSources {
cSourcesFiles = cSources bnfo,
cxxSourceFiles = cxxSources bnfo,
inputSourceFiles = [main],
inputSourceModules = filter (/= mainModName) $ exeModules exe
}
else return (cSources bnfo, cxxSources bnfo, [main], exeModules exe)
else return (main : cSources bnfo, main : cxxSources bnfo, [], exeModules exe)
else return BuildSources {
cSourcesFiles = cSources bnfo,
cxxSourceFiles = cxxSources bnfo,
inputSourceFiles = [main],
inputSourceModules = exeModules exe
}
else return BuildSources {
cSourcesFiles = main : cSources bnfo,
cxxSourceFiles = main : cxxSources bnfo,
inputSourceFiles = [],
inputSourceModules = exeModules exe
}
flibSources :: ForeignLib -> ([FilePath], [FilePath], [FilePath], [ModuleName])
flibSources :: ForeignLib -> BuildSources
flibSources flib@ForeignLib{foreignLibBuildInfo = bnfo} =
(cSources bnfo, cxxSources bnfo, [], foreignLibModules flib)
BuildSources {
cSourcesFiles = cSources bnfo,
cxxSourceFiles = cxxSources bnfo,
inputSourceFiles = [],
inputSourceModules = foreignLibModules flib
}
isHaskell :: FilePath -> Bool
isHaskell fp = elem (takeExtension fp) [".hs", ".lhs"]
......@@ -1168,10 +1202,13 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do
| otherwise = mempty
rpaths <- getRPaths lbi clbi
(cSrcs, cxxSrcs, inputFiles, inputModules) <- gbuildSources verbosity
(specVersion pkg_descr) tmpDir bm
buildSources <- gbuildSources verbosity (specVersion pkg_descr) tmpDir bm
let isGhcDynamic = isDynamic comp
let cSrcs = cSourcesFiles buildSources
cxxSrcs = cxxSourceFiles buildSources
inputFiles = inputSourceFiles buildSources
inputModules = inputSourceModules buildSources
isGhcDynamic = isDynamic comp
dynamicTooSupported = supportsDynamicToo comp
cObjs = map (`replaceExtension` objExtension) cSrcs
cxxObjs = map (`replaceExtension` objExtension) cxxSrcs
......
......@@ -160,6 +160,7 @@ emptyInstalledPackageInfo
depends = [],
abiDepends = [],
ccOptions = [],
cxxOptions = [],
ldOptions = [],
frameworkDirs = [],
frameworks = [],
......
......@@ -33,6 +33,8 @@ checkTests = testGroup "regressions"
, checkTest "pre-1.6-glob.cabal"
, checkTest "pre-3.0-globstar.cabal"
, checkTest "bad-glob-syntax.cabal"
, checkTest "cc-options-with-optimization.cabal"
, checkTest "cxx-options-with-optimization.cabal"
]
checkTest :: FilePath -> TestTree
......
......@@ -7,6 +7,7 @@ InstalledPackageInfo
ccOptions = [],
compatPackageKey = "Includes2-0.1.0.0-inplace-mylib+3gY9SyjX86dBypHcOaev1n",
copyright = "",
cxxOptions = [],
dataDir = "/home/travis/build/haskell/cabal/cabal-testsuite/PackageTests/Backpack/Includes2",
depends = [`UnitId "base-4.10.1.0"`,
`UnitId "Includes2-0.1.0.0-inplace-mysql"`],
......
......@@ -6,6 +6,7 @@ InstalledPackageInfo
ccOptions = [],
compatPackageKey = "internal-preprocessor-test-0.1.0.0",
copyright = "",
cxxOptions = [],
dataDir = "/home/ogre/Documents/other-haskell/cabal/cabal-testsuite/PackageTests/CustomPreProcess",
depends = [`UnitId "base-4.8.2.0-0d6d1084fbc041e1cded9228e80e264d"`],
description = "See https://github.com/haskell/cabal/issues/1541#issuecomment-30155513",
......
......@@ -6,6 +6,7 @@ InstalledPackageInfo
ccOptions = [],
compatPackageKey = "transformers-0.5.2.0",
copyright = "",
cxxOptions = [],
dataDir = "/opt/ghc/8.2.2/share/x86_64-linux-ghc-8.2.2/transformers-0.5.2.0",
depends = [`UnitId "base-4.10.1.0"`],
description = concat
......
......@@ -4,6 +4,7 @@ InstalledPackageInfo
author = "Andy Gill, Ross Paterson",
category = "Control",
ccOptions = [],
cxxOptions = [],
compatPackageKey = "transformers-0.5.2.0",
copyright = "",
dataDir = "/opt/ghc/8.2.2/share/x86_64-linux-ghc-8.2.2/transformers-0.5.2.0",
......
cabal-version: 2.2
category: test
description: test a build check involving C++-options field
license: BSD-3-Clause
maintainer: me@example.com
name: cxx-options-with-optimization
synopsis: test a build check
version: 1
library
build-depends: base >= 4.9 && <4.10
cc-options: -O2
default-language: Haskell2010
exposed-modules: Prelude
hs-source-dirs: .
'cc-options: -O[n]' is generally not needed. When building with optimisations Cabal automatically adds '-O2' for C code. Setting it yourself interferes with the --disable-optimization flag.
cabal-version: 2.2
category: test
description: test a build check involving C++-options field
license: BSD-3-Clause
maintainer: me@example.com
name: cxx-options-with-optimization
synopsis: test a build check
version: 1
library
build-depends: base >= 4.9 && <4.10
cxx-options: -O2
default-language: Haskell2010
exposed-modules: Prelude
hs-source-dirs: .
'cxx-options: -O[n]' is generally not needed. When building with optimisations Cabal automatically adds '-O2' for C++ code. Setting it yourself interferes with the --disable-optimization flag.
cabal-version: 2.2
category: Example
build-type: Simple
name: T5309
version: 1.0.0.0
author: Alex Washburn
maintainer: github@recursion.ninja
copyright: 2018 Alex Washburn (recursion.ninja)
synopsis: A binding to a C++ hashtable for thread-safe memoization.
description: This package is designed to provide a "minimal working example"
to test the cxx-sources and the cxx-options buildinfo flags.
The code was pulled out PCG, https://github.com/amnh/pcg
common ffi-build-info
-- We must provide the full relative path to every C file that the project depends on.
c-sources: memoized-tcm/costMatrixWrapper.c
memoized-tcm/dynamicCharacterOperations.c
cc-options: --std=c11
cxx-sources: memoized-tcm/costMatrix.cpp
cxx-options: --std=c++11
default-language: Haskell2010
-- This library is required for the C++ standard template library.
extra-libraries: stdc++
-- Here we list all directories that contain C header files that the FFI tools will need
-- to locate when preprocessing the C files. Without listing the directories containing
-- the C header files here, the FFI preprocession (hsc2hs, c2hs,etc.) will fail to locate
-- the requisite files.
-- Note also, that the parent directory of the nessicary C header files must be specified.
-- The preprocesser will not recursively look in subdirectories for C header files!
include-dirs: memoized-tcm
common language-spec
build-depends: base >=4.5.1
-- , lens
default-language: Haskell2010
ghc-options: -O2 -Wall
common lib-build-info
hs-source-dirs: lib
-- Modules exported by the library.
other-modules: Bio.Character.Exportable.Class
Data.TCM.Memoized
Data.TCM.Memoized.FFI
library
import: ffi-build-info
, language-spec
-- Modules exported by the library.
exposed-modules: Bio.Character.Exportable.Class
Data.TCM.Memoized
Data.TCM.Memoized.FFI
hs-source-dirs: lib
executable exe-no-lib
import: ffi-build-info
, language-spec
, lib-build-info
main-is: Main.hs
hs-source-dirs: app
executable exe-with-lib
import: language-spec
main-is: Main.hs
build-depends: T5309
hs-source-dirs: app
benchmark bench-no-lib
import: ffi-build-info
, language-spec
, lib-build-info
main-is: Main.hs
type: exitcode-stdio-1.0
hs-source-dirs: app
benchmark bench-with-lib
import: language-spec
main-is: Main.hs
type: exitcode-stdio-1.0
build-depends: T5309
hs-source-dirs: app
test-suite test-no-lib
import: ffi-build-info
, language-spec
, lib-build-info
main-is: Main.hs
type: exitcode-stdio-1.0
hs-source-dirs: app
test-suite test-with-lib
import: language-spec
main-is: Main.hs
type: exitcode-stdio-1.0
build-depends: T5309
hs-source-dirs: app
{-# LANGUAGE FlexibleContexts, TypeFamilies #-}
module Main (main) where
import Data.TCM.Memoized
main :: IO ()
main = generateMemoizedTransitionCostMatrix 5 (const (const 1)) `seq` return ()
# cabal new-build
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- T5309-1.0.0.0 (lib) (first run)
- T5309-1.0.0.0 (exe:exe-no-lib) (first run)
- T5309-1.0.0.0 (exe:exe-with-lib) (first run)
Configuring library for T5309-1.0.0.0..
Preprocessing library for T5309-1.0.0.0..
Building library for T5309-1.0.0.0..
Configuring executable 'exe-no-lib' for T5309-1.0.0.0..
Preprocessing executable 'exe-no-lib' for T5309-1.0.0.0..
Building executable 'exe-no-lib' for T5309-1.0.0.0..
Configuring executable 'exe-with-lib' for T5309-1.0.0.0..
Warning: The package has an extraneous version range for a dependency on an internal library: T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0. This version range includes the current package but isn't needed as the current package's library will always be used.
Preprocessing executable 'exe-with-lib' for T5309-1.0.0.0..
Building executable 'exe-with-lib' for T5309-1.0.0.0..
# cabal new-test
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- T5309-1.0.0.0 (test:test-no-lib) (first run)
- T5309-1.0.0.0 (test:test-with-lib) (first run)
Configuring test suite 'test-no-lib' for T5309-1.0.0.0..
Preprocessing test suite 'test-no-lib' for T5309-1.0.0.0..
Building test suite 'test-no-lib' for T5309-1.0.0.0..
Running 1 test suites...
Test suite test-no-lib: RUNNING...
Test suite test-no-lib: PASS
Test suite logged to: <ROOT>/cabal.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/T5309-1.0.0.0/t/test-no-lib/test/T5309-1.0.0.0-test-no-lib.log
1 of 1 test suites (1 of 1 test cases) passed.
Configuring test suite 'test-with-lib' for T5309-1.0.0.0..
Warning: The package has an extraneous version range for a dependency on an internal library: T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0. This version range includes the current package but isn't needed as the current package's library will always be used.
Preprocessing test suite 'test-with-lib' for T5309-1.0.0.0..
Building test suite 'test-with-lib' for T5309-1.0.0.0..
Running 1 test suites...
Test suite test-with-lib: RUNNING...
Test suite test-with-lib: PASS
Test suite logged to: <ROOT>/cabal.dist/work/./dist/build/<ARCH>/ghc-<GHCVER>/T5309-1.0.0.0/t/test-with-lib/test/T5309-1.0.0.0-test-with-lib.log
1 of 1 test suites (1 of 1 test cases) passed.
# cabal new-bench
Build profile: -w ghc-<GHCVER> -O1
In order, the following will be built:
- T5309-1.0.0.0 (bench:bench-no-lib) (first run)
- T5309-1.0.0.0 (bench:bench-with-lib) (first run)
Configuring benchmark 'bench-no-lib' for T5309-1.0.0.0..
Preprocessing benchmark 'bench-no-lib' for T5309-1.0.0.0..
Building benchmark 'bench-no-lib' for T5309-1.0.0.0..
Running 1 benchmarks...
Benchmark bench-no-lib: RUNNING...
Benchmark bench-no-lib: FINISH
Configuring benchmark 'bench-with-lib' for T5309-1.0.0.0..
Warning: The package has an extraneous version range for a dependency on an internal library: T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0, T5309 -any && ==1.0.0.0. This version range includes the current package but isn't needed as the current package's library will always be used.
Preprocessing benchmark 'bench-with-lib' for T5309-1.0.0.0..
Building benchmark 'bench-with-lib' for T5309-1.0.0.0..
Running 1 benchmarks...
Benchmark bench-with-lib: RUNNING...
Benchmark bench-with-lib: FINISH
import Test.Cabal.Prelude
main = cabalTest $ do
cabal "new-build" ["all"]
cabal "new-test" ["all"]
cabal "new-bench" ["all"]
-----------------------------------------------------------------------------
-- |
-- Module : Bio.Character.Exportable.Class
-- Copyright : (c) 2015-2015 Ward Wheeler
-- License : BSD-style
--
-- Maintainer : wheeler@amnh.org
-- Stability : provisional
-- Portability : portable
--
-- Class for needed operations of coded sequences and characters
--
--
-----------------------------------------------------------------------------
{-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies, MultiParamTypeClasses #-}
module Bio.Character.Exportable.Class where
import Foreign.C.Types
-- |
-- Represents a sequence of fixed width characters packed into a bitwise form
-- consumable by lower level functions.
class Exportable c where
toExportableBuffer :: c -> ExportableCharacterSequence
fromExportableBuffer :: ExportableCharacterSequence -> c
toExportableElements :: c -> Maybe ExportableCharacterElements
fromExportableElements :: ExportableCharacterElements -> c
-- |
-- A structure used for FFI calls.
--
-- 'bufferChunks' contains the bit-packed representation of the character sequence.
data ExportableCharacterSequence
= ExportableCharacterSequence
{ exportedElementCountSequence :: Int
, exportedElementWidthSequence :: Int
, exportedBufferChunks :: [CULong]
} deriving (Eq, Show)
-- |
-- A structure used for FFI calls--
-- 'characterElements' contains the integral value for each character element.
data ExportableCharacterElements
= ExportableCharacterElements
{ exportedElementCountElements :: Int
, exportedElementWidthElements :: Int
, exportedCharacterElements :: [CUInt]
} deriving (Eq, Show)
-----------------------------------------------------------------------------
-- |
-- Module : Data.TCM.Memoized
-- Copyright : (c) 2015-2015 Ward Wheeler
-- License : BSD-style
--
-- Maintainer : wheeler@amnh.org
-- Stability : provisional
-- Portability : portable
--
-----------------------------------------------------------------------------
module Data.TCM.Memoized
( FFI.MemoizedCostMatrix
, generateMemoizedTransitionCostMatrix
, FFI.getMedianAndCost
) where
import qualified Data.TCM.Memoized.FFI as FFI
-- |
-- /O(n^2)/ where @n@ is the alphabet size.
--
-- Generate a memoized TCM by supplying the size of the symbol alphabet and the
-- generating function for unambiguous symbol change cost to produce a memoized
-- TCM. A memoized TCM computes all the costs and medians of unambiguous,
-- singleton symbol set transitions strictly when this function is invoked. A
-- memoized TCM calculates the cost and medians of ambiguous symbol sets in a
-- lazy, memoized manner.
--
-- *Note:* The collection of ambiguous symbols set transitions is the powerset of
-- the collection of unambiguous, singleton symbol sets. The lazy, memoization is
-- a requisite for efficient computation on any non-trivial alphabet size.
generateMemoizedTransitionCostMatrix
:: Word -- ^ Alphabet size
-> (Word -> Word -> Word) -- ^ Generating function
-> FFI.MemoizedCostMatrix
generateMemoizedTransitionCostMatrix = FFI.getMemoizedCostMatrix
{-
-- Causes ambiguity with Data.TCM.(!)
(!) :: Exportable s => FFI.MemoizedCostMatrix -> (s, s) -> (s, Word)
(!) memo (x,y) = FFI.getMedianAndCost memo x y
-}
-----------------------------------------------------------------------------
-- |
-- TODO: Document module.
--
-- Exports C types for dynamic characters and their constructors allong with
-- an FFI binding for the memoizing TCM structure.
-----------------------------------------------------------------------------
{-# LANGUAGE BangPatterns, DeriveGeneric, FlexibleInstances, ForeignFunctionInterface, TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.TCM.Memoized.FFI
( CBufferUnit
, CDynamicChar(..)
, DCElement(..)
, ForeignVoid()
, MemoizedCostMatrix(costMatrix)
, getMemoizedCostMatrix
, getMedianAndCost
-- * Utility functions
, calculateBufferLength
, coerceEnum
, constructCharacterFromExportable
, constructElementFromExportable
, constructEmptyElement
) where
import Bio.Character.Exportable.Class
import Data.Bits
import Foreign hiding (alignPtr)
import Foreign.C.Types
import GHC.Generics (Generic)
import System.IO.Unsafe
-- import Debug.Trace
#include "costMatrixWrapper.h"
#include "dynamicCharacterOperations.h"
-- |
-- A convient type alias for improved clairity of use.
type CBufferUnit = CULong -- This will be compatible with uint64_t
-- |
-- Type of a dynamic character to pass back and forth across the FFI interface.
data CDynamicChar
= CDynamicChar
{ alphabetSizeChar :: CSize
, numElements :: CSize
, dynCharLen :: CSize
, dynChar :: Ptr CBufferUnit