diff options
-rw-r--r-- | compiler/GHC/Linker/MacOS.hs | 31 | ||||
-rw-r--r-- | testsuite/tests/driver/T3007/all.T | 3 |
2 files changed, 27 insertions, 7 deletions
diff --git a/compiler/GHC/Linker/MacOS.hs b/compiler/GHC/Linker/MacOS.hs index 765ea7a7b3..576b9e7feb 100644 --- a/compiler/GHC/Linker/MacOS.hs +++ b/compiler/GHC/Linker/MacOS.hs @@ -23,9 +23,12 @@ import GHC.Utils.Exception import GHC.Utils.Logger import Data.List (isPrefixOf, nub, sort, intersperse, intercalate) -import Control.Monad (join, forM, filterM) +import Data.Char +import Data.Maybe +import Control.Monad (join, forM, filterM, void) import System.Directory (doesFileExist, getHomeDirectory) import System.FilePath ((</>), (<.>)) +import Text.ParserCombinators.ReadP as Parser -- | On macOS we rely on the linkers @-dead_strip_dylibs@ flag to remove unused -- libraries from the dynamic library. We do this to reduce the number of load @@ -51,10 +54,8 @@ runInjectRPaths logger 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 logger dflags Nothing [Option "-l", Option dylib] - let paths = concatMap f info - where f ("path":p:_) = [p] - f _ = [] + info <- lines <$> askOtool logger 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') @@ -63,6 +64,26 @@ runInjectRPaths logger dflags lib_paths dylib = do [] -> return () _ -> runInstallNameTool logger 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 + + getUnitFrameworkOpts :: UnitEnv -> [UnitId] -> IO [String] getUnitFrameworkOpts unit_env dep_packages | platformUsesFrameworks (ue_platform unit_env) = do diff --git a/testsuite/tests/driver/T3007/all.T b/testsuite/tests/driver/T3007/all.T index be57f45807..d0442712e9 100644 --- a/testsuite/tests/driver/T3007/all.T +++ b/testsuite/tests/driver/T3007/all.T @@ -1,4 +1,3 @@ test('T3007', - [when(opsys('darwin'), expect_broken(20026)), - extra_files(['A/', 'B/'])], + [extra_files(['A/', 'B/'])], makefile_test, []) |