diff options
-rw-r--r-- | compiler/main/DriverPipeline.hs | 10 | ||||
-rw-r--r-- | compiler/main/DynFlags.hs | 9 | ||||
-rw-r--r-- | compiler/main/FileCleanup.hs | 17 | ||||
-rw-r--r-- | compiler/main/Packages.hs | 10 |
4 files changed, 44 insertions, 2 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index e4a9fa2150..92e3455521 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -1744,6 +1744,16 @@ linkBinary' staticLink dflags o_files dep_packages = do in ["-L" ++ l] ++ ["-Xlinker", "-rpath", "-Xlinker", libpath] | otherwise = ["-L" ++ l] + pkg_lib_path_opts <- + if gopt Opt_SingleLibFolder dflags + then do + libs <- getLibs dflags dep_packages + tmpDir <- newTempDir dflags + sequence_ [ copyFile lib (tmpDir </> basename) + | (lib, basename) <- libs] + return [ "-L" ++ tmpDir ] + else pure pkg_lib_path_opts + let dead_strip | gopt Opt_WholeArchiveHsLibs dflags = [] diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 77a6185e4c..b10740b56c 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -557,6 +557,13 @@ data GeneralFlag | Opt_OptimalApplicativeDo | Opt_VersionMacros | Opt_WholeArchiveHsLibs + -- copy all libs into a single folder prior to linking binaries + -- this should elivate the excessive command line limit restrictions + -- on windows, by only requiring a single -L argument instead of + -- one for each dependency. At the time of this writing, gcc + -- forwards all -L flags to the collect2 command without using a + -- response file and as such breaking apart. + | Opt_SingleLibFolder -- output style opts | Opt_ErrorSpans -- Include full span info in error messages, @@ -2820,6 +2827,8 @@ dynamic_flags_deps = [ #endif , make_ord_flag defGhcFlag "relative-dynlib-paths" (NoArg (setGeneralFlag Opt_RelativeDynlibPaths)) + , make_ord_flag defGhcFlag "copy-libs-when-linking" + (NoArg (setGeneralFlag Opt_SingleLibFolder)) , make_ord_flag defGhcFlag "pie" (NoArg (setGeneralFlag Opt_PICExecutable)) , make_ord_flag defGhcFlag "no-pie" (NoArg (unSetGeneralFlag Opt_PICExecutable)) diff --git a/compiler/main/FileCleanup.hs b/compiler/main/FileCleanup.hs index 5150b81fd1..35bed6149b 100644 --- a/compiler/main/FileCleanup.hs +++ b/compiler/main/FileCleanup.hs @@ -3,7 +3,7 @@ module FileCleanup ( TempFileLifetime(..) , cleanTempDirs, cleanTempFiles, cleanCurrentModuleTempFiles , addFilesToClean, changeTempFilesLifetime - , newTempName, newTempLibName + , newTempName, newTempLibName, newTempDir , withSystemTempDirectory, withTempDirectory ) where @@ -132,6 +132,21 @@ newTempName dflags lifetime extn addFilesToClean dflags lifetime [filename] return filename +newTempDir :: DynFlags -> IO FilePath +newTempDir dflags + = do d <- getTempDir dflags + findTempDir (d </> "ghc_") + where + findTempDir :: FilePath -> IO FilePath + findTempDir prefix + = do n <- newTempSuffix dflags + let filename = prefix ++ show n + b <- doesDirectoryExist filename + if b then findTempDir prefix + else do createDirectory filename + -- see mkTempDir below; this is wrong: -> consIORef (dirsToClean dflags) filename + return filename + newTempLibName :: DynFlags -> TempFileLifetime -> Suffix -> IO (FilePath, FilePath, String) newTempLibName dflags lifetime extn diff --git a/compiler/main/Packages.hs b/compiler/main/Packages.hs index d9c198a432..71354b1463 100644 --- a/compiler/main/Packages.hs +++ b/compiler/main/Packages.hs @@ -50,7 +50,7 @@ module Packages ( collectArchives, collectIncludeDirs, collectLibraryPaths, collectLinkOpts, - packageHsLibs, + packageHsLibs, getLibs, -- * Utils unwireUnitId, @@ -1761,6 +1761,14 @@ collectArchives dflags pc = where searchPaths = nub . filter notNull . libraryDirsForWay dflags $ pc libs = packageHsLibs dflags pc ++ extraLibraries pc +getLibs :: DynFlags -> [PreloadUnitId] -> IO [(String,String)] +getLibs dflags pkgs = do + ps <- getPreloadPackagesAnd dflags pkgs + fmap concat . forM ps $ \p -> do + let candidates = [ (l </> f, f) | l <- collectLibraryPaths dflags [p] + , f <- (\n -> "lib" ++ n ++ ".a") <$> packageHsLibs dflags p ] + filterM (doesFileExist . fst) candidates + packageHsLibs :: DynFlags -> PackageConfig -> [String] packageHsLibs dflags p = map (mkDynName . addSuffix) (hsLibraries p) where |