Hannes Siebenhandl pushed to branch wip/fendor/longpath-aware-manifest at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Driver/DynFlags.hs
    ... ... @@ -1210,6 +1210,7 @@ defaultFlags settings
    1210 1210
       = [ Opt_AutoLinkPackages,
    
    1211 1211
           Opt_DiagnosticsShowCaret,
    
    1212 1212
           Opt_EmbedManifest,
    
    1213
    +      Opt_WinLongPathAware,
    
    1213 1214
           Opt_FamAppCache,
    
    1214 1215
           Opt_GenManifest,
    
    1215 1216
           Opt_GhciHistory,
    

  • compiler/GHC/Driver/Flags.hs
    ... ... @@ -744,6 +744,7 @@ data GeneralFlag
    744 744
        | Opt_PrintBindContents
    
    745 745
        | Opt_GenManifest
    
    746 746
        | Opt_EmbedManifest
    
    747
    +   | Opt_WinLongPathAware
    
    747 748
        | Opt_SharedImplib
    
    748 749
        | Opt_BuildingCabalPackage
    
    749 750
        | Opt_IgnoreDotGhci
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -2525,6 +2525,7 @@ fFlagsDeps = [
    2525 2525
       flagSpec "eager-blackholing"                Opt_EagerBlackHoling,
    
    2526 2526
       flagSpec "orig-thunk-info"                  Opt_OrigThunkInfo,
    
    2527 2527
       flagSpec "embed-manifest"                   Opt_EmbedManifest,
    
    2528
    +  flagSpec "win-aware-long-paths"             Opt_WinLongPathAware,
    
    2528 2529
       flagSpec "enable-rewrite-rules"             Opt_EnableRewriteRules,
    
    2529 2530
       flagSpec "enable-th-splice-warnings"        Opt_EnableThSpliceWarnings,
    
    2530 2531
       flagSpec "error-spans"                      Opt_ErrorSpans,
    

  • compiler/GHC/Linker/Windows.hs
    ... ... @@ -16,6 +16,7 @@ import System.Directory
    16 16
     
    
    17 17
     data ManifestOpts = ManifestOpts
    
    18 18
       { manifestEmbed :: !Bool    -- ^ Should the manifest be embedded in the binary with Windres
    
    19
    +  , manifestLongPathAware :: !Bool
    
    19 20
       , manifestTempdir :: TempDir
    
    20 21
       , manifestWindresConfig :: WindresConfig
    
    21 22
       , manifestObjectSuf :: String
    
    ... ... @@ -24,6 +25,7 @@ data ManifestOpts = ManifestOpts
    24 25
     initManifestOpts :: DynFlags -> ManifestOpts
    
    25 26
     initManifestOpts dflags = ManifestOpts
    
    26 27
       { manifestEmbed = gopt Opt_EmbedManifest dflags
    
    28
    +  , manifestLongPathAware = gopt Opt_WinLongPathAware dflags
    
    27 29
       , manifestTempdir = tmpDir dflags
    
    28 30
       , manifestWindresConfig = configureWindres dflags
    
    29 31
       , manifestObjectSuf = objectSuf dflags
    
    ... ... @@ -37,21 +39,7 @@ maybeCreateManifest
    37 39
        -> IO [FilePath] -- ^ extra objects to embed, maybe
    
    38 40
     maybeCreateManifest logger tmpfs opts exe_filename = do
    
    39 41
        let manifest_filename = exe_filename <.> "manifest"
    
    40
    -       manifest =
    
    41
    -         "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\
    
    42
    -         \  <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n\
    
    43
    -         \  <assemblyIdentity version=\"1.0.0.0\"\n\
    
    44
    -         \     processorArchitecture=\"X86\"\n\
    
    45
    -         \     name=\"" ++ dropExtension exe_filename ++ "\"\n\
    
    46
    -         \     type=\"win32\"/>\n\n\
    
    47
    -         \  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\
    
    48
    -         \    <security>\n\
    
    49
    -         \      <requestedPrivileges>\n\
    
    50
    -         \        <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n\
    
    51
    -         \        </requestedPrivileges>\n\
    
    52
    -         \       </security>\n\
    
    53
    -         \  </trustInfo>\n\
    
    54
    -         \</assembly>\n"
    
    42
    +       manifest = manifestContents (manifestLongPathAware opts) exe_filename
    
    55 43
     
    
    56 44
        writeFile manifest_filename manifest
    
    57 45
     
    
    ... ... @@ -80,3 +68,36 @@ maybeCreateManifest logger tmpfs opts exe_filename = do
    80 68
              removeFile manifest_filename
    
    81 69
     
    
    82 70
              return [rc_obj_filename]
    
    71
    +
    
    72
    +manifestContents :: Bool -> FilePath -> String
    
    73
    +manifestContents longPathAware exe_filename =
    
    74
    +  unlines $
    
    75
    +    [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
    
    76
    +    , "  <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
    
    77
    +    , "  <assemblyIdentity version=\"1.0.0.0\""
    
    78
    +    , "     processorArchitecture=\"X86\""
    
    79
    +    , "     name=\"" ++ dropExtension exe_filename ++ "\""
    
    80
    +    , "     type=\"win32\"/>"
    
    81
    +    , "  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">"
    
    82
    +    , "    <security>"
    
    83
    +    , "      <requestedPrivileges>"
    
    84
    +    , "        <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>"
    
    85
    +    , "      </requestedPrivileges>"
    
    86
    +    , "    </security>"
    
    87
    +    , "  </trustInfo>"
    
    88
    +    ]
    
    89
    +    ++
    
    90
    +    (
    
    91
    +      if longPathAware
    
    92
    +        then
    
    93
    +          [ "  <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">"
    
    94
    +          , "    <windowsSettings xmlns:ws2=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">"
    
    95
    +          , "      <ws2:longPathAware>true</ws2:longPathAware>"
    
    96
    +          , "    </windowsSettings>"
    
    97
    +          , "  </application>"
    
    98
    +          ]
    
    99
    +        else
    
    100
    +          []
    
    101
    +    ) ++
    
    102
    +    [ "  </assembly>"
    
    103
    +    ]

  • docs/users_guide/phases.rst
    ... ... @@ -1430,6 +1430,29 @@ for example).
    1430 1430
         See also :ghc-flag:`-pgmwindres ⟨cmd⟩` (:ref:`replacing-phases`) and
    
    1431 1431
         :ghc-flag:`-optwindres ⟨option⟩` (:ref:`forcing-options-through`).
    
    1432 1432
     
    
    1433
    +.. ghc-flag:: -fwin-aware-long-paths
    
    1434
    +    :shortdesc: Declare the linked binary to be long path aware on Windows.
    
    1435
    +    :reverse: -fno-win-aware-long-paths
    
    1436
    +    :type: dynamic
    
    1437
    +    :category: linking
    
    1438
    +    :since: 9.14.2
    
    1439
    +
    
    1440
    +    Declare in the manifest file that GHC generates when linking a binary on Windows
    
    1441
    +    to be aware of long paths.
    
    1442
    +
    
    1443
    +    Windows paths usually have a `MAX_PATH <https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation>`__
    
    1444
    +    limit of 260 characters.
    
    1445
    +    This limitation can be lifted by opting into enabling long paths in various
    
    1446
    +    ways, see `Enable long paths in Windows 10 and later`_.
    
    1447
    +
    
    1448
    +    To invoke the compiled program with long paths, the Windows manifest needs
    
    1449
    +    to declare that the program is aware of long paths and can handle them
    
    1450
    +    appropriately.
    
    1451
    +
    
    1452
    +    :ghc-flag:`-fno-embed-manifest` also implies :ghc-flag:`-fno-win-aware-long-paths`.
    
    1453
    +
    
    1454
    +    _Enable long paths in Windows 10 and later: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry#enable-long-paths-in-windows-10-version-1607-and-later
    
    1455
    +
    
    1433 1456
     .. ghc-flag:: -fno-shared-implib
    
    1434 1457
         :shortdesc: Don't generate an import library for a DLL (Windows only)
    
    1435 1458
         :type: dynamic