summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-08-09 22:46:26 +0800
committerZubin <zubin.duggal@gmail.com>2021-10-12 06:43:25 +0000
commit1716c7a4cb7400e582890861fe6c4065b4f5d706 (patch)
treea0d8f3833e2b5c9d768a3ca89fec9d230044fa6d
parentc531e9ad4dc72b31fe3eabe6a391141fb0f6f38e (diff)
downloadhaskell-1716c7a4cb7400e582890861fe6c4065b4f5d706.tar.gz
Fix parsing of rpaths which include spaces in runInjectRPaths
The logic didn't account for the fact that the paths could contain spaces before which led to errors such as the following from install_name_tool. Stderr ( T14304 ): Warning: -rtsopts and -with-rtsopts have no effect with -shared. Call hs_init_ghc() from your main() function to set these options. error: /nix/store/a6j5761iy238pbckxq2xrhqr2d5kra4m-cctools-binutils-darwin-949.0.1/bin/install_name_tool: for: dist/build/libHSp-0.1-ghc8.10.6.dylib (for architecture arm64) option "-add_rpath /Users/matt/ghc/bindisttest/install dir/lib/ghc-8.10.6/ghc-prim-0.6.1" would duplicate path, file already has LC_RPATH for: /Users/matt/ghc/bindisttest/install dir/lib/ghc-8.10.6/ghc-prim-0.6.1 `install_name_tool' failed in phase `Install Name Tool'. (Exit code: 1) Fixes #20212 (cherry picked from commit 459017906306be4b0127fe423020771db75e8dd7)
-rw-r--r--compiler/GHC/SysTools/Tasks.hs30
1 files changed, 25 insertions, 5 deletions
diff --git a/compiler/GHC/SysTools/Tasks.hs b/compiler/GHC/SysTools/Tasks.hs
index 3b075e7116..ec54ef2a46 100644
--- a/compiler/GHC/SysTools/Tasks.hs
+++ b/compiler/GHC/SysTools/Tasks.hs
@@ -19,6 +19,8 @@ import GHC.Platform
import GHC.Utils.Misc
import Data.List
+import Data.Char
+import Data.Maybe
import System.IO
import System.Process
@@ -27,9 +29,10 @@ import GHC.Prelude
import GHC.SysTools.Process
import GHC.SysTools.Info
-import Control.Monad (join, forM, filterM)
+import Control.Monad (join, forM, filterM, void)
import System.Directory (doesFileExist)
import System.FilePath ((</>))
+import Text.ParserCombinators.ReadP as Parser
{-
************************************************************************
@@ -266,10 +269,9 @@ runInjectRPaths dflags lib_paths dylib = do
-- filter the output for only the libraries. And then drop the @rpath prefix.
let libs = fmap (drop 7) $ filter (isPrefixOf "@rpath") $ fmap (head.words) $ info
-- find any pre-existing LC_PATH items
- info <- fmap words.lines <$> askOtool dflags Nothing [Option "-l", Option dylib]
- let paths = concatMap f info
- where f ("path":p:_) = [p]
- f _ = []
+ info <- lines <$> askOtool dflags Nothing [Option "-l", Option dylib]
+
+ let paths = mapMaybe get_rpath info
lib_paths' = [ p | p <- lib_paths, not (p `elem` paths) ]
-- only find those rpaths, that aren't already in the library.
rpaths <- nub.sort.join <$> forM libs (\f -> filterM (\l -> doesFileExist (l </> f)) lib_paths')
@@ -278,6 +280,24 @@ runInjectRPaths dflags lib_paths dylib = do
[] -> return ()
_ -> runInstallNameTool dflags $ map Option $ "-add_rpath":(intersperse "-add_rpath" rpaths) ++ [dylib]
+get_rpath :: String -> Maybe FilePath
+get_rpath l = case readP_to_S rpath_parser l of
+ [(rpath, "")] -> Just rpath
+ _ -> Nothing
+
+
+rpath_parser :: ReadP FilePath
+rpath_parser = do
+ skipSpaces
+ void $ string "path"
+ void $ many1 (satisfy isSpace)
+ rpath <- many get
+ void $ many1 (satisfy isSpace)
+ void $ string "(offset "
+ void $ munch1 isDigit
+ void $ Parser.char ')'
+ skipSpaces
+ return rpath
runLink :: DynFlags -> [Option] -> IO ()
runLink dflags args = traceToolCommand dflags "linker" $ do