Skip to content

Commit 2f7b22e

Browse files
committed
deprecate -dynamic-too: remove duplicate object file generation
This commit deprecates the -dynamic-too flag and removes the infrastructure that generated separate .dyn_o and .dyn_hi files alongside regular .o and .hi files. Key changes: - Flag -dynamic-too now emits a deprecation warning and is a no-op - Remove auto-enablement of -dynamic-too for TemplateHaskell - Remove pipeline double-run that generated both static and dynamic objects - Remove DynamicTooState type and dynamicNow field from DynFlags - Remove dynamicTooState and setDynamicNow functions - Unify dyn/non-dyn file paths (mkDynObjPath = mkObjPath, etc.) - Remove dynamic interface loading and checking - Update linker to use .o files for dynamic loading The ModLocation fields (ml_dyn_obj_file, ml_dyn_hi_file) are kept for API compatibility but now return the same paths as their non-dyn counterparts. Build systems that rely on .dyn_o files will need to be updated to use regular .o files instead.
1 parent 967ae7b commit 2f7b22e

12 files changed

Lines changed: 67 additions & 242 deletions

File tree

compiler/GHC/Driver/Downsweep.hs

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -940,12 +940,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do
940940
}
941941
-- Recursive call to catch the other cases
942942
enable_code_gen_ms ms'
943-
| dynamic_too_enable enable_spec ms -> do
944-
let ms' = ms
945-
{ ms_hspp_opts = gopt_set (ms_hspp_opts ms) Opt_BuildDynamicToo
946-
}
947-
-- Recursive call to catch the other cases
948-
enable_code_gen_ms ms'
943+
-- Note: dynamic_too_enable case removed - -dynamic-too is deprecated
949944
| ext_interp_enable ms -> do
950945
let ms' = ms
951946
{ ms_hspp_opts = gopt_set (ms_hspp_opts ms) Opt_ExternalInterpreter
@@ -968,14 +963,10 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do
968963
-- can't compile anything anyway! See #16219.
969964
isHomeUnitDefinite (ue_unitHomeUnit (ms_unitid ms) unit_env)
970965

966+
-- bytecode_and_enable: prefer bytecode over needing dynamic objects
967+
-- Note: dynamic_too_enable logic removed - -dynamic-too is deprecated
971968
bytecode_and_enable enable_spec ms =
972-
-- In the situation where we **would** need to enable dynamic-too
973-
-- IF we had decided we needed objects
974-
dynamic_too_enable EnableObject ms
975-
-- but we prefer to use bytecode rather than objects
976-
&& prefer_bytecode
977-
-- and we haven't already turned it on
978-
&& not generate_both
969+
prefer_bytecode && not generate_both
979970
where
980971
lcl_dflags = ms_hspp_opts ms
981972
prefer_bytecode = case enable_spec of
@@ -985,29 +976,6 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do
985976

986977
generate_both = gopt Opt_ByteCodeAndObjectCode lcl_dflags
987978

988-
-- #8180 - when using TemplateHaskell, switch on -dynamic-too so
989-
-- the linker can correctly load the object files. This isn't necessary
990-
-- when using -fexternal-interpreter.
991-
-- FIXME: Duplicated from makeDynFlagsConsistent
992-
dynamic_too_enable enable_spec ms
993-
| sTargetRTSLinkerOnlySupportsSharedLibs $ settings lcl_dflags =
994-
not isDynWay && not dyn_too_enabled
995-
&& enable_object
996-
| otherwise =
997-
hostIsDynamic && not hostIsProfiled && internalInterpreter &&
998-
not isDynWay && not isProfWay && not dyn_too_enabled
999-
&& enable_object
1000-
where
1001-
lcl_dflags = ms_hspp_opts ms
1002-
internalInterpreter = not (gopt Opt_ExternalInterpreter lcl_dflags)
1003-
dyn_too_enabled = gopt Opt_BuildDynamicToo lcl_dflags
1004-
isDynWay = hasWay (ways lcl_dflags) WayDyn
1005-
isProfWay = hasWay (ways lcl_dflags) WayProf
1006-
enable_object = case enable_spec of
1007-
EnableByteCode -> False
1008-
EnableByteCodeAndObject -> True
1009-
EnableObject -> True
1010-
1011979
-- #16331 - when no "internal interpreter" is available but we
1012980
-- need to process some TemplateHaskell or QuasiQuotes, we automatically
1013981
-- turn on -fexternal-interpreter.

compiler/GHC/Driver/DynFlags.hs

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ module GHC.Driver.DynFlags (
2222
xopt_DuplicateRecordFields,
2323
xopt_FieldSelectors,
2424
lang_set,
25-
DynamicTooState(..), dynamicTooState, setDynamicNow,
25+
-- Note: DynamicTooState, dynamicTooState, setDynamicNow removed
26+
-- -dynamic-too is deprecated, only dynamic objects are produced
2627
OnOff(..),
2728
DynFlags(..),
2829
ParMakeCount(..),
@@ -296,10 +297,7 @@ data DynFlags = DynFlags {
296297
dynOutputHi :: Maybe String,
297298
dynLibLoader :: DynLibLoader,
298299

299-
dynamicNow :: !Bool, -- ^ Indicate if we are now generating dynamic output
300-
-- because of -dynamic-too. This predicate is
301-
-- used to query the appropriate fields
302-
-- (outputFile/dynOutputFile, ways, etc.)
300+
-- Note: dynamicNow field removed - -dynamic-too is deprecated
303301

304302
-- | This defaults to 'non-module'. It can be set by
305303
-- 'GHC.Driver.Pipeline.setDumpPrefix' or 'ghc.GHCi.UI.runStmt' based on
@@ -618,7 +616,6 @@ defaultDynFlags mySettings =
618616

619617
dynObjectSuf_ = "dyn_" ++ phaseInputExt StopLn,
620618
dynHiSuf_ = "dyn_hi",
621-
dynamicNow = False,
622619

623620
pluginModNames = [],
624621
pluginModNameOpts = [],
@@ -938,27 +935,8 @@ positionIndependent dflags = gopt Opt_PIC dflags || gopt Opt_PIE dflags
938935
-- need Template-Haskell and GHC is dynamically linked (cf
939936
-- GHC.Driver.Pipeline.compileOne').
940937
--
941-
-- We used to try and fall back from a dynamic-too failure but this feature
942-
-- didn't work as expected (#20446) so it was removed to simplify the
943-
-- implementation and not obscure latent bugs.
944-
945-
data DynamicTooState
946-
= DT_Dont -- ^ Don't try to build dynamic objects too
947-
| DT_OK -- ^ Will still try to generate dynamic objects
948-
| DT_Dyn -- ^ Currently generating dynamic objects (in the backend)
949-
deriving (Eq,Show,Ord)
950-
951-
dynamicTooState :: DynFlags -> DynamicTooState
952-
dynamicTooState dflags
953-
| not (gopt Opt_BuildDynamicToo dflags) = DT_Dont
954-
| dynamicNow dflags = DT_Dyn
955-
| otherwise = DT_OK
956-
957-
setDynamicNow :: DynFlags -> DynFlags
958-
setDynamicNow dflags0 =
959-
dflags0
960-
{ dynamicNow = True
961-
}
938+
-- Note: DynamicTooState type and dynamicTooState/setDynamicNow functions removed
939+
-- -dynamic-too is deprecated - only dynamic objects are produced now
962940

963941
data PkgDbRef
964942
= GlobalPkgDb
@@ -1019,18 +997,7 @@ dopt_unset :: DynFlags -> DumpFlag -> DynFlags
1019997
dopt_unset dfs f = dfs{ dumpFlags = EnumSet.delete f (dumpFlags dfs) }
1020998

1021999
-- | Test whether a 'GeneralFlag' is set
1022-
--
1023-
-- Note that `dynamicNow` (i.e., dynamic objects built with `-dynamic-too`)
1024-
-- always implicitly enables Opt_PIC, Opt_ExternalDynamicRefs, and disables
1025-
-- Opt_SplitSections.
1026-
--
10271000
gopt :: GeneralFlag -> DynFlags -> Bool
1028-
gopt Opt_PIC dflags
1029-
| dynamicNow dflags = True
1030-
gopt Opt_ExternalDynamicRefs dflags
1031-
| dynamicNow dflags = True
1032-
gopt Opt_SplitSections dflags
1033-
| dynamicNow dflags = False
10341001
gopt f dflags = f `EnumSet.member` generalFlags dflags
10351002

10361003
-- | Set a 'GeneralFlag'
@@ -1448,9 +1415,7 @@ languageExtensions (Just GHC2024)
14481415
LangExt.RoleAnnotations]
14491416

14501417
ways :: DynFlags -> Ways
1451-
ways dflags
1452-
| dynamicNow dflags = addWay WayDyn (targetWays_ dflags)
1453-
| otherwise = targetWays_ dflags
1418+
ways dflags = targetWays_ dflags
14541419

14551420
-- | Get target profile
14561421
targetProfile :: DynFlags -> Profile

compiler/GHC/Driver/Main.hs

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,10 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do
13771377
let force_write_interface = gopt Opt_WriteInterface dflags
13781378
write_interface = backendWritesFiles (backend dflags)
13791379

1380+
-- Note: dynamicNow and DynamicTooState removed - -dynamic-too is deprecated
1381+
-- We now only write a single .hi file
13801382
write_iface dflags' iface =
1381-
let !iface_name = if dynamicNow dflags' then ml_dyn_hi_file mod_location else ml_hi_file mod_location
1383+
let !iface_name = ml_hi_file mod_location
13821384
profile = targetProfile dflags'
13831385
in
13841386
{-# SCC "writeIface" #-}
@@ -1389,43 +1391,16 @@ hscMaybeWriteIface logger dflags is_simple iface old_iface mod_location = do
13891391

13901392
if (write_interface || force_write_interface) then do
13911393

1392-
-- FIXME: with -dynamic-too, "change" is only meaningful for the
1393-
-- non-dynamic interface, not for the dynamic one. We should have another
1394-
-- flag for the dynamic interface. In the meantime:
1395-
--
1396-
-- * when we write a single full interface, we check if we are
1397-
-- currently writing the dynamic interface due to -dynamic-too, in
1398-
-- which case we ignore "change".
1399-
--
1400-
-- * when we write two simple interfaces at once because of
1401-
-- dynamic-too, we use "change" both for the non-dynamic and the
1402-
-- dynamic interfaces. Hopefully both the dynamic and the non-dynamic
1403-
-- interfaces stay in sync...
1404-
--
14051394
let change = old_iface /= Just (mi_iface_hash iface)
14061395

1407-
let dt = dynamicTooState dflags
1408-
14091396
when (logHasDumpFlag logger Opt_D_dump_if_trace) $ putMsg logger $
14101397
hang (text "Writing interface(s):") 2 $ vcat
14111398
[ text "Kind:" <+> if is_simple then text "simple" else text "full"
14121399
, text "Hash change:" <+> ppr change
1413-
, text "DynamicToo state:" <+> text (show dt)
14141400
]
14151401

1416-
if is_simple
1417-
then when change $ do -- FIXME: see 'change' comment above
1418-
write_iface dflags iface
1419-
case dt of
1420-
DT_Dont -> return ()
1421-
DT_Dyn -> panic "Unexpected DT_Dyn state when writing simple interface"
1422-
DT_OK -> write_iface (setDynamicNow dflags) iface
1423-
else case dt of
1424-
DT_Dont | change -> write_iface dflags iface
1425-
DT_OK | change -> write_iface dflags iface
1426-
-- FIXME: see change' comment above
1427-
DT_Dyn -> write_iface dflags iface
1428-
_ -> return ()
1402+
-- Simply write the interface if there was a change
1403+
when change $ write_iface dflags iface
14291404

14301405
when (gopt Opt_WriteHie dflags) $ do
14311406
-- This is slightly hacky. A hie file is considered to be up to date

compiler/GHC/Driver/Pipeline.hs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -786,19 +786,9 @@ hscBackendPipeline :: P m => PipeEnv -> HscEnv -> ModSummary -> HscBackendAction
786786
hscBackendPipeline pipe_env hsc_env mod_sum result =
787787
if backendGeneratesCode (backend (hsc_dflags hsc_env)) then
788788
do
789-
res <- hscGenBackendPipeline pipe_env hsc_env mod_sum result
790-
-- Only run dynamic-too if the backend generates object files
791-
-- See Note [Writing interface files]
792-
-- If we are writing a simple interface (not . backendWritesFiles), then
793-
-- hscMaybeWriteIface in the regular pipeline will write both the hi and
794-
-- dyn_hi files. This way we can avoid running the pipeline twice and
795-
-- generating a duplicate linkable.
796-
-- We must not run the backend a second time with `dynamicNow` enable because
797-
-- all the work has already been done in the first pipeline.
798-
when (gopt Opt_BuildDynamicToo (hsc_dflags hsc_env) && backendWritesFiles (backend (hsc_dflags hsc_env)) ) $ do
799-
let dflags' = setDynamicNow (hsc_dflags hsc_env) -- set "dynamicNow"
800-
() <$ hscGenBackendPipeline pipe_env (hscSetFlags dflags' hsc_env) mod_sum result
801-
return res
789+
-- Note: -dynamic-too is deprecated and ignored
790+
-- We no longer run the backend twice - only dynamic objects are produced
791+
hscGenBackendPipeline pipe_env hsc_env mod_sum result
802792
else
803793
case result of
804794
HscUpdate iface -> return (iface, emptyHomeModInfoLinkable)

compiler/GHC/Driver/Pipeline/Execute.hs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,8 @@ runHscBackendPhase :: PipeEnv
545545
runHscBackendPhase pipe_env hsc_env mod_name src_flavour location result = do
546546
let dflags = hsc_dflags hsc_env
547547
logger = hsc_logger hsc_env
548-
o_file = if dynamicNow dflags then ml_dyn_obj_file location else ml_obj_file location -- The real object file
548+
-- Note: dynamicNow removed - always use standard object file path
549+
o_file = ml_obj_file location -- The real object file
549550
next_phase = hscPostBackendPhase src_flavour (backend dflags)
550551
case result of
551552
HscUpdate iface ->
@@ -888,35 +889,26 @@ getOutputFilename
888889
getOutputFilename logger tmpfs stop_phase output basename dflags next_phase maybe_location
889890
-- 1. If we are generating object files for a .hs file, then return the odir as the ModLocation
890891
-- will have been modified to point to the accurate locations
892+
-- Note: dynamicNow removed - always use standard object file path
891893
| StopLn <- next_phase, Just loc <- maybe_location =
892-
return $ if dynamicNow dflags then ml_dyn_obj_file loc
893-
else ml_obj_file loc
894+
return $ ml_obj_file loc
894895
-- 2. If output style is persistent then
895896
| is_last_phase, Persistent <- output = persistent_fn
896897
-- 3. Specific file is only set when outputFile is set by -o
897898
-- If we are in dynamic mode but -dyno is not set then write to the same path as
898899
-- -o with a .dyn_* extension. This case is not triggered for object files which
899900
-- are always handled by the ModLocation.
901+
-- Note: dynamicNow removed - always use standard output file
900902
| is_last_phase, SpecificFile <- output =
901-
return $
902-
if dynamicNow dflags
903-
then case dynOutputFile_ dflags of
904-
Nothing -> let ofile = getOutputFile_ dflags
905-
new_ext = case takeExtension ofile of
906-
"" -> "dyn"
907-
ext -> "dyn_" ++ tail ext
908-
in replaceExtension ofile new_ext
909-
Just fn -> fn
910-
else getOutputFile_ dflags
903+
return $ getOutputFile_ dflags
911904
| keep_this_output = persistent_fn
912905
| Temporary lifetime <- output = newTempName logger tmpfs (tmpDir dflags) lifetime suffix
913906
| otherwise = newTempName logger tmpfs (tmpDir dflags) TFL_CurrentModule
914907
suffix
915908
where
916-
getOutputFile_ dflags =
917-
case outputFile_ dflags of
918-
Nothing -> pprPanic "SpecificFile: No filename" (ppr (dynamicNow dflags) $$
919-
text (fromMaybe "-" (dynOutputFile_ dflags)))
909+
getOutputFile_ dflags' =
910+
case outputFile_ dflags' of
911+
Nothing -> pprPanic "SpecificFile: No filename" (text (fromMaybe "-" (dynOutputFile_ dflags')))
920912
Just fn -> fn
921913

922914
hcsuf = hcSuf dflags

compiler/GHC/Driver/Session.hs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ module GHC.Driver.Session (
4141
xopt_DuplicateRecordFields,
4242
xopt_FieldSelectors,
4343
lang_set,
44-
DynamicTooState(..), dynamicTooState, setDynamicNow,
44+
-- Note: DynamicTooState, dynamicTooState, setDynamicNow removed
45+
-- -dynamic-too is deprecated
4546
sccProfilingEnabled,
4647
needSourceNotes,
4748
OnOff(..),
@@ -1275,8 +1276,10 @@ dynamic_flags_deps = [
12751276
, make_ord_flag defGhcFlag "ddump-file-prefix"
12761277
(hasArg (setDumpPrefixForce . Just . flip (++) "."))
12771278

1278-
, make_ord_flag defGhcFlag "dynamic-too"
1279-
(NoArg (setGeneralFlag Opt_BuildDynamicToo))
1279+
-- -dynamic-too is deprecated and ignored - GHC now only produces dynamic objects
1280+
, make_dep_flag defGhcFlag "dynamic-too"
1281+
(NoArg (return ()))
1282+
"-dynamic-too is deprecated and ignored. Use -dynamic instead."
12801283

12811284
------- Keeping temporary files -------------------------------------
12821285
-- These can be singular (think ghc -c) or plural (think ghc --make)
@@ -3611,17 +3614,7 @@ makeDynFlagsConsistent :: DynFlags -> (DynFlags, [Warn], [Located SDoc])
36113614
-- ensure that a later change doesn't invalidate an earlier check.
36123615
-- Be careful not to introduce potential loops!
36133616
makeDynFlagsConsistent dflags
3614-
-- Disable -dynamic-too on Windows (#8228, #7134, #5987)
3615-
| os == OSMinGW32 && gopt Opt_BuildDynamicToo dflags
3616-
= let dflags' = gopt_unset dflags Opt_BuildDynamicToo
3617-
warn = "-dynamic-too is not supported on Windows"
3618-
in loop dflags' warn
3619-
-- Disable -dynamic-too if we are are compiling with -dynamic already, otherwise
3620-
-- you get two dynamic object files (.o and .dyn_o). (#20436)
3621-
| ways dflags `hasWay` WayDyn && gopt Opt_BuildDynamicToo dflags
3622-
= let dflags' = gopt_unset dflags Opt_BuildDynamicToo
3623-
warn = "-dynamic-too is ignored when using -dynamic"
3624-
in loop dflags' warn
3617+
-- Note: -dynamic-too validation removed - flag is now deprecated and ignored
36253618

36263619
| gopt Opt_SplitSections dflags
36273620
, platformHasSubsectionsViaSymbols (targetPlatform dflags)
@@ -3846,15 +3839,13 @@ decodeSize str
38463839
foreign import ccall unsafe "setHeapSize" setHeapSize :: Int -> IO ()
38473840
foreign import ccall unsafe "enableTimingStats" enableTimingStats :: IO ()
38483841

3842+
-- Note: dynamicNow removed - -dynamic-too is deprecated
3843+
-- Always use the non-dynamic output file paths
38493844
outputFile :: DynFlags -> Maybe String
3850-
outputFile dflags
3851-
| dynamicNow dflags = dynOutputFile_ dflags
3852-
| otherwise = outputFile_ dflags
3845+
outputFile dflags = outputFile_ dflags
38533846

38543847
objectSuf :: DynFlags -> String
3855-
objectSuf dflags
3856-
| dynamicNow dflags = dynObjectSuf_ dflags
3857-
| otherwise = objectSuf_ dflags
3848+
objectSuf dflags = objectSuf_ dflags
38583849

38593850
-- | Pretty-print the difference between 2 DynFlags.
38603851
--

0 commit comments

Comments
 (0)