Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mpickering committed May 17, 2024
1 parent 811c308 commit cc1d30d
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 34 deletions.
47 changes: 29 additions & 18 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1733,23 +1733,28 @@ configureCoverage verbosity cfg comp = do
--
-- Note that @--enable-executable-profiling@ also affects profiling
-- of benchmarks and (non-detailed) test suites.
computeEffectiveProfiling :: ConfigFlags -> (Bool {- lib -}, Bool {- exe -})
computeEffectiveProfiling :: ConfigFlags -> (Bool {- lib vanilla-}, Bool {- lib shared -}, Bool {- exe -})
computeEffectiveProfiling cfg =
-- The --profiling flag sets the default for both libs and exes,
-- but can be overridden by --library-profiling, or the old deprecated
-- --executable-profiling flag.
--
-- The --profiling-detail and --library-profiling-detail flags behave
-- similarly
let tryExeProfiling =
let dynamicExe = fromFlagOrDefault False (configDynExe cfg)
tryExeProfiling =
fromFlagOrDefault
False
(mappend (configProf cfg) (configProfExe cfg))
tryLibProfiling =
fromFlagOrDefault
tryExeProfiling
(mappend (configProf cfg) (configProfLib cfg))
in (tryLibProfiling, tryExeProfiling)
(tryExeProfiling && not dynamicExe)
(configProfLib cfg)
tryLibProfilingShared =
fromFlagOrDefault
(tryExeProfiling && dynamicExe)
(configProfShared cfg)
in (tryLibProfiling, tryLibProfilingShared, tryExeProfiling)

-- | Select and apply profiling settings for the build based on the
-- 'ConfigFlags' and 'Compiler'.
Expand All @@ -1759,7 +1764,7 @@ configureProfiling
-> Compiler
-> IO (LBC.BuildOptions -> LBC.BuildOptions)
configureProfiling verbosity cfg comp = do
let (tryLibProfiling, tryExeProfiling) = computeEffectiveProfiling cfg
let (tryLibProfiling, tryLibProfilingShared, tryExeProfiling) = computeEffectiveProfiling cfg

tryExeProfileLevel =
fromFlagOrDefault
Expand Down Expand Up @@ -1798,21 +1803,27 @@ configureProfiling verbosity cfg comp = do
, LBC.withProfExe = tryExeProfiling
, LBC.withProfExeDetail = exeLevel
}
let tryLibProfShared = fromFlagOrDefault False (configProfShared cfg)
compilerSupportsProfilingDynamic = profilingDynamicSupported comp
let compilerSupportsProfilingDynamic = profilingDynamicSupported comp
apply2 <-
if tryLibProfShared && compilerSupportsProfilingDynamic
if tryLibProfilingShared && compilerSupportsProfilingDynamic
then return $ \buildOptions -> apply buildOptions { LBC.withProfLibShared = True }
else do
when (tryLibProfShared && not compilerSupportsProfilingDynamic) $ do
warn verbosity ( "The compiler "
++ showCompilerId comp
++ " does not support "
++ "profiling shared objects. Static profiled objects "
++ "will be built."
)
return $ \buildOptions -> apply buildOptions { LBC.withProfLibShared = False }
return (tryExeProfiling && not tryLibProfiling, apply2)
if (tryLibProfilingShared && not compilerSupportsProfilingDynamic)
then do
warn verbosity ( "The compiler "
++ showCompilerId comp
++ " does not support "
++ "profiling shared objects. Static profiled objects "
++ "will be built."
)
return $ \buildOptions ->
let original_options = apply buildOptions
in original_options { LBC.withProfLibShared = False
, LBC.withProfLib = True
, LBC.withDynExe = if LBC.withProfExe original_options then False else LBC.withDynExe original_options }
else
return apply
return (tryExeProfiling && not (tryLibProfiling || tryLibProfilingShared) , apply2)
else do
let apply buildOptions =
buildOptions
Expand Down
12 changes: 8 additions & 4 deletions Cabal/src/Distribution/Simple/GHC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -891,13 +891,17 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi = do
wantStatic = withStaticLib lbi
wantDynamic = withSharedLib lbi
wantProf = withProfLib lbi
wantProfDyn = withProfLibShared lbi
comp = compiler lbi

let wantedWays =
[ProfDynWay | wantProf && wantDynamic && profilingDynamicSupported comp ]
<> [ProfWay | wantProf && (not wantDynamic || wantStatic || wantVanilla)]
let computed_wantedWays =
[ProfDynWay | wantProfLibShared lbi ]
<> [ProfWay | wantProf ]
<> [DynWay | wantDynamic && not (componentIsIndefinite clbi) ]
<> [StaticWay | wantStatic || wantVanilla || not (wantDynamic || wantProf)]
<> [StaticWay | wantStatic || wantVanilla ]

wantedWays = if null computed_wantedWays then [StaticWay] else computed_wantedWays



info verbosity ("Wanted install ways: " ++ show wantedWays)
Expand Down
24 changes: 16 additions & 8 deletions Cabal/src/Distribution/Simple/GHC/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program.Builtin (ghcProgram)
import Distribution.Simple.Program.Db (requireProgram)
import Distribution.Simple.Utils
import Distribution.Simple.Compiler
import Distribution.Types.ComponentLocalBuildInfo (componentIsIndefinite)
import Distribution.Types.ParStrat
import Distribution.Utils.NubList (fromNubListR)
Expand Down Expand Up @@ -113,7 +112,6 @@ build numJobs pkg_descr pbci = do

-- Determine in which ways we want to build the component
let
comp = compiler lbi
wantVanilla = if isLib then withVanillaLib lbi else False
-- Arguably, wantStatic should be "withFullyStaticExe lbi" for executables,
-- but it was not before the refactor.
Expand All @@ -125,23 +123,33 @@ build numJobs pkg_descr pbci = do
CTest{} -> withDynExe lbi
CBench{} -> withDynExe lbi
wantProf = if isLib then withProfLib lbi else withProfExe lbi
wantProfShared = if isLib then withProfLibShared lbi else (withProfExe lbi && wantDynamic)

--enable-profiling (enable (static profiling way)) .p_o
--enable-shared (enabled dynamic way) .dyn_o
--enable-profiling-shared (enable dyanmic profilng way) .p_dyn_o
--enable-library-vanilla (enable vanilla way) .o

-- See also Note [Building Haskell Modules accounting for TH] in Distribution.Simple.GHC.Build.Modules
-- We build static by default if no other way is wanted.
-- For executables and foreign libraries, there should only be one wanted way.
wantedWays =
Set.fromList $
calculatedWantedWays =
-- If building a library, we accumulate all the ways,
-- otherwise, we take just one.
(if isLib then id else take 1) $
[ProfDynWay | wantProf && wantDynamic && profilingDynamicSupported comp]
<> [ProfWay | wantProf && (not wantDynamic || wantStatic || wantVanilla)]
[ProfDynWay | wantProfShared ]
<> [ProfWay | wantProf ]
-- I don't see why we shouldn't build with dynamic
-- indefinite components.
<> [DynWay | wantDynamic && not (componentIsIndefinite clbi)]
<> [StaticWay | wantStatic || wantVanilla || not (wantDynamic || wantProf)]
<> [StaticWay | wantStatic || wantVanilla ]

-- If for some reason the logic above returns an empty list
wantedWays =
Set.fromList (if null calculatedWantedWays then [StaticWay] else calculatedWantedWays)


liftIO $ info verbosity ("Wanted build ways: " ++ show (Set.toList wantedWays))
liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show (Set.toList wantedWays))

-- We need a separate build and link phase, and C sources must be compiled
-- after Haskell modules, because C sources may depend on stub headers
Expand Down
2 changes: 1 addition & 1 deletion Cabal/src/Distribution/Simple/GHC/Build/Modules.hs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ buildHaskellModules numJobs ghcProg pkg_descr buildTargetDir wantedWays pbci = d
return buildOpts

data BuildWay = StaticWay | DynWay | ProfWay | ProfDynWay
deriving (Eq, Ord, Show, Enum)
deriving (Eq, Ord, Show, Read, Enum)

-- | Returns the object/interface extension prefix for the given build way (e.g. "dyn_" for 'DynWay')
buildWayPrefix :: BuildWay -> String
Expand Down
3 changes: 3 additions & 0 deletions cabal-testsuite/PackageTests/ProfShared/Lib.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Lib where

lib = 10
5 changes: 5 additions & 0 deletions cabal-testsuite/PackageTests/ProfShared/exe/Prof.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Main where

import Lib

main = print lib
13 changes: 13 additions & 0 deletions cabal-testsuite/PackageTests/ProfShared/profShared.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Cabal-Version: 3.8
Name: prof-shared
Version: 0.1
Build-Type: Simple

library
exposed-modules: Lib
Build-Depends: base

executable Prof
main-is: Prof.hs
hs-source-dirs: exe
build-depends: base, prof-shared
10 changes: 7 additions & 3 deletions cabal-testsuite/src/Test/Cabal/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -840,17 +840,21 @@ hasSharedLibraries = do
shared_libs_were_removed <- isGhcVersion ">= 7.8"
return (not (buildOS == Windows && shared_libs_were_removed))

hasProfiledLibraries :: TestM Bool
hasProfiledLibraries = do
testCompilerWithArgs :: [String] -> TestM Bool
testCompilerWithArgs args = do
env <- getTestEnv
ghc_path <- programPathM ghcProgram
let prof_test_hs = testWorkDir env </> "Prof.hs"
liftIO $ writeFile prof_test_hs "module Prof where"
r <- liftIO $ run (testVerbosity env) (Just $ testCurrentDir env)
(testEnvironment env) ghc_path ["-prof", "-c", prof_test_hs]
(testEnvironment env) ghc_path (["-c", prof_test_hs] ++ args)
Nothing
return (resultExitCode r == ExitSuccess)

hasProfiledLibraries, hasProfiledSharedLibraries :: TestM Bool
hasProfiledLibraries = testCompilerWithArgs ["-prof"]
hasProfiledSharedLibraries = testCompilerWithArgs ["-prof", "-dynamic"]

-- | Check if the GHC that is used for compiling package tests has
-- a shared library of the cabal library under test in its database.
--
Expand Down
3 changes: 3 additions & 0 deletions doc/setup-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,9 @@ Miscellaneous options
Build shared library. This implies a separate compiler run to
generate position independent code as required on most platforms.

``--enable-shared`` is enabled automatically if GHC is dynamically linked or
you request to build dynamic executables.

.. option:: --disable-shared

(default) Do not build shared library.
Expand Down

0 comments on commit cc1d30d

Please sign in to comment.