[Git][ghc/ghc][wip/fendor/longpath-aware-manifest] Add `-fwin-aware-long-paths` to support ling paths on Windows
Hannes Siebenhandl pushed to branch wip/fendor/longpath-aware-manifest at Glasgow Haskell Compiler / GHC Commits: e23169ef by Fendor at 2026-03-02T21:37:51+01:00 Add `-fwin-aware-long-paths` to support ling paths on Windows While Windows supports file paths longer than the MAX_PATH restriction, it is opt-in, and not enabled by default. By declaring the binary to be long path aware in the manifest of the windows executable, the binary opts-in to the new behaviour. It is up to the developer to make sure they use UNC paths and Win.h specific functions for filesystem operations to use long paths in their application. See https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-lim... and https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests for the documentation on the application manifest and long path option. - - - - - 5 changed files: - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Linker/Windows.hs - docs/users_guide/phases.rst Changes: ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1210,6 +1210,7 @@ defaultFlags settings = [ Opt_AutoLinkPackages, Opt_DiagnosticsShowCaret, Opt_EmbedManifest, + Opt_WinLongPathAware, Opt_FamAppCache, Opt_GenManifest, Opt_GhciHistory, ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -744,6 +744,7 @@ data GeneralFlag | Opt_PrintBindContents | Opt_GenManifest | Opt_EmbedManifest + | Opt_WinLongPathAware | Opt_SharedImplib | Opt_BuildingCabalPackage | Opt_IgnoreDotGhci ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2525,6 +2525,7 @@ fFlagsDeps = [ flagSpec "eager-blackholing" Opt_EagerBlackHoling, flagSpec "orig-thunk-info" Opt_OrigThunkInfo, flagSpec "embed-manifest" Opt_EmbedManifest, + flagSpec "win-aware-long-paths" Opt_WinLongPathAware, flagSpec "enable-rewrite-rules" Opt_EnableRewriteRules, flagSpec "enable-th-splice-warnings" Opt_EnableThSpliceWarnings, flagSpec "error-spans" Opt_ErrorSpans, ===================================== compiler/GHC/Linker/Windows.hs ===================================== @@ -16,6 +16,7 @@ import System.Directory data ManifestOpts = ManifestOpts { manifestEmbed :: !Bool -- ^ Should the manifest be embedded in the binary with Windres + , manifestLongPathAware :: !Bool , manifestTempdir :: TempDir , manifestWindresConfig :: WindresConfig , manifestObjectSuf :: String @@ -24,6 +25,7 @@ data ManifestOpts = ManifestOpts initManifestOpts :: DynFlags -> ManifestOpts initManifestOpts dflags = ManifestOpts { manifestEmbed = gopt Opt_EmbedManifest dflags + , manifestLongPathAware = gopt Opt_WinLongPathAware dflags , manifestTempdir = tmpDir dflags , manifestWindresConfig = configureWindres dflags , manifestObjectSuf = objectSuf dflags @@ -37,21 +39,7 @@ maybeCreateManifest -> IO [FilePath] -- ^ extra objects to embed, maybe maybeCreateManifest logger tmpfs opts exe_filename = do let manifest_filename = exe_filename <.> "manifest" - manifest = - "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\ - \ <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n\ - \ <assemblyIdentity version=\"1.0.0.0\"\n\ - \ processorArchitecture=\"X86\"\n\ - \ name=\"" ++ dropExtension exe_filename ++ "\"\n\ - \ type=\"win32\"/>\n\n\ - \ <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\ - \ <security>\n\ - \ <requestedPrivileges>\n\ - \ <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n\ - \ </requestedPrivileges>\n\ - \ </security>\n\ - \ </trustInfo>\n\ - \</assembly>\n" + manifest = manifestContents (manifestLongPathAware opts) exe_filename writeFile manifest_filename manifest @@ -80,3 +68,36 @@ maybeCreateManifest logger tmpfs opts exe_filename = do removeFile manifest_filename return [rc_obj_filename] + +manifestContents :: Bool -> FilePath -> String +manifestContents longPathAware exe_filename = + unlines $ + [ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + , " <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">" + , " <assemblyIdentity version=\"1.0.0.0\"" + , " processorArchitecture=\"X86\"" + , " name=\"" ++ dropExtension exe_filename ++ "\"" + , " type=\"win32\"/>" + , " <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">" + , " <security>" + , " <requestedPrivileges>" + , " <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>" + , " </requestedPrivileges>" + , " </security>" + , " </trustInfo>" + ] + ++ + ( + if longPathAware + then + [ " <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">" + , " <windowsSettings xmlns:ws2=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">" + , " <ws2:longPathAware>true</ws2:longPathAware>" + , " </windowsSettings>" + , " </application>" + ] + else + [] + ) ++ + [ " </assembly>" + ] ===================================== docs/users_guide/phases.rst ===================================== @@ -1430,6 +1430,29 @@ for example). See also :ghc-flag:`-pgmwindres ⟨cmd⟩` (:ref:`replacing-phases`) and :ghc-flag:`-optwindres ⟨option⟩` (:ref:`forcing-options-through`). +.. ghc-flag:: -fwin-aware-long-paths + :shortdesc: Declare the linked binary to be long path aware on Windows. + :reverse: -fno-win-aware-long-paths + :type: dynamic + :category: linking + :since: 9.14.2 + + Declare in the manifest file that GHC generates when linking a binary on Windows + to be aware of long paths. + + Windows paths usually have a `MAX_PATH <https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation>`__ + limit of 260 characters. + This limitation can be lifted by opting into enabling long paths in various + ways, see `Enable long paths in Windows 10 and later`_. + + To invoke the compiled program with long paths, the Windows manifest needs + to declare that the program is aware of long paths and can handle them + appropriately. + + :ghc-flag:`-fno-embed-manifest` also implies :ghc-flag:`-fno-win-aware-long-paths`. + + _Enable long paths in Windows 10 and later: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-lim... + .. ghc-flag:: -fno-shared-implib :shortdesc: Don't generate an import library for a DLL (Windows only) :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e23169efcda88936d05b0660b0666454... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e23169efcda88936d05b0660b0666454... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Hannes Siebenhandl (@fendor)